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;
}