in source/packages/services/commands/src/commands/workflow/workflow.startjob.ts [159:305]
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;
}