public async getThing()

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