in source/packages/libraries/core/thing-list-builder/src/awsIotThingListBuilder.ts [107:258]
public async listThings(req: ListThingsRequest): Promise<ListThingsResponse> {
logger.debug(`awsIotThingListBuilder listThings: r:${JSON.stringify(req)}`);
ow(req, ow.object.nonEmpty);
const thingNamesResult: string[] = [];
const arnsOutOfRegion: string[] = [];
if ((req.thingNames?.length ?? 0) > 0) {
thingNamesResult.push(...req.thingNames);
}
const assetLibraryGroupPathsToProcess: string[] = [];
if (req.assetLibraryGroupPaths !== undefined) {
assetLibraryGroupPathsToProcess.push(...req.assetLibraryGroupPaths);
}
// if we have an Asset Library query specified, retrieve all the asset library groups/devices it relates to
if (req.assetLibraryQuery !== undefined) {
logger.silly(`awsIotThingListBuilder listThings: processing assetLibraryQuery`);
let searchResults = await this.assetLibrarySearchClient.search(req.assetLibraryQuery);
logger.silly(
`awsIotThingListBuilder listThings: searchResults:${JSON.stringify(searchResults)}`
);
while ((searchResults.results?.length ?? 0) > 0) {
for (const r of searchResults.results) {
if (this.isDevice(r)) {
const awsIotThingArn = (r as Device10Resource).awsIotThingArn;
if (awsIotThingArn !== undefined) {
if (this.isInRegion(awsIotThingArn)) {
thingNamesResult.push(this.getName(awsIotThingArn));
} else {
arnsOutOfRegion.push(awsIotThingArn);
}
}
} else {
assetLibraryGroupPathsToProcess.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(
req.assetLibraryQuery,
offset + count
);
} else {
searchResults.results = [];
}
}
}
// for Asset Library groups, we need to expand to retrieve the thing arn of all devices that are a member of the group
if (assetLibraryGroupPathsToProcess.length > 0) {
logger.silly(
`awsIotThingListBuilder listThings: expanding assetLibraryGroupPathsToProcess: ${JSON.stringify(
assetLibraryGroupPathsToProcess
)}`
);
for (const groupPath of assetLibraryGroupPathsToProcess) {
let result = await this.assetLibraryGroupClient.listGroupMembersDevices(groupPath);
logger.silly(
`awsIotThingListBuilder listThings: result: ${JSON.stringify(result)}`
);
while (result?.results !== undefined) {
for (const device of result.results) {
if (device.awsIotThingArn) {
if (this.isInRegion(device.awsIotThingArn)) {
thingNamesResult.push(this.getName(device.awsIotThingArn));
} else {
arnsOutOfRegion.push(device.awsIotThingArn);
}
}
}
if (result.pagination === undefined) {
break;
}
const offset = result.pagination.offset + result.pagination.count;
result = await this.assetLibraryGroupClient.listGroupMembersDevices(
groupPath,
undefined,
undefined,
offset,
result.pagination.count
);
}
}
}
// for Asset Library devices, we need to get its corresponding thing arn
if ((req.assetLibraryDeviceIds?.length ?? 0) > 0) {
logger.silly(
`awsIotThingListBuilder listThings: expanding assetLibraryDeviceIds: ${JSON.stringify(
req.assetLibraryDeviceIds
)}`
);
// TODO: performance improvement, process in parallel
const result = await this.assetLibraryDeviceClient.getDevicesByID(
req.assetLibraryDeviceIds,
false,
['awsIotThingArn'],
[]
);
logger.silly(`awsIotThingListBuilder listThings: result: ${JSON.stringify(result)}`);
for (const device of result.results) {
if (device.awsIotThingArn) {
if (this.isInRegion(device.awsIotThingArn)) {
thingNamesResult.push(this.getName(device.awsIotThingArn));
} else {
arnsOutOfRegion.push(device.awsIotThingArn);
}
}
}
}
// for aws iot thing groups we need to expand to retrieve the group members
if ((req.thingGroupNames?.length ?? 0) > 0) {
logger.silly(
`awsIotThingListBuilder listThings: expanding thingGroupNames: ${JSON.stringify(
req.thingGroupNames
)}`
);
for (const thingGroup of req.thingGroupNames) {
let result = await this.iot.send(
new ListThingsInThingGroupCommand({ thingGroupName: thingGroup })
);
logger.silly(`awsIotThingListBuilder listThings: r: ${JSON.stringify(req)}`);
while ((result.things?.length ?? 0) > 0) {
thingNamesResult.push(...result.things);
if (result.nextToken !== undefined && result.nextToken !== null) {
result = await this.iot.send(
new ListThingsInThingGroupCommand({
thingGroupName: thingGroup,
nextToken: result.nextToken,
})
);
} else {
break;
}
}
}
}
// one final step, make sure they're unique
const response: ListThingsResponse = {
thingNames: [...new Set(thingNamesResult)],
arnsOutOfRegion: [...new Set(arnsOutOfRegion)],
};
logger.debug(`awsIotThingListBuilder listThings: exit:${JSON.stringify(response)}`);
return response;
}