constructor()

in source/patterns/@aws-solutions-constructs/aws-apigateway-iot/lib/index.ts [82:198]


  constructor(scope: Construct, id: string, props: ApiGatewayToIotProps) {
    super(scope, id);
    defaults.CheckProps(props);

    // Assignment to local member variables to make these available to all member methods of the class.
    // (Split the string just in case user supplies fully qualified endpoint eg. ab123cdefghij4l-ats.iot.ap-south-1.amazonaws.com)
    this.iotEndpoint = props.iotEndpoint.trim().split('.')[0];

    // Mandatory params check
    if (!this.iotEndpoint || this.iotEndpoint.length < 0) {
      throw new Error('specify a valid iotEndpoint');
    }

    // Add additional params to the apiGatewayProps
    let extraApiGwProps = {
      binaryMediaTypes: ['application/octet-stream'],
      defaultMethodOptions: {
        apiKeyRequired: props.apiGatewayCreateApiKey
      }
    };

    // If apiGatewayProps are specified override the extra Api Gateway properties
    if (props.apiGatewayProps) {
      extraApiGwProps = defaults.overrideProps(props.apiGatewayProps, extraApiGwProps);
    }

    // Check whether an API Gateway execution role is specified?
    if (props.apiGatewayExecutionRole) {
      this.apiGatewayRole = props.apiGatewayExecutionRole;
    } else {
      // JSON that will be used for policy document
      const policyJSON = {
        Version: "2012-10-17",
        Statement: [
          {
            Action: [
              "iot:UpdateThingShadow"
            ],
            Resource: `arn:aws:iot:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:thing/*`,
            Effect: "Allow"
          },
          {
            Action: [
              "iot:Publish"
            ],
            Resource: `arn:aws:iot:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:topic/*`,
            Effect: "Allow"
          }
        ]
      };

      // Create a policy document
      const policyDocument: iam.PolicyDocument = iam.PolicyDocument.fromJson(policyJSON);

      // Props for IAM Role
      const iamRoleProps: iam.RoleProps = {
        assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
        path: '/',
        inlinePolicies: {awsapigatewayiotpolicy: policyDocument}
      };

      // Create a policy that overrides the default policy that gets created with the construct
      this.apiGatewayRole = new iam.Role(this, 'apigateway-iot-role', iamRoleProps);
    }

    // Setup the API Gateway
    [this.apiGateway, this.apiGatewayCloudWatchRole,
      this.apiGatewayLogGroup] = defaults.GlobalRestApi(this, extraApiGwProps, props.logGroupProps);

    // Validate the Query Params
    const requestValidatorProps: api.RequestValidatorProps = {
      restApi: this.apiGateway,
      validateRequestBody: false,
      validateRequestParameters: true
    };
    this.requestValidator = new api.RequestValidator(this, `aws-apigateway-iot-req-val`, requestValidatorProps);

    // Create a resource for messages '/message'
    const msgResource: api.IResource = this.apiGateway.root.addResource('message');

    // Create resources from '/message/{topic-level-1}' through '/message/{topic-level-1}/..../{topic-level-7}'
    let topicPath = 'topics';
    let parentNode = msgResource;
    let integParams = {};
    let methodParams = {};
    for (let pathLevel = 1; pathLevel <= this.topicNestingLevel; pathLevel++) {
      const topicName = `topic-level-${pathLevel}`;
      const topicResource: api.IResource = parentNode.addResource(`{${topicName}}`);
      const integReqParam = JSON.parse(`{"integration.request.path.${topicName}": "method.request.path.${topicName}"}`);
      const methodReqParam = JSON.parse(`{"method.request.path.${topicName}": true}`);
      topicPath = `${topicPath}/{${topicName}}`;
      integParams = Object.assign(integParams, integReqParam);
      methodParams = Object.assign(methodParams, methodReqParam);
      this.addResourceMethod(topicResource, props, topicPath, integParams, methodParams);
      parentNode = topicResource;
    }

    // Create a resource for shadow updates '/shadow'
    const shadowResource: api.IResource = this.apiGateway.root.addResource('shadow');

    // Create resource '/shadow/{thingName}'
    const defaultShadowResource: api.IResource = shadowResource.addResource('{thingName}');
    const shadowReqParams = {'integration.request.path.thingName': 'method.request.path.thingName'};
    const methodShadowReqParams = {'method.request.path.thingName': true};
    this.addResourceMethod(defaultShadowResource, props, 'things/{thingName}/shadow',
      shadowReqParams, methodShadowReqParams);

    // Create resource '/shadow/{thingName}/{shadowName}'
    const namedShadowResource: api.IResource = defaultShadowResource.addResource('{shadowName}');
    const namedShadowReqParams = Object.assign({
      'integration.request.path.shadowName': 'method.request.path.shadowName'},
    shadowReqParams);
    const methodNamedShadowReqParams = Object.assign({
      'method.request.path.shadowName': true}, methodShadowReqParams);
    this.addResourceMethod(namedShadowResource, props, 'things/{thingName}/shadow?name={shadowName}',
      namedShadowReqParams, methodNamedShadowReqParams);
  }