From c83563621e85943d02df37361f06774501bf5192 Mon Sep 17 00:00:00 2001 From: Bo Lu Date: Tue, 19 Dec 2023 12:09:37 -0500 Subject: [PATCH] Initial release for GET responses for GCS and RCS configurations --- docs/cloudformation/geocore-stack.yml | 110 +++++++++++++++++- .../viewer-config-service-20231218-0800.zip | Bin 0 -> 6102 bytes .../viewer-config-service-20231218-1200.zip | Bin 0 -> 6082 bytes 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 docs/lambda/viewer-config-service/viewer-config-service-20231218-0800.zip create mode 100644 docs/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip diff --git a/docs/cloudformation/geocore-stack.yml b/docs/cloudformation/geocore-stack.yml index 9a86ee7..c4fb0a8 100644 --- a/docs/cloudformation/geocore-stack.yml +++ b/docs/cloudformation/geocore-stack.yml @@ -390,7 +390,24 @@ Resources: KeyType: HASH - AttributeName: popularity - KeyType: RANGE + KeyType: RANGE + + DynamoDbGeoviewConfigService: + Type: AWS::DynamoDB::Table + Condition: CreateDynamoDb + Properties: + TableName: geoview_config_service + BillingMode: PAY_PER_REQUEST + PointInTimeRecoverySpecification: + PointInTimeRecoveryEnabled: true + AttributeDefinitions: + - + AttributeName: uuid + AttributeType: S + KeySchema: + - + AttributeName: uuid + KeyType: HASH GeoCoreDatabase: Type: AWS::Glue::Database @@ -1712,6 +1729,39 @@ Resources: Layers: - arn:aws:lambda:ca-central-1:336392948345:layer:AWSSDKPandas-Python38:4 + LambdaViewerConfigService: + Type: AWS::Serverless::Function + Properties: + Runtime: python3.9 + Role: !GetAtt LambdaExecutionRole.Arn + CodeUri: + Bucket: !Ref DeploymentBucket + Key: + Fn::If: + - IsProd + - cloudformation-templates/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip + - Fn::If: + - IsStage + - cloudformation-templates/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip + - cloudformation-templates/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip + MemorySize: 3009 + Handler: app.lambda_handler + Timeout: 15 + Environment: + Variables: + GCS_TABLE: 'geoview_config_service' + GEOCORE_ID_API: 'https://geocore.api.geo.ca/id/v2' + RCS_CONFIG_PATH: 'https://maps.canada.ca/geonetwork/srv/api/v2/docs/' + Events: + ApiEvent: + Type: Api + Properties: + RestApiId: !Ref RestApi + Path: /vcs + Method: any + Layers: + - arn:aws:lambda:ca-central-1:336392948345:layer:AWSSDKPandas-Python39:11 + LambdaExecutionRole: Type: AWS::IAM::Role Properties: @@ -4283,6 +4333,64 @@ Resources: requestTemplates: application/json: "{\"statusCode\": 200}" passthroughBehavior: "when_no_match" + /vcs: + get: + consumes: + - "application/json" + produces: + - "application/json" + responses: + "200": + description: "200 response" + schema: + $ref: "#/definitions/Empty" + headers: + Access-Control-Allow-Origin: + type: "string" + x-amazon-apigateway-integration: + type: "aws" + httpMethod: "POST" + uri: !Sub "arn:aws:apigateway:ca-central-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ca-central-1:${AWS::AccountId}:function:${LambdaViewerConfigService}/invocations" + responses: + default: + statusCode: "200" + responseParameters: + method.response.header.Access-Control-Allow-Origin: "'*'" + requestTemplates: + application/json: "{\r\n \"lang\" : \"$input.params('lang')\",\r\n \ + \ \"metadata\" : \"$input.params('metadata')\",\r\n \ + \ \"id\" : \"$input.params('id')\"\r\n}" + passthroughBehavior: "when_no_templates" + contentHandling: "CONVERT_TO_TEXT" + options: + consumes: + - "application/json" + produces: + - "application/json" + responses: + "200": + description: "200 response" + schema: + $ref: "#/definitions/Empty" + headers: + Access-Control-Allow-Origin: + type: "string" + Access-Control-Allow-Methods: + type: "string" + Access-Control-Allow-Headers: + type: "string" + x-amazon-apigateway-integration: + type: "mock" + responses: + default: + statusCode: "200" + responseParameters: + method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'" + method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'" + method.response.header.Access-Control-Allow-Origin: "'*'" + requestTemplates: + application/json: "{\"statusCode\": 200}" + passthroughBehavior: "when_no_match" /saved_records/add: post: produces: diff --git a/docs/lambda/viewer-config-service/viewer-config-service-20231218-0800.zip b/docs/lambda/viewer-config-service/viewer-config-service-20231218-0800.zip new file mode 100644 index 0000000000000000000000000000000000000000..7b645e613ba7dc35aab150958c472e277e3f1400 GIT binary patch literal 6102 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 Y{eOca{mZBaApD(Fe_xqT_^;?c0RNLzlmGw# literal 0 HcmV?d00001 diff --git a/docs/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip b/docs/lambda/viewer-config-service/viewer-config-service-20231218-1200.zip new file mode 100644 index 0000000000000000000000000000000000000000..8403f071cee8359da8defdd2122d6da9f129b75b GIT binary patch literal 6082 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 E0R$gO3jhEB literal 0 HcmV?d00001