From 7534dcd761ac9dc302022d5ef612f4a942a56c4c Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Sat, 23 Mar 2024 00:53:11 +0100 Subject: [PATCH] feat(apigatewayv2): add missing `WebSocketIntegration` props (#29566) ### Issue # (if applicable) None as far as I can tell ### Reason for this change I was looking at the WebSocket integration to get a feel for #29562, and noticed a couple of missing properties ### Description of changes * Added support for `timeout` and `contentHandling` * Minor copy-pasta fixes in documentation and test description ### Description of how you validated changes I've added unit tests to check these optional properties. I've also updated and verified the following integrations tests: * `integ.lambda.ts`: * `ContentHandlingStrategy` and `TimeoutInMillis` are both correctly set ```sh $ aws apigatewayv2 get-integration --api-id bu24s9i8t0 --integration-id fxqec8c { "ConnectionType": "INTERNET", "ContentHandlingStrategy": "CONVERT_TO_TEXT", "IntegrationId": "fxqec8c", "IntegrationMethod": "POST", "IntegrationType": "AWS_PROXY", "IntegrationUri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:637423343434:function:WebSocketApiInteg-DefaultHandler604DF7AC-GSQYxsiaKjkz/invocations", "PassthroughBehavior": "WHEN_NO_MATCH", "PayloadFormatVersion": "1.0", "RequestTemplates": {}, "TimeoutInMillis": 10000 } ``` * `integ.aws.ts`: * `ContentHandlingStrategy`, `TemplateSelectionExpression`, `TimeoutInMillis`, `PassthroughBehavior`, and `RequestParameters` are all correctly set ```sh $ aws apigatewayv2 get-integration --api-id qp17tw07w3 --integration-id hycmjxb { "ConnectionType": "INTERNET", "ContentHandlingStrategy": "CONVERT_TO_BINARY", "CredentialsArn": "arn:aws:iam::637423343434:role/integ-aws-websocket-integrat-ApiGatewayRoleD2518903-i80lztfxo5XI", "IntegrationId": "hycmjxb", "IntegrationMethod": "POST", "IntegrationResponseSelectionExpression": "${integration.response.statuscode}", "IntegrationType": "AWS", "IntegrationUri": "arn:aws:apigateway:us-east-1:dynamodb:action/PutItem", "PassthroughBehavior": "WHEN_NO_TEMPLATES", "PayloadFormatVersion": "1.0", "RequestParameters": { "integration.request.header.Content-Type": "'application/x-www-form-urlencoded'" }, "RequestTemplates": { "application/json": "{\"TableName\":\"MyTable\",\"Item\":{\"id\":{\"S\":\"$context.requestId\"}}}" }, "TemplateSelectionExpression": "\\$default", "TimeoutInMillis": 10000 } ``` ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...nteg-aws-websocket-integration.assets.json | 4 +- ...eg-aws-websocket-integration.template.json | 9 +- .../integ.aws.js.snapshot/manifest.json | 20 +- .../websocket/integ.aws.js.snapshot/tree.json | 9 +- .../test/websocket/integ.aws.ts | 11 +- .../WebSocketApiInteg.assets.json | 6 +- .../WebSocketApiInteg.template.json | 4 +- .../integ.lambda.js.snapshot/cdk.out | 2 +- .../integ.lambda.js.snapshot/integ.json | 2 +- .../integ.lambda.js.snapshot/manifest.json | 24 +-- .../integ.lambda.js.snapshot/tree.json | 202 +++++++++--------- .../test/websocket/integ.lambda.ts | 11 +- .../aws-apigatewayv2-integrations/README.md | 5 +- .../lib/websocket/aws.ts | 22 +- .../lib/websocket/lambda.ts | 32 ++- .../test/websocket/aws.test.ts | 48 ++++- .../test/websocket/lambda.test.ts | 78 ++++--- .../lib/websocket/integration.ts | 53 ++++- 18 files changed, 358 insertions(+), 184 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.assets.json index 93e8c3b698172..46b3a9c480519 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "165e169601b6d918afe762f370d9ce4ceb525ddb21c3aa95abf339d5fd6b532c": { + "636fdd026b7f14567bc975abac73dfbac55058665c31d090375174adc715aab5": { "source": { "path": "integ-aws-websocket-integration.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "165e169601b6d918afe762f370d9ce4ceb525ddb21c3aa95abf339d5fd6b532c.json", + "objectKey": "636fdd026b7f14567bc975abac73dfbac55058665c31d090375174adc715aab5.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.template.json index af961456f5acb..683dde85dc2c3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/integ-aws-websocket-integration.template.json @@ -97,6 +97,7 @@ "ApiId": { "Ref": "mywsapi32E6CE11" }, + "ContentHandlingStrategy": "CONVERT_TO_BINARY", "CredentialsArn": { "Fn::GetAtt": [ "ApiGatewayRoleD2518903", @@ -117,6 +118,10 @@ ] ] }, + "PassthroughBehavior": "WHEN_NO_TEMPLATES", + "RequestParameters": { + "integration.request.header.Content-Type": "'application/x-www-form-urlencoded'" + }, "RequestTemplates": { "application/json": { "Fn::Join": [ @@ -130,7 +135,9 @@ ] ] } - } + }, + "TemplateSelectionExpression": "\\$default", + "TimeoutInMillis": 10000 } }, "mywsapiconnectRoute45A0ED6A": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/manifest.json index 24accf82b2dcf..a472b3cafbe28 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/165e169601b6d918afe762f370d9ce4ceb525ddb21c3aa95abf339d5fd6b532c.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/636fdd026b7f14567bc975abac73dfbac55058665c31d090375174adc715aab5.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -101,24 +101,6 @@ "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } - ], - "mywsapiitemRouteDynamodbPutItem27DCDF48": [ - { - "type": "aws:cdk:logicalId", - "data": "mywsapiitemRouteDynamodbPutItem27DCDF48", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } - ], - "mywsapiitemRoute86C9FFC9": [ - { - "type": "aws:cdk:logicalId", - "data": "mywsapiitemRoute86C9FFC9", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } ] }, "displayName": "integ-aws-websocket-integration" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/tree.json index e7e21f31223ef..8daa67ba0998a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.js.snapshot/tree.json @@ -214,6 +214,7 @@ "apiId": { "Ref": "mywsapi32E6CE11" }, + "contentHandlingStrategy": "CONVERT_TO_BINARY", "credentialsArn": { "Fn::GetAtt": [ "ApiGatewayRoleD2518903", @@ -234,6 +235,10 @@ ] ] }, + "passthroughBehavior": "WHEN_NO_TEMPLATES", + "requestParameters": { + "integration.request.header.Content-Type": "'application/x-www-form-urlencoded'" + }, "requestTemplates": { "application/json": { "Fn::Join": [ @@ -247,7 +252,9 @@ ] ] } - } + }, + "templateSelectionExpression": "\\$default", + "timeoutInMillis": 10000 } }, "constructInfo": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.ts index 222d45b70f179..c31f9aa5c5133 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.aws.ts @@ -1,7 +1,7 @@ -import { HttpMethod, WebSocketApi, WebSocketStage } from 'aws-cdk-lib/aws-apigatewayv2'; +import { ContentHandling, HttpMethod, PassthroughBehavior, WebSocketApi, WebSocketStage } from 'aws-cdk-lib/aws-apigatewayv2'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as iam from 'aws-cdk-lib/aws-iam'; -import { App, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { App, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib'; import { WebSocketAwsIntegration, WebSocketMockIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; @@ -42,6 +42,9 @@ webSocketApi.addRoute('$connect', { integrationUri: `arn:aws:apigateway:${stack.region}:dynamodb:action/PutItem`, integrationMethod: HttpMethod.POST, credentialsRole: apiRole, + requestParameters: { + 'integration.request.header.Content-Type': '\'application/x-www-form-urlencoded\'', + }, requestTemplates: { 'application/json': JSON.stringify({ TableName: table.tableName, @@ -52,6 +55,10 @@ webSocketApi.addRoute('$connect', { }, }), }, + templateSelectionExpression: '\\$default', + passthroughBehavior: PassthroughBehavior.WHEN_NO_TEMPLATES, + contentHandling: ContentHandling.CONVERT_TO_BINARY, + timeout: Duration.seconds(10), }), }); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json index c73ed81c6cb7f..24a57b275ad97 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.assets.json @@ -1,7 +1,7 @@ { - "version": "34.0.0", + "version": "36.0.0", "files": { - "fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233": { + "f542f97a9aa5e38fc369d5e5530a480ab81374b9796bc3e79ae4f98411f2900b": { "source": { "path": "WebSocketApiInteg.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233.json", + "objectKey": "f542f97a9aa5e38fc369d5e5530a480ab81374b9796bc3e79ae4f98411f2900b.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json index e50d8cfbe1645..e62da6105c8e5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/WebSocketApiInteg.template.json @@ -431,6 +431,7 @@ "ApiId": { "Ref": "mywsapi32E6CE11" }, + "ContentHandlingStrategy": "CONVERT_TO_TEXT", "IntegrationType": "AWS_PROXY", "IntegrationUri": { "Fn::Join": [ @@ -454,7 +455,8 @@ "/invocations" ] ] - } + }, + "TimeoutInMillis": 10000 } }, "mywsapidefaultRouteE9382DF8": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/cdk.out index 2313ab5436501..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"34.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/integ.json index 851e1157a43a6..ca04fda251454 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "testCases": { "integ.lambda": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/manifest.json index 1f2c3210e48af..2795874854105 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "34.0.0", + "version": "36.0.0", "artifacts": { "WebSocketApiInteg.assets": { "type": "cdk:asset-manifest", @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa386136122b6cd106460ddbdcd437d10712be61617b8d1bf2110a459aa9e233.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f542f97a9aa5e38fc369d5e5530a480ab81374b9796bc3e79ae4f98411f2900b.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -91,10 +91,7 @@ "/WebSocketApiInteg/mywsapi/$connect-Route/ConnectIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapiconnectRouteConnectIntegrationPermission719B6E63", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "mywsapiconnectRouteConnectIntegrationPermission719B6E63" } ], "/WebSocketApiInteg/mywsapi/$connect-Route/ConnectIntegration/Resource": [ @@ -112,10 +109,7 @@ "/WebSocketApiInteg/mywsapi/$disconnect-Route/DisconnectIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapidisconnectRouteDisconnectIntegrationPermissionA8197C41", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "mywsapidisconnectRouteDisconnectIntegrationPermissionA8197C41" } ], "/WebSocketApiInteg/mywsapi/$disconnect-Route/DisconnectIntegration/Resource": [ @@ -133,10 +127,7 @@ "/WebSocketApiInteg/mywsapi/$default-Route/DefaultIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapidefaultRouteDefaultIntegrationPermission3B7F9CA1", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "mywsapidefaultRouteDefaultIntegrationPermission3B7F9CA1" } ], "/WebSocketApiInteg/mywsapi/$default-Route/DefaultIntegration/Resource": [ @@ -154,10 +145,7 @@ "/WebSocketApiInteg/mywsapi/sendmessage-Route/SendMessageIntegration-Permission": [ { "type": "aws:cdk:logicalId", - "data": "mywsapisendmessageRouteSendMessageIntegrationPermission92C9841E", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "mywsapisendmessageRouteSendMessageIntegrationPermission92C9841E" } ], "/WebSocketApiInteg/mywsapi/sendmessage-Route/SendMessageIntegration/Resource": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/tree.json index 990d79acbeef9..9b3963465943c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.js.snapshot/tree.json @@ -20,8 +20,8 @@ "id": "ImportServiceRole", "path": "WebSocketApiInteg/ConnectHandler/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -59,14 +59,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -89,14 +89,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DisconnectHandler": { @@ -111,8 +111,8 @@ "id": "ImportServiceRole", "path": "WebSocketApiInteg/DisconnectHandler/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -150,14 +150,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -180,14 +180,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultHandler": { @@ -202,8 +202,8 @@ "id": "ImportServiceRole", "path": "WebSocketApiInteg/DefaultHandler/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -241,14 +241,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -271,14 +271,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "MessageHandler": { @@ -293,8 +293,8 @@ "id": "ImportServiceRole", "path": "WebSocketApiInteg/MessageHandler/ServiceRole/ImportServiceRole", "constructInfo": { - "fqn": "aws-cdk-lib.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -332,14 +332,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.CfnRole", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_iam.Role", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -362,14 +362,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.Function", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "mywsapi": { @@ -388,8 +388,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnApi", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "$connect-Route": { @@ -437,8 +437,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ConnectIntegration": { @@ -481,14 +481,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -516,14 +516,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "$disconnect-Route": { @@ -571,8 +571,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DisconnectIntegration": { @@ -615,14 +615,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -650,14 +650,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "$default-Route": { @@ -705,8 +705,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "DefaultIntegration": { @@ -722,6 +722,7 @@ "apiId": { "Ref": "mywsapi32E6CE11" }, + "contentHandlingStrategy": "CONVERT_TO_TEXT", "integrationType": "AWS_PROXY", "integrationUri": { "Fn::Join": [ @@ -745,18 +746,19 @@ "/invocations" ] ] - } + }, + "timeoutInMillis": 10000 } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -784,14 +786,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "sendmessage-Route": { @@ -839,8 +841,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "SendMessageIntegration": { @@ -883,14 +885,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -918,20 +920,20 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketApi", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "mystage": { @@ -952,44 +954,44 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnStage", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketStage", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "ApiEndpoint": { "id": "ApiEndpoint", "path": "WebSocketApiInteg/ApiEndpoint", "constructInfo": { - "fqn": "aws-cdk-lib.CfnOutput", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "WebSocketApiInteg/BootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "WebSocketApiInteg/CheckBootstrapVersion", "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Tree": { @@ -997,13 +999,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.App", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts index 1760199995c72..45712d93d9e59 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts @@ -1,6 +1,6 @@ -import { WebSocketApi, WebSocketStage } from 'aws-cdk-lib/aws-apigatewayv2'; +import { ContentHandling, WebSocketApi, WebSocketStage } from 'aws-cdk-lib/aws-apigatewayv2'; import * as lambda from 'aws-cdk-lib/aws-lambda'; -import { App, CfnOutput, Stack } from 'aws-cdk-lib'; +import { App, CfnOutput, Duration, Stack } from 'aws-cdk-lib'; import { WebSocketLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'; /* @@ -41,7 +41,12 @@ const messageHandler = new lambda.Function(stack, 'MessageHandler', { const webSocketApi = new WebSocketApi(stack, 'mywsapi', { connectRouteOptions: { integration: new WebSocketLambdaIntegration('ConnectIntegration', connectHandler) }, disconnectRouteOptions: { integration: new WebSocketLambdaIntegration('DisconnectIntegration', disconnetHandler) }, - defaultRouteOptions: { integration: new WebSocketLambdaIntegration('DefaultIntegration', defaultHandler) }, + defaultRouteOptions: { + integration: new WebSocketLambdaIntegration('DefaultIntegration', defaultHandler, { + timeout: Duration.seconds(10), + contentHandling: ContentHandling.CONVERT_TO_TEXT, + }), + }, }); const stage = new WebSocketStage(stack, 'mystage', { webSocketApi, diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md index 82a9ea2cd6341..724ac8bcd4a59 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md @@ -303,4 +303,7 @@ webSocketApi.addRoute('$connect', { }, }), }); -``` \ No newline at end of file +``` + +You can also set additional properties to change the behavior of your integration, such as `contentHandling`. +See [Working with binary media types for WebSocket APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-develop-binary-media-types.html). \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/aws.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/aws.ts index 968234cbbac9f..dc265fb223b6c 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/aws.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/aws.ts @@ -4,11 +4,13 @@ import { WebSocketRouteIntegrationConfig, WebSocketRouteIntegrationBindOptions, PassthroughBehavior, + ContentHandling, } from '../../../aws-apigatewayv2'; import { IRole } from '../../../aws-iam'; +import { Duration } from '../../../core'; /** - * Props for AWS type integration for an HTTP Api. + * Props for AWS type integration for a WebSocket Api. */ export interface WebSocketAwsIntegrationProps { /** @@ -21,6 +23,14 @@ export interface WebSocketAwsIntegrationProps { */ readonly integrationMethod: string; + /** + * Specifies how to handle response payload content type conversions. + * + * @default - The response payload will be passed through from the integration response to + * the route response or method response without modification. + */ + readonly contentHandling?: ContentHandling; + /** * Specifies the credentials role required for the integration. * @@ -56,6 +66,14 @@ export interface WebSocketAwsIntegrationProps { */ readonly templateSelectionExpression?: string; + /** + * The maximum amount of time an integration will run before it returns without a response. + * Must be between 50 milliseconds and 29 seconds. + * + * @default Duration.seconds(29) + */ + readonly timeout?: Duration; + /** * Specifies the pass-through behavior for incoming requests based on the * Content-Type header in the request, and the available mapping templates @@ -84,11 +102,13 @@ export class WebSocketAwsIntegration extends WebSocketRouteIntegration { type: WebSocketIntegrationType.AWS, uri: this.props.integrationUri, method: this.props.integrationMethod, + contentHandling: this.props.contentHandling, credentialsRole: this.props.credentialsRole, requestParameters: this.props.requestParameters, requestTemplates: this.props.requestTemplates, passthroughBehavior: this.props.passthroughBehavior, templateSelectionExpression: this.props.templateSelectionExpression, + timeout: this.props.timeout, }; } } diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/lambda.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/lambda.ts index bdcd980e010b0..3ae153e63ec79 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/lambda.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/lambda.ts @@ -3,10 +3,32 @@ import { WebSocketIntegrationType, WebSocketRouteIntegrationBindOptions, WebSocketRouteIntegrationConfig, + ContentHandling, } from '../../../aws-apigatewayv2'; import { ServicePrincipal } from '../../../aws-iam'; import { IFunction } from '../../../aws-lambda'; -import { Stack } from '../../../core'; +import { Duration, Stack } from '../../../core'; + +/** + * Props for Lambda type integration for a WebSocket Api. + */ +export interface WebSocketLambdaIntegrationProps { + /** + * The maximum amount of time an integration will run before it returns without a response. + * Must be between 50 milliseconds and 29 seconds. + * + * @default Duration.seconds(29) + */ + readonly timeout?: Duration; + + /** + * Specifies how to handle response payload content type conversions. + * + * @default - The response payload will be passed through from the integration response to + * the route response or method response without modification. + */ + readonly contentHandling?: ContentHandling; +} /** * Lambda WebSocket Integration @@ -20,7 +42,11 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { * @param handler the Lambda function handler * @param props properties to configure the integration */ - constructor(id: string, private readonly handler: IFunction) { + constructor( + id: string, + private readonly handler: IFunction, + private readonly props: WebSocketLambdaIntegrationProps = {}, + ) { super(id); this._id = id; } @@ -47,6 +73,8 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { return { type: WebSocketIntegrationType.AWS_PROXY, uri: integrationUri, + timeout: this.props.timeout, + contentHandling: this.props.contentHandling, }; } } diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts index 4bdbf544e2c03..5294734854aba 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts @@ -1,9 +1,10 @@ import { WebSocketAwsIntegration } from './../../lib/websocket/aws'; import { Template } from '../../../assertions'; -import { WebSocketApi } from '../../../aws-apigatewayv2'; -import { Stack } from '../../../core'; +import { ContentHandling, PassthroughBehavior, WebSocketApi } from '../../../aws-apigatewayv2'; +import * as iam from '../../../aws-iam'; +import { Duration, Stack } from '../../../core'; -describe('MockWebSocketIntegration', () => { +describe('AwsWebSocketIntegration', () => { test('default', () => { // GIVEN const stack = new Stack(); @@ -25,4 +26,45 @@ describe('MockWebSocketIntegration', () => { IntegrationMethod: 'POST', }); }); + + test('can set custom properties', () => { + // GIVEN + const stack = new Stack(); + const role = new iam.Role(stack, 'MyRole', { assumedBy: new iam.ServicePrincipal('foo') }); + + // WHEN + new WebSocketApi(stack, 'Api', { + defaultRouteOptions: { + integration: new WebSocketAwsIntegration('AwsIntegration', { + integrationUri: 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem', + integrationMethod: 'POST', + credentialsRole: role, + requestParameters: { + 'integration.request.header.Content-Type': '\'application/x-www-form-urlencoded\'', + }, + requestTemplates: { 'application/json': '{ "statusCode": 200 }' }, + templateSelectionExpression: '\\$default', + passthroughBehavior: PassthroughBehavior.WHEN_NO_TEMPLATES, + contentHandling: ContentHandling.CONVERT_TO_BINARY, + timeout: Duration.seconds(10), + }), + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + IntegrationType: 'AWS', + IntegrationUri: 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem', + IntegrationMethod: 'POST', + CredentialsArn: { 'Fn::GetAtt': ['MyRoleF48FFE04', 'Arn'] }, + RequestParameters: { + 'integration.request.header.Content-Type': '\'application/x-www-form-urlencoded\'', + }, + RequestTemplates: { 'application/json': '{ "statusCode": 200 }' }, + TemplateSelectionExpression: '\\$default', + PassthroughBehavior: 'WHEN_NO_TEMPLATES', + ContentHandlingStrategy: 'CONVERT_TO_BINARY', + TimeoutInMillis: 10000, + }); + }); }); diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts index 05c263bb6a927..8b3298ac425c1 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts @@ -1,11 +1,35 @@ import { WebSocketLambdaIntegration } from './../../lib/websocket/lambda'; import { Template } from '../../../assertions'; -import { WebSocketApi } from '../../../aws-apigatewayv2'; +import { ContentHandling, WebSocketApi } from '../../../aws-apigatewayv2'; import { Code, Function } from '../../../aws-lambda'; import * as lambda from '../../../aws-lambda'; -import { Stack } from '../../../core'; +import { Duration, Stack } from '../../../core'; describe('LambdaWebSocketIntegration', () => { + const IntegrationUri = { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':apigateway:', + { + Ref: 'AWS::Region', + }, + ':lambda:path/2015-03-31/functions/', + { + 'Fn::GetAtt': [ + 'Fn9270CBC0', + 'Arn', + ], + }, + '/invocations', + ], + ], + }; + test('default', () => { // GIVEN const stack = new Stack(); @@ -21,30 +45,36 @@ describe('LambdaWebSocketIntegration', () => { // THEN Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'AWS_PROXY', - IntegrationUri: { - 'Fn::Join': [ - '', - [ - 'arn:', - { - Ref: 'AWS::Partition', - }, - ':apigateway:', - { - Ref: 'AWS::Region', - }, - ':lambda:path/2015-03-31/functions/', - { - 'Fn::GetAtt': [ - 'Fn9270CBC0', - 'Arn', - ], - }, - '/invocations', - ], - ], + IntegrationUri, + }); + }); + + test('can set custom properties', () => { + // GIVEN + const stack = new Stack(); + const fooFn = fooFunction(stack, 'Fn'); + + // WHEN + new WebSocketApi(stack, 'Api', { + connectRouteOptions: { + integration: new WebSocketLambdaIntegration( + 'Integration', + fooFn, + { + timeout: Duration.seconds(10), + contentHandling: ContentHandling.CONVERT_TO_TEXT, + }, + ), }, }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + IntegrationType: 'AWS_PROXY', + IntegrationUri, + TimeoutInMillis: 10000, + ContentHandlingStrategy: 'CONVERT_TO_TEXT', + }); }); }); diff --git a/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts b/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts index 58d4ed93464c8..2485f7368a5bc 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts @@ -3,7 +3,7 @@ import { IWebSocketApi } from './api'; import { IWebSocketRoute } from './route'; import { CfnIntegration } from '.././index'; import { IRole } from '../../../aws-iam'; -import { Resource } from '../../../core'; +import { Duration, Resource } from '../../../core'; import { IIntegration } from '../common'; /** @@ -32,6 +32,21 @@ export enum WebSocketIntegrationType { AWS = 'AWS', } +/** + * Integration content handling + */ +export enum ContentHandling { + /** + * Converts a request payload from a base64-encoded string to a binary blob. + */ + CONVERT_TO_BINARY = 'CONVERT_TO_BINARY', + + /** + * Converts a request payload from a binary blob to a base64-encoded string. + */ + CONVERT_TO_TEXT = 'CONVERT_TO_TEXT', +} + /** * Integration Passthrough Behavior */ @@ -82,6 +97,14 @@ export interface WebSocketIntegrationProps { */ readonly integrationMethod?: string; + /** + * Specifies how to handle response payload content type conversions. + * + * @default - The response payload will be passed through from the integration response to + * the route response or method response without modification. + */ + readonly contentHandling?: ContentHandling; + /** * Specifies the IAM role required for the integration. * @@ -117,6 +140,14 @@ export interface WebSocketIntegrationProps { */ readonly templateSelectionExpression?: string; + /** + * The maximum amount of time an integration will run before it returns without a response. + * Must be between 50 milliseconds and 29 seconds. + * + * @default Duration.seconds(29) + */ + readonly timeout?: Duration; + /** * Specifies the pass-through behavior for incoming requests based on the * Content-Type header in the request, and the available mapping templates @@ -144,11 +175,13 @@ export class WebSocketIntegration extends Resource implements IWebSocketIntegrat integrationType: props.integrationType, integrationUri: props.integrationUri, integrationMethod: props.integrationMethod, + contentHandlingStrategy: props.contentHandling, credentialsArn: props.credentialsRole?.roleArn, requestParameters: props.requestParameters, requestTemplates: props.requestTemplates, passthroughBehavior: props.passthroughBehavior, templateSelectionExpression: props.templateSelectionExpression, + timeoutInMillis: props.timeout?.toMilliseconds(), }); this.integrationId = integ.ref; this.webSocketApi = props.webSocketApi; @@ -201,9 +234,11 @@ export abstract class WebSocketRouteIntegration { integrationType: config.type, integrationUri: config.uri, integrationMethod: config.method, + contentHandling: config.contentHandling, credentialsRole: config.credentialsRole, requestTemplates: config.requestTemplates, requestParameters: config.requestParameters, + timeout: config.timeout, passthroughBehavior: config.passthroughBehavior, templateSelectionExpression: config.templateSelectionExpression, }); @@ -239,6 +274,14 @@ export interface WebSocketRouteIntegrationConfig { */ readonly method?: string; + /** + * Specifies how to handle response payload content type conversions. + * + * @default - The response payload will be passed through from the integration response to + * the route response or method response without modification. + */ + readonly contentHandling?: ContentHandling; + /** * Credentials role * @@ -267,6 +310,14 @@ export interface WebSocketRouteIntegrationConfig { */ readonly templateSelectionExpression?: string; + /** + * The maximum amount of time an integration will run before it returns without a response. + * Must be between 50 milliseconds and 29 seconds. + * + * @default Duration.seconds(29) + */ + readonly timeout?: Duration; + /** * Integration passthrough behaviors. *