public async getThing()

in source/packages/services/provisioning/src/things/things.service.ts [283:380]


    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 (Object.prototype.hasOwnProperty.call( describeThingGroupResult, 'thingGroupProperties')) {
                if (Object.prototype.hasOwnProperty.call( describeThingGroupResult,'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;
    }