private async buildTargetList()

in source/packages/services/commands/src/commands/workflow/workflow.startjob.ts [126:235]


    private async buildTargetList(commandId:string, targets:string[], targetQuery:SearchRequestModel) : Promise<string[]> {
        logger.debug(`workflow.startjob buildTargetList: commandId:${commandId}, targets:${targets}, targetQuery:${JSON.stringify(targetQuery)}`);

        ow(commandId, ow.string.nonEmpty);
        // ow(targets, ow.array.nonEmpty.minLength(1));

        let awsThingTargets:string[]=[];
        const awsGroupTargets:string[]=[];
        const cdfDeviceTargets:string[]=[];
        const cdfGroupTargets:string[]=[];

        // if we have a target query specified, retrieve all the asset library groups/devices it relates to
        if (targetQuery!==undefined) {
            let searchResults = await this.assetLibrarySearchClient.search(targetQuery);
            logger.verbose(`workflow.startjob buildTargetList: searchResults:${JSON.stringify(searchResults)}`);
            while (searchResults.results.length>0) {
                for(const r of searchResults.results) {
                    if (this.isDevice(r)) {
                        const awsIotThingArn = (r as Device10Resource).awsIotThingArn;
                        if (awsIotThingArn!==undefined) {
                            awsThingTargets.push(awsIotThingArn);
                        }
                    } else {
                        cdfGroupTargets.push((r as Group10Resource).groupPath);
                    }
                }
                // possibly paginated results?
                if (searchResults.pagination!==undefined) {
                    const offset = searchResults.pagination.offset;
                    const count = searchResults.pagination.count;
                    searchResults = await this.assetLibrarySearchClient.search(targetQuery, offset+count );
                } else {
                    searchResults.results=[];
                }
            }
        }

        // figure out the type of each target
        if (targets!==undefined) {
            for(const target of targets) {
                const targetType = this.getTargetType(target);
                switch (targetType) {
                    case TargetType.awsIotThing:
                    awsThingTargets.push(target);
                        break;
                    case TargetType.awsIotGroup:
                    awsGroupTargets.push(target);
                        break;
                    case TargetType.cdfDevice:
                        cdfDeviceTargets.push(target);
                        break;
                    case TargetType.cdfGroup:
                        cdfGroupTargets.push(target);
                        break;
                    default:
                }
            }
        }

        // if we have too many aws iot thing groups as targets, we can't proceed
        const maxGroups = (awsThingTargets.length===0 && cdfDeviceTargets.length===0 && cdfGroupTargets.length===0) ? this.maxTargets : this.maxTargets-1;
        if (awsGroupTargets.length>maxGroups) {
            throw new Error('MAX_GROUPS_EXCEEDED');
        }

        // for CDF groups, we need to get the thing arn of all devices related to the group
        if (cdfGroupTargets.length>0) {
            logger.debug(`workflow.startjob buildTargetList: creating CDFGroupTargets cdfGroupTargets: ${JSON.stringify(cdfGroupTargets)}`);
            for(const groupPath of cdfGroupTargets) {
                let result = await this.assetLibraryGroupClient.listGroupMembersDevices(groupPath);
                while (result.results!==undefined) {
                    for(const device of result.results) {
                        if (device.awsIotThingArn) {
                            awsThingTargets.push(device.awsIotThingArn);
                        }
                    }
                    if (result.pagination===undefined) {
                        break;
                    }
                    const offset = result.pagination.offset + result.pagination.count;
                    result = await this.assetLibraryGroupClient.listGroupMembersDevices(groupPath, null, null, offset, result.pagination.count);
                }
            }
        }

        // for CDF devices, we need to get its corresponding thing arn
        if (cdfDeviceTargets.length>0) {
            logger.debug(`workflow.startjob buildTargetList: creating CDFDeviceTargets, cdfDeviceTargets: ${JSON.stringify(cdfDeviceTargets)}`);
            const result = await this.assetLibraryDeviceClient.getDevicesByID(cdfDeviceTargets, false, [], []);
            for(const device of result.results) {
                if (device.awsIotThingArn) {
                    awsThingTargets.push(device.awsIotThingArn);
                }
            }
        }

        // if the no. devices is greater than the available slots we have, they need flattening into an ephemeral group
        const maxDevices = this.maxTargets - awsGroupTargets.length;
        if (awsThingTargets.length>maxDevices) {
            const ephemeralGroupArn = await this.buildEphemeralGroup(commandId, awsThingTargets);
            awsGroupTargets.push(ephemeralGroupArn);
            awsThingTargets=[];
        }

        // what we have left should be the list of thing and group arns.  one final step, make sure they're unique
        const jobTargets = [...new Set(awsThingTargets.concat(awsGroupTargets))];

        logger.debug(`workflow.startjob buildTargetList: exit:${jobTargets}`);
        return jobTargets;
    }