Ejemplo n.º 1
0
 def add_cors_options(api_gateway_resource: aws_apigateway.Resource):
     api_gateway_resource.add_method(
         'OPTIONS',
         aws_apigateway.MockIntegration(integration_responses=[
             CDKMasterStack.get_options_integration_response()
         ],
                                        passthrough_behavior=aws_apigateway.
                                        PassthroughBehavior.WHEN_NO_MATCH,
                                        request_templates={
                                            "application/json":
                                            "{\"statusCode\":200}"
                                        }),
         method_responses=[CDKMasterStack.get_options_method_response()])
Ejemplo n.º 2
0
    def _add_generic_api_integration(self,
                                     api_resource: aws_apigateway.Resource,
                                     api_function,
                                     get_access_auth: bool = False,
                                     edit_access_auth: bool = False,
                                     is_proxy: bool = False):

        api_lambda_integration = aws_apigateway.LambdaIntegration(
            api_function,
            proxy=False,
            integration_responses=[self.get_integration_response()],
            request_templates={
                "application/json": self.get_request_template()
            })

        if is_proxy:
            api_lambda_integration_without_response = aws_apigateway.LambdaIntegration(
                api_function,
                proxy=False,
                request_templates={
                    "application/json": self.get_request_template()
                })
            api_resource = api_resource.add_proxy(
                default_integration=api_lambda_integration_without_response,
                any_method=False)

        self.add_cors_options(api_resource)
        get_authorizer = self._api_authorizer if get_access_auth else None
        edit_authorizer = self._api_authorizer if edit_access_auth else None

        self._add_generic_api_method(api_resource, api_lambda_integration,
                                     ["GET"], get_authorizer)
        self._add_generic_api_method(api_resource, api_lambda_integration,
                                     ["POST"], edit_authorizer)
 def __add_resource_method(resource: apigw.Resource, http_method: str, integration: apigw.LambdaIntegration,
                           authorizer: apigw.CfnAuthorizer) -> None:
     method = resource.add_method(
         http_method=http_method,
         integration=integration,
         authorization_type=apigw.AuthorizationType.COGNITO,
     )
     method_resource: apigw.Resource = method.node.find_child("Resource")
     method_resource.add_property_override("AuthorizerId", {"Ref": authorizer.logical_id})
Ejemplo n.º 4
0
    def _add_generic_api_method(
            self, api_resource: aws_apigateway.Resource,
            integration: aws_apigateway.LambdaIntegration, methods: List[str],
            authorizer: Optional[aws_apigateway.CfnAuthorizer]):

        auth_type = None if authorizer is None else aws_apigateway.AuthorizationType.COGNITO
        for method in methods:
            api_method = api_resource.add_method(
                method,
                integration,
                method_responses=[self.get_method_response()],
                authorization_type=auth_type)

            if authorizer:
                api_method.node.find_child("Resource").add_property_override(
                    'AuthorizerId', authorizer.ref)
Ejemplo n.º 5
0
    def add_get_method(
        self,
        api: aws_apigateway.RestApi,
        resource: aws_apigateway.Resource,
        table: aws_dynamodb.Table,
    ) -> aws_apigateway.Method:
        list_announcements_lambda = create_function(
            stack=self,
            id="ListAnnouncementLambda",
            settings={
                "handler":
                "list_announcements.main",
                "runtime":
                aws_lambda.Runtime.PYTHON_3_8,
                "timeout":
                core.Duration.minutes(
                    self.settings.AWS_LAMBDA_GET_ANNOUNCEMENT_TIMEOUT),
                "retry_attempts":
                self.settings.AWS_LAMBDA_GET_ANNOUNCEMENT_RETRY_ATTEMPTS,
            },
        )
        table.grant_read_data(list_announcements_lambda)
        list_announcements_lambda.add_environment(
            "TABLE_NAME",
            table.table_name,
        )

        list_announcements_method = resource.add_method(
            "GET",
            integration=aws_apigateway.LambdaIntegration(
                list_announcements_lambda,
                proxy=True,
                integration_responses=[
                    aws_apigateway.IntegrationResponse(status_code="200", ),
                    aws_apigateway.IntegrationResponse(status_code="404", ),
                ],
            ),
        )
        self.methods_to_deploy.append(list_announcements_method)
        return list_announcements_method
Ejemplo n.º 6
0
    def __init__(self, scope: cdk.Construct, construct_id: str, context,
                 resource: apigw.Resource, user_pool: cognito.UserPool,
                 user_client: cognito.UserPoolClient,
                 user_pool_parameter: ssm.StringParameter,
                 launcher_network_config_parameter: ssm.StringParameter,
                 launcher_task_definition: GrantingTaskDefinition,
                 launcher_cluster: ecs.Cluster, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        server_domain = self.node.try_get_context('server_domain')

        servers_table = db.Table.from_table_name(self, 'servers-dynamo',
                                                 context['servers_table_name'])
        servers_key = kms.Key.from_key_arn(
            self, 'ServersKey',
            f'arn:aws:kms:{context["region"]}:{context["account_id"]}:key/{context["kms_key_id"]}'
        )

        class ServerLambda(PythonFunction):
            def __init__(self, scope, construct_id, handler: str):
                super().__init__(
                    scope,
                    construct_id,
                    entry='servers_lambda',
                    index='views.py',
                    handler=handler,
                    runtime=_lambda.Runtime.PYTHON_3_8,
                    timeout=cdk.Duration.seconds(30),
                    environment={
                        'SERVER_DOMAIN':
                        server_domain,
                        'DYNAMODB_SERVERS_TABLE_NAME':
                        servers_table.table_name,
                        'LAUNCHER_NETWORK_CONFIG_PARAMETER':
                        launcher_network_config_parameter.parameter_name,
                        'LAUNCHER_TASK_ARN':
                        launcher_task_definition.task_definition_arn,
                        'CLUSTER_ARN':
                        launcher_cluster.cluster_arn
                    })
                servers_table.grant_read_write_data(self)
                servers_key.grant_encrypt_decrypt(self)
                launcher_network_config_parameter.grant_read(self)
                launcher_task_definition.grant_run(self)

        servers_lambda = ServerLambda(self, 'ServersLambda', handler='servers')
        server_lambda = ServerLambda(self, 'ServerLambda', handler='server')

        user_pool_parameter_lambda = PythonFunction(
            self,
            'UserPoolParameterLambda',
            entry='parameter_lambda',
            index='main.py',
            handler='main',
            runtime=_lambda.Runtime.PYTHON_3_8,
            timeout=cdk.Duration.seconds(30),
            environment={
                'USER_POOL_PARAMETER': user_pool_parameter.parameter_name
            })
        user_pool_parameter.grant_read(user_pool_parameter_lambda)

        user_pool_authorizer = apigw.CognitoUserPoolsAuthorizer(
            self, 'UserPoolAuthorizer', cognito_user_pools=[user_pool])

        # /api
        api = resource.add_resource('api')

        # /api/user_pool
        parameter = api.add_resource(
            'user_pool',
            default_integration=apigw.LambdaIntegration(
                user_pool_parameter_lambda),
            default_method_options=apigw.MethodOptions(
                authorization_type=apigw.AuthorizationType.NONE))
        parameter.add_method('GET')

        # /api/servers
        servers = api.add_resource(
            'servers',
            default_integration=apigw.LambdaIntegration(servers_lambda),
            default_method_options=apigw.MethodOptions(
                authorizer=user_pool_authorizer))
        servers.add_method('GET')
        servers.add_method('PUT')

        # /api/servers/{hostname}
        server = servers.add_resource(
            '{hostname}',
            default_integration=apigw.LambdaIntegration(server_lambda),
            default_method_options=apigw.MethodOptions(
                authorizer=user_pool_authorizer))
        server.add_method('GET')
        server.add_method('PUT')
        server.add_method('POST')
Ejemplo n.º 7
0
    def __init__(self, scope: core.Construct, id: str,
                 resource: aws_apigateway.Resource):
        super().__init__(scope, id)

        # DynamoDB
        self.table = aws_dynamodb.Table(
            self,
            "users_table",
            partition_key=aws_dynamodb.Attribute(
                name="id", type=aws_dynamodb.AttributeType.STRING),
            billing_mode=aws_dynamodb.BillingMode.PAY_PER_REQUEST,
            table_name="users_table",
            removal_policy=core.RemovalPolicy.DESTROY)

        # Lambdas
        create_lambda = aws_lambda.Function(
            self,
            "users_create_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/users/create"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="users_create_lambda")
        create_lambda.add_environment("USERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(create_lambda)

        find_lambda = aws_lambda.Function(
            self,
            "users_find_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/users/find"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="users_find_lambda")
        find_lambda.add_environment("USERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(find_lambda)

        remove_lambda = aws_lambda.Function(
            self,
            "users_remove_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/users/remove"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="users_remove_lambda")
        remove_lambda.add_environment("USERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(remove_lambda)

        credit_subtract_lambda = aws_lambda.Function(
            self,
            "users_credit_subtract_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/users/credit_subtract"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="users_credit_subtract_lambda")
        credit_subtract_lambda.add_environment("USERS_TABLE",
                                               self.table.table_name)
        self.table.grant_read_write_data(credit_subtract_lambda)

        credit_add_lambda = aws_lambda.Function(
            self,
            "users_credit_add_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/users/credit_add"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="users_credit_add_lambda")
        credit_add_lambda.add_environment("USERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(credit_add_lambda)

        # API Gateway Lambda integrations
        create_integration = aws_apigateway.LambdaIntegration(create_lambda)
        find_integration = aws_apigateway.LambdaIntegration(find_lambda)
        remove_integration = aws_apigateway.LambdaIntegration(remove_lambda)
        credit_subtract_integration = aws_apigateway.LambdaIntegration(
            credit_subtract_lambda)
        credit_add_integration = aws_apigateway.LambdaIntegration(
            credit_add_lambda)

        # API Gateway
        credit = resource.add_resource("credit")

        # POST /users/create
        create = resource.add_resource("create")
        create.add_method("POST", create_integration)

        # DELETE /users/remove/{user_id}
        remove = resource.add_resource("remove").add_resource("{user_id}")
        remove.add_method("DELETE", remove_integration)

        # GET /users/find/{user_id}
        find = resource.add_resource("find").add_resource("{user_id}")
        find.add_method("GET", find_integration)

        # POST /users/credit/subtract/{user_id}/{amount}
        credit_subtract = credit.add_resource("subtract").add_resource(
            "{user_id}").add_resource("{amount}")
        credit_subtract.add_method("POST", credit_subtract_integration)

        # POST /users/credit/add/{user_id}/{amount}
        credit_add = credit.add_resource("add").add_resource(
            "{user_id}").add_resource("{amount}")
        credit_add.add_method("POST", credit_add_integration)
Ejemplo n.º 8
0
    def add_post_method(
        self,
        api: aws_apigateway.RestApi,
        resource: aws_apigateway.Resource,
        table: aws_dynamodb.Table,
    ) -> aws_apigateway.Method:
        create_announcement_lambda = create_function(
            stack=self,
            id="CreateAnnouncementLambda",
            settings={
                "handler":
                "create_announcement.main",
                "runtime":
                aws_lambda.Runtime.PYTHON_3_8,
                "timeout":
                core.Duration.minutes(
                    self.settings.AWS_LAMBDA_CREATE_ANNOUNCEMENT_TIMEOUT),
                "retry_attempts":
                self.settings.AWS_LAMBDA_CREATE_ANNOUNCEMENT_RETRY_ATTEMPTS,
            },
        )
        create_announcement_lambda.add_environment(
            "TABLE_NAME",
            table.table_name,
        )

        table.grant_read_write_data(create_announcement_lambda)

        create_announcement_request_validator = aws_apigateway.RequestValidator(
            self,
            "CreateAnnouncementRequestValidator",
            rest_api=api,
            validate_request_body=True,
            request_validator_name="Create Announcement Request Validator",
        )

        create_announcement_request_model = aws_apigateway.Model(
            self,
            "CreateAnnouncementRequestModel",
            model_name="CreateAnnouncementRequest",
            rest_api=api,
            schema=aws_apigateway.JsonSchema(
                type=aws_apigateway.JsonSchemaType.OBJECT,
                required=["Item"],
                properties={
                    "Item":
                    aws_apigateway.JsonSchema(
                        type=aws_apigateway.JsonSchemaType.OBJECT,
                        required=["title", "date", "description"],
                        properties={
                            "title":
                            aws_apigateway.JsonSchema(
                                type=aws_apigateway.JsonSchemaType.STRING),
                            "description":
                            aws_apigateway.JsonSchema(
                                type=aws_apigateway.JsonSchemaType.STRING, ),
                            "date":
                            aws_apigateway.JsonSchema(
                                type=aws_apigateway.JsonSchemaType.STRING,
                                min_length=1,
                                format="date",
                                pattern=
                                "^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])$",
                            ),
                        },
                    )
                },
            ),
        )

        create_announcement_response_success_model = aws_apigateway.Model(
            self,
            "CreateAnnouncementResponseSuccess",
            model_name="CreateAnnouncementResponseSuccess",
            rest_api=api,
            schema=aws_apigateway.JsonSchema(
                type=aws_apigateway.JsonSchemaType.OBJECT,
                required=["id"],
                properties={
                    "id":
                    aws_apigateway.JsonSchema(
                        type=aws_apigateway.JsonSchemaType.STRING)
                },
            ),
        )
        create_announcement_response_error_model = aws_apigateway.Model(
            self,
            "CreateAnnouncementResponseError",
            model_name="CreateAnnouncementResponseError",
            rest_api=api,
            schema=aws_apigateway.JsonSchema(
                type=aws_apigateway.JsonSchemaType.OBJECT,
                required=["error"],
                properties={
                    "error":
                    aws_apigateway.JsonSchema(
                        type=aws_apigateway.JsonSchemaType.STRING)
                },
            ),
        )

        create_announcement_method = resource.add_method(
            "POST",
            integration=aws_apigateway.LambdaIntegration(
                create_announcement_lambda,
                proxy=True,
                integration_responses=[
                    aws_apigateway.IntegrationResponse(
                        status_code="200",
                        response_parameters={
                            "method.response.header.Access-Control-Allow-Origin":
                            "'*'"
                        },
                    ),
                    aws_apigateway.IntegrationResponse(
                        status_code="404",
                        response_parameters={
                            "method.response.header.Access-Control-Allow-Origin":
                            "'*'"
                        },
                    ),
                ],
                passthrough_behavior=aws_apigateway.PassthroughBehavior.NEVER,
            ),
            request_validator=create_announcement_request_validator,
            request_models={
                "application/json": create_announcement_request_model
            },
            method_responses=[
                aws_apigateway.MethodResponse(
                    status_code="200",
                    response_models={
                        "application/json":
                        create_announcement_response_success_model
                    },
                    response_parameters={
                        "method.response.header.Access-Control-Allow-Origin":
                        True
                    },
                ),
                aws_apigateway.MethodResponse(
                    status_code="404",
                    response_models={
                        "application/json":
                        create_announcement_response_error_model
                    },
                    response_parameters={
                        "method.response.header.Access-Control-Allow-Origin":
                        True
                    },
                ),
            ],
        )

        self.methods_to_deploy.append(create_announcement_method)
        return create_announcement_method
Ejemplo n.º 9
0
    def __init__(self, scope: core.Construct, id: str,
                 resource: aws_apigateway.Resource, users: UsersService,
                 orders: OrdersService):
        super().__init__(scope, id)

        # Lambda
        status_lambda = aws_lambda.Function(
            self,
            "payment_status_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/payment/status"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="payment_status_lambda")
        status_lambda.add_environment("ORDERS_TABLE", orders.table.table_name)
        orders.table.grant_read_write_data(status_lambda)

        pay_lambda = aws_lambda.Function(
            self,
            "payment_pay_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/payment/pay"),
            memory_size=256,
            timeout=core.Duration.seconds(60),
            function_name="payment_pay_lambda")
        pay_lambda.add_environment("ORDERS_TABLE", orders.table.table_name)
        pay_lambda.add_environment("USERS_TABLE", users.table.table_name)
        orders.table.grant_read_write_data(pay_lambda)
        users.table.grant_read_write_data(pay_lambda)
        pay_lambda.grant_invoke(orders.checkout_lambda)

        cancel_lambda = aws_lambda.Function(
            self,
            "payment_cancel_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/payment/cancel"),
            memory_size=256,
            timeout=core.Duration.seconds(60),
            function_name="payment_cancel_lambda")
        cancel_lambda.add_environment("ORDERS_TABLE", orders.table.table_name)
        cancel_lambda.add_environment("USERS_TABLE", users.table.table_name)
        orders.table.grant_read_write_data(cancel_lambda)
        users.table.grant_read_write_data(cancel_lambda)
        cancel_lambda.grant_invoke(orders.checkout_lambda)

        # API Gateway integration
        status_integration = aws_apigateway.LambdaIntegration(status_lambda)
        pay_integration = aws_apigateway.LambdaIntegration(pay_lambda)
        cancel_integration = aws_apigateway.LambdaIntegration(cancel_lambda)

        # API Gateway
        # GET /payment/status/{order_id}
        status = resource.add_resource("status").add_resource("{order_id}")
        status.add_method("GET", status_integration)

        # POST /payment/pay/{order_id}/{amount}
        pay = resource.add_resource("pay").add_resource(
            "{order_id}").add_resource("{amount}")
        pay.add_method("POST", pay_integration)

        # POST /payment/cancel/{order_id}
        cancel = resource.add_resource("cancel").add_resource("{order_id}")
        cancel.add_method("POST", cancel_integration)
Ejemplo n.º 10
0
 def _add_get_integration(self, rest_api: apigw.Resource, asset_bucket,
                          s3_integration_role) -> apigw.Resource:
     """
     Add integration for /ui/
     """
     s3_integration = apigw.AwsIntegration(
         service='s3',
         path=f'{asset_bucket.bucket_name}/index.html',
         integration_http_method='GET',
         options=apigw.IntegrationOptions(
             credentials_role=s3_integration_role,
             integration_responses=[
                 apigw.IntegrationResponse(
                     status_code='200',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length',
                         'method.response.header.Timestamp':
                         'integration.response.header.Date'
                     }),
                 apigw.IntegrationResponse(
                     status_code='400',
                     selection_pattern=r'4\d{2}',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length'
                     }),
                 apigw.IntegrationResponse(
                     status_code='500',
                     selection_pattern=r'5\d{2}',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length'
                     })
             ]))
     ui = rest_api.add_resource('ui')
     ui.add_method('GET',
                   integration=s3_integration,
                   method_responses=[
                       apigw.MethodResponse(
                           status_code='200',
                           response_parameters={
                               'method.response.header.Content-Type': True,
                               'method.response.header.Content-Length':
                               True,
                               'method.response.header.Timestamp': True
                           }),
                       apigw.MethodResponse(
                           status_code='400',
                           response_parameters={
                               'method.response.header.Content-Type': True,
                               'method.response.header.Content-Length': True
                           }),
                       apigw.MethodResponse(
                           status_code='500',
                           response_parameters={
                               'method.response.header.Content-Type': True,
                               'method.response.header.Content-Length': True
                           })
                   ])
     return ui
Ejemplo n.º 11
0
 def _add_item_integration(self, ui_resource: apigw.Resource, asset_bucket,
                           s3_integration_role) -> apigw.Resource:
     """
     Add integration for /ui/{object}
     """
     s3_integration = apigw.AwsIntegration(
         service='s3',
         path=f'{asset_bucket.bucket_name}/{{object}}',
         integration_http_method='GET',
         options=apigw.IntegrationOptions(
             credentials_role=s3_integration_role,
             integration_responses=[
                 apigw.IntegrationResponse(
                     status_code='200',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length',
                         'method.response.header.Timestamp':
                         'integration.response.header.Date'
                     }),
                 apigw.IntegrationResponse(
                     status_code='400',
                     selection_pattern=r'4\d{2}',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length'
                     }),
                 apigw.IntegrationResponse(
                     status_code='500',
                     selection_pattern=r'5\d{2}',
                     response_parameters={
                         'method.response.header.Content-Type':
                         'integration.response.header.Content-Type',
                         'method.response.header.Content-Length':
                         'integration.response.header.Content-Length'
                     })
             ],
             request_parameters={
                 'integration.request.path.object':
                 'method.request.path.item'
             }))
     ui_item = ui_resource.add_resource('{item}')
     ui_item.add_method(
         'GET',
         integration=s3_integration,
         method_responses=[
             apigw.MethodResponse(
                 status_code='200',
                 response_parameters={
                     'method.response.header.Content-Type': True,
                     'method.response.header.Content-Length': True,
                     'method.response.header.Timestamp': True
                 }),
             apigw.MethodResponse(
                 status_code='400',
                 response_parameters={
                     'method.response.header.Content-Type': True,
                     'method.response.header.Content-Length': True
                 }),
             apigw.MethodResponse(
                 status_code='500',
                 response_parameters={
                     'method.response.header.Content-Type': True,
                     'method.response.header.Content-Length': True
                 })
         ],
         request_parameters={'method.request.path.item': True})
     return ui_item
Ejemplo n.º 12
0
    def __init__(self, scope: core.Construct, id: str, resource: aws_apigateway.Resource, stock: StockService):
        super().__init__(scope, id)

        # DynamoDB
        self.table = aws_dynamodb.Table(
            self,
            "orders_table",
            partition_key=aws_dynamodb.Attribute(
                name="id",
                type=aws_dynamodb.AttributeType.STRING
            ),
            billing_mode=aws_dynamodb.BillingMode.PAY_PER_REQUEST,
            table_name="orders_table",
            removal_policy=core.RemovalPolicy.DESTROY
        )

        # Lambdas
        create_lambda = aws_lambda.Function(
            self,
            "orders_create_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/create"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="orders_create_lambda"
        )
        create_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(create_lambda)

        remove_lambda = aws_lambda.Function(
            self,
            "orders_remove_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/remove"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="orders_remove_lambda"
        )
        remove_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(remove_lambda)

        find_lambda = aws_lambda.Function(
            self,
            "orders_find_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/find"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="orders_find_lambda"
        )
        find_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(find_lambda)

        item_add_lambda = aws_lambda.Function(
            self,
            "orders_item_add_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/item_add"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="orders_item_add_lambda"
        )
        item_add_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        item_add_lambda.add_environment("STOCK_TABLE", stock.table.table_name)
        self.table.grant_read_write_data(item_add_lambda)
        stock.find_lambda.grant_invoke(item_add_lambda)

        item_remove_lambda = aws_lambda.Function(
            self,
            "orders_item_remove_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/item_remove"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="orders_item_remove_lambda"
        )
        item_remove_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        item_remove_lambda.add_environment("STOCK_TABLE", stock.table.table_name)
        self.table.grant_read_write_data(item_remove_lambda)
        stock.find_lambda.grant_invoke(item_remove_lambda)

        self.checkout_lambda = aws_lambda.Function(
            self,
            "orders_checkout_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/orders/checkout"),
            memory_size=256,
            timeout=core.Duration.seconds(60),
            function_name="orders_checkout_lambda"
        )
        self.checkout_lambda.add_environment("ORDERS_TABLE", self.table.table_name)
        self.table.grant_read_write_data(self.checkout_lambda)
        stock.add_lambda.grant_invoke(self.checkout_lambda)
        stock.subtract_lambda.grant_invoke(self.checkout_lambda)

        # API Gateway Lambda integrations
        create_integration = aws_apigateway.LambdaIntegration(create_lambda)
        remove_integration = aws_apigateway.LambdaIntegration(remove_lambda)
        find_integration = aws_apigateway.LambdaIntegration(find_lambda)
        item_add_integration = aws_apigateway.LambdaIntegration(item_add_lambda)
        item_remove_integration = aws_apigateway.LambdaIntegration(item_remove_lambda)
        checkout_integration = aws_apigateway.LambdaIntegration(self.checkout_lambda)

        # API Gateway
        # POST /orders/create/{user_id}
        create = resource.add_resource("create").add_resource("{user_id}")
        create.add_method("POST", create_integration)

        # DELETE /orders/remove/{order_id}
        remove = resource.add_resource("remove").add_resource("{order_id}")
        remove.add_method("DELETE", remove_integration)

        # GET /orders/find/{order_id}
        find = resource.add_resource("find").add_resource("{order_id}")
        find.add_method("GET", find_integration)

        # POST /orders/addItem/{order_id}/{item_id}
        item_add = resource.add_resource("addItem").add_resource("{order_id}").add_resource("{item_id}")
        item_add.add_method("POST", item_add_integration)

        # DELETE /orders/removeItem/{order_id}/{item_id}
        item_remove = resource.add_resource("removeItem").add_resource("{order_id}").add_resource("{item_id}")
        item_remove.add_method("DELETE", item_remove_integration)

        # POST /orders/checkout/{order_id}
        checkout = resource.add_resource("checkout").add_resource("{order_id}")
        checkout.add_method("POST", checkout_integration)
Ejemplo n.º 13
0
    def __init__(self, scope: core.Construct, id: str,
                 resource: aws_apigateway.Resource):
        super().__init__(scope, id)

        # DynamoDB
        self.table = aws_dynamodb.Table(
            self,
            "stock_table",
            partition_key=aws_dynamodb.Attribute(
                name="id", type=aws_dynamodb.AttributeType.STRING),
            billing_mode=aws_dynamodb.BillingMode.PAY_PER_REQUEST,
            table_name="stock_table",
            removal_policy=core.RemovalPolicy.DESTROY)

        # Lambdas
        create_lambda = aws_lambda.Function(
            self,
            "stock_create_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/stock/create"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="stock_create_lambda")
        create_lambda.add_environment("STOCK_TABLE", self.table.table_name)
        self.table.grant_read_write_data(create_lambda)

        self.find_lambda = aws_lambda.Function(
            self,
            "stock_find_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/stock/find"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="stock_find_lambda")
        self.find_lambda.add_environment("STOCK_TABLE", self.table.table_name)
        self.table.grant_read_write_data(self.find_lambda)

        self.add_lambda = aws_lambda.Function(
            self,
            "stock_add_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/stock/add"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="stock_add_lambda")
        self.add_lambda.add_environment("STOCK_TABLE", self.table.table_name)
        self.table.grant_read_write_data(self.add_lambda)

        self.subtract_lambda = aws_lambda.Function(
            self,
            "stock_subtract_lambda",
            runtime=aws_lambda.Runtime.PYTHON_3_6,
            handler="lambda_function.lambda_handler",
            code=aws_lambda.Code.asset("./services/stock/subtract"),
            memory_size=256,
            timeout=core.Duration.seconds(10),
            function_name="stock_subtract_lambda")
        self.subtract_lambda.add_environment("STOCK_TABLE",
                                             self.table.table_name)
        self.table.grant_read_write_data(self.subtract_lambda)

        # API Gateway integration
        create_integration = aws_apigateway.LambdaIntegration(create_lambda)
        find_integration = aws_apigateway.LambdaIntegration(self.find_lambda)
        add_integration = aws_apigateway.LambdaIntegration(self.add_lambda)
        subtract_integration = aws_apigateway.LambdaIntegration(
            self.subtract_lambda)

        # API Gateway
        # POST /stock/item/create/{price}
        create = resource.add_resource("item").add_resource(
            "create").add_resource("{price}")
        create.add_method("POST", create_integration)

        # GET /stock/find/{item_id}
        find = resource.add_resource("find").add_resource("{item_id}")
        find.add_method("GET", find_integration)

        # POST /stock/add/{item_id}/{number}
        add = resource.add_resource("add").add_resource(
            "{item_id}").add_resource("{number}")
        add.add_method("POST", add_integration)

        # POST /stock/subtract/{item_id}/{number}
        subtract = resource.add_resource("subtract").add_resource(
            "{item_id}").add_resource("{number}")
        subtract.add_method("POST", subtract_integration)