in source/packages/services/provisioning/src/things/things.service.ts [351:468]
public async getThing(thingName: string): Promise<ThingDetailModel> {
logger.debug(`things.service getThing: in: thingName:${thingName}`);
const describeThingFuture = this._iot.describeThing({ thingName }).promise();
const listThingPrincipalsFuture = this._iot.listThingPrincipals({ thingName }).promise();
const listThingGroupsForThingFuture = this._iot
.listThingGroupsForThing({ thingName })
.promise();
const results = await Promise.all([
describeThingFuture,
listThingPrincipalsFuture,
listThingGroupsForThingFuture,
]);
let thing: AWS.Iot.DescribeThingResponse = {};
try {
thing = results[0];
} catch (e) {
throw new Error('NOT_FOUND');
}
const thingModel: ThingDetailModel = {
thingName,
arn: thing.thingArn,
attributes: thing.attributes,
certificates: [],
policies: [],
groups: [],
};
const foundPolicies: { [key: string]: boolean } = {};
const thingPrincipals = results[1];
if (thingPrincipals.principals.length > 0) {
for (const certArn of thingPrincipals.principals) {
const certificateId = certArn.split('/')[1];
const describeCertificateFuture = this._iot
.describeCertificate({ certificateId })
.promise();
const listPrincipalPoliciesFuture = this._iot
.listPrincipalPolicies({ principal: certArn })
.promise();
const pricipalResults = await Promise.all([
describeCertificateFuture,
listPrincipalPoliciesFuture,
]);
const describeCertificateResponse = pricipalResults[0];
const certificateStatus: CertificateStatus =
describeCertificateResponse.certificateDescription.status === 'ACTIVE'
? CertificateStatus.ACTIVE
: CertificateStatus.INACTIVE;
const certDetails: ThingCertificateModel = {
certificateId:
describeCertificateResponse.certificateDescription.certificateId,
arn: describeCertificateResponse.certificateDescription.certificateArn,
certificateStatus,
certificatePem:
describeCertificateResponse.certificateDescription.certificatePem,
};
thingModel.certificates.push(certDetails);
const attachedPolicies = pricipalResults[1];
for (const policy of attachedPolicies.policies) {
foundPolicies[policy.policyName] = true;
}
}
const policyFutures: Promise<PromiseResult<GetPolicyResponse, AWSError>>[] = [];
for (const policyName of Object.keys(foundPolicies)) {
policyFutures.push(this._iot.getPolicy({ policyName }).promise());
}
const policyResults = await Promise.all(policyFutures);
for (const policyResult of policyResults) {
const policyDetails: ThingPolicyModel = {
policyName: policyResult.policyName,
arn: policyResult.policyArn,
policyDocument: JSON.parse(policyResult.policyDocument),
};
thingModel.policies.push(policyDetails);
}
}
// TODO: this returns immmediate groups and does not traverse the group hierarchy
const thingGroups = results[2];
const describeThingGroupFutures: Promise<
PromiseResult<DescribeThingGroupResponse, AWSError>
>[] = [];
for (const group of thingGroups.thingGroups) {
describeThingGroupFutures.push(
this._iot.describeThingGroup({ thingGroupName: group.groupName }).promise()
);
}
const describeThingGroupResults = await Promise.all(describeThingGroupFutures);
for (const describeThingGroupResult of describeThingGroupResults) {
let groupAttributes: { [key: string]: string } = {};
if (describeThingGroupResult.hasOwnProperty('thingGroupProperties')) {
if (describeThingGroupResult.hasOwnProperty('attributePayload')) {
groupAttributes =
describeThingGroupResult.thingGroupProperties.attributePayload.attributes;
}
}
const groupModel: ThingGroupModel = {
groupName: describeThingGroupResult.thingGroupName,
arn: describeThingGroupResult.thingGroupArn,
attributes: groupAttributes,
};
thingModel.groups.push(groupModel);
}
logger.debug(`things.service getThing: exit: thingModel:${JSON.stringify(thingModel)}`);
return thingModel;
}