From ceba418d86d0e648b5f2743a0f401a83c0190879 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 07:41:36 +0100 Subject: [PATCH 1/7] feat(apigatewayv2): add missing `WebSocketIntegration` props --- .../lib/websocket/aws.ts | 22 +++++- .../lib/websocket/lambda.ts | 22 +++++- .../test/websocket/aws.test.ts | 44 +++++++++++- .../test/websocket/lambda.test.ts | 72 +++++++++++++------ .../lib/websocket/integration.ts | 53 +++++++++++++- 5 files changed, 183 insertions(+), 30 deletions(-) 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..02782ce7fab78 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 { /** @@ -56,6 +58,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 @@ -66,6 +76,14 @@ export interface WebSocketAwsIntegrationProps { * @default - No passthrough behavior required. */ readonly passthroughBehavior?: PassthroughBehavior; + + /** + * 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; } /** @@ -88,7 +106,9 @@ export class WebSocketAwsIntegration extends WebSocketRouteIntegration { requestParameters: this.props.requestParameters, requestTemplates: this.props.requestTemplates, passthroughBehavior: this.props.passthroughBehavior, + contentHandling: this.props.contentHandling, 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..5f18035c00720 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 @@ -6,7 +6,20 @@ import { } 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; +} /** * Lambda WebSocket Integration @@ -20,7 +33,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 +64,7 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { return { type: WebSocketIntegrationType.AWS_PROXY, uri: integrationUri, + timeout: this.props.timeout, }; } } 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..06b59487f7224 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,41 @@ 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: { foo: 'bar' }, + requestTemplates: { 'application/json': '{ "statusCode": 200 }' }, + templateSelectionExpression: '$request.body', + 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: { foo: 'bar' }, + RequestTemplates: { 'application/json': '{ "statusCode": 200 }' }, + TemplateSelectionExpression: '$request.body', + 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..80a846f6f163b 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 @@ -3,9 +3,33 @@ import { Template } from '../../../assertions'; import { 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,32 @@ 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 a custom timeout', () => { + // 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) }, + ), }, }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + IntegrationType: 'AWS_PROXY', + IntegrationUri, + TimeoutInMillis: 10000, + }); }); }); 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..244fd410b6d61 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'; /** @@ -56,6 +56,21 @@ export enum PassthroughBehavior { WHEN_NO_TEMPLATES = 'WHEN_NO_TEMPLATES', } +/** + * 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', +} + /** * The integration properties */ @@ -117,6 +132,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 @@ -127,6 +150,14 @@ export interface WebSocketIntegrationProps { * @default - No passthrough behavior required. */ readonly passthroughBehavior?: PassthroughBehavior; + + /** + * 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; } /** @@ -149,6 +180,8 @@ export class WebSocketIntegration extends Resource implements IWebSocketIntegrat requestTemplates: props.requestTemplates, passthroughBehavior: props.passthroughBehavior, templateSelectionExpression: props.templateSelectionExpression, + contentHandlingStrategy: props.contentHandling, + 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, }); @@ -267,10 +302,26 @@ 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. * * @default - No pass through bahavior. */ readonly passthroughBehavior?: PassthroughBehavior; + + /** + * 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; } From 3527eed978d1b4b08bf9e9b142a9560f6f8b622e Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 07:49:28 +0100 Subject: [PATCH 2/7] chore: fix prop order --- .../lib/websocket/aws.ts | 18 +++--- .../lib/websocket/integration.ts | 64 +++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) 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 02782ce7fab78..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 @@ -23,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. * @@ -76,14 +84,6 @@ export interface WebSocketAwsIntegrationProps { * @default - No passthrough behavior required. */ readonly passthroughBehavior?: PassthroughBehavior; - - /** - * 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; } /** @@ -102,11 +102,11 @@ 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, - contentHandling: this.props.contentHandling, templateSelectionExpression: this.props.templateSelectionExpression, timeout: this.props.timeout, }; 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 244fd410b6d61..2485f7368a5bc 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2/lib/websocket/integration.ts @@ -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 */ @@ -56,21 +71,6 @@ export enum PassthroughBehavior { WHEN_NO_TEMPLATES = 'WHEN_NO_TEMPLATES', } -/** - * 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', -} - /** * The integration properties */ @@ -97,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. * @@ -150,14 +158,6 @@ export interface WebSocketIntegrationProps { * @default - No passthrough behavior required. */ readonly passthroughBehavior?: PassthroughBehavior; - - /** - * 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; } /** @@ -175,12 +175,12 @@ 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, - contentHandlingStrategy: props.contentHandling, timeoutInMillis: props.timeout?.toMilliseconds(), }); this.integrationId = integ.ref; @@ -274,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 * @@ -316,12 +324,4 @@ export interface WebSocketRouteIntegrationConfig { * @default - No pass through bahavior. */ readonly passthroughBehavior?: PassthroughBehavior; - - /** - * 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; } From 3c3b2b9bc8c752804a477a6621ef51b4c4937994 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 08:57:05 +0100 Subject: [PATCH 3/7] chore: lambda integ --- .../WebSocketApiInteg.assets.json | 6 ++--- .../WebSocketApiInteg.template.json | 3 ++- .../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 | 25 ++++++++++--------- .../test/websocket/integ.lambda.ts | 4 +-- 7 files changed, 28 insertions(+), 38 deletions(-) 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..f17489e73e483 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": { + "a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894": { "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": "a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894.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..c45d7d6e8fe18 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 @@ -454,7 +454,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..dff3a6e0238f0 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}/a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894.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..7abceb0fd8ac1 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 @@ -487,7 +487,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketIntegration", "version": "0.0.0" } }, @@ -522,7 +522,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketRoute", "version": "0.0.0" } }, @@ -621,7 +621,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketIntegration", "version": "0.0.0" } }, @@ -656,7 +656,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketRoute", "version": "0.0.0" } }, @@ -745,7 +745,8 @@ "/invocations" ] ] - } + }, + "timeoutInMillis": 10000 } }, "constructInfo": { @@ -755,7 +756,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketIntegration", "version": "0.0.0" } }, @@ -790,7 +791,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketRoute", "version": "0.0.0" } }, @@ -889,7 +890,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketIntegration", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketIntegration", "version": "0.0.0" } }, @@ -924,13 +925,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketRoute", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketRoute", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketApi", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketApi", "version": "0.0.0" } }, @@ -958,7 +959,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-apigatewayv2-alpha.WebSocketStage", + "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketStage", "version": "0.0.0" } }, @@ -997,7 +998,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.70" + "version": "10.3.0" } } }, 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..ae9274e981f11 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 * 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,7 @@ 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) }) }, }); const stage = new WebSocketStage(stack, 'mystage', { webSocketApi, From 6f340748fef9123db2bd097b46678c59a0f3c2fe Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 09:31:50 +0100 Subject: [PATCH 4/7] chore: aws integ --- ...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 ++++++++-- .../test/websocket/aws.test.ts | 12 +++++++---- 6 files changed, 36 insertions(+), 29 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-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/aws.test.ts index 06b59487f7224..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 @@ -39,9 +39,11 @@ describe('AwsWebSocketIntegration', () => { integrationUri: 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem', integrationMethod: 'POST', credentialsRole: role, - requestParameters: { foo: 'bar' }, + requestParameters: { + 'integration.request.header.Content-Type': '\'application/x-www-form-urlencoded\'', + }, requestTemplates: { 'application/json': '{ "statusCode": 200 }' }, - templateSelectionExpression: '$request.body', + templateSelectionExpression: '\\$default', passthroughBehavior: PassthroughBehavior.WHEN_NO_TEMPLATES, contentHandling: ContentHandling.CONVERT_TO_BINARY, timeout: Duration.seconds(10), @@ -55,9 +57,11 @@ describe('AwsWebSocketIntegration', () => { IntegrationUri: 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem', IntegrationMethod: 'POST', CredentialsArn: { 'Fn::GetAtt': ['MyRoleF48FFE04', 'Arn'] }, - RequestParameters: { foo: 'bar' }, + RequestParameters: { + 'integration.request.header.Content-Type': '\'application/x-www-form-urlencoded\'', + }, RequestTemplates: { 'application/json': '{ "statusCode": 200 }' }, - TemplateSelectionExpression: '$request.body', + TemplateSelectionExpression: '\\$default', PassthroughBehavior: 'WHEN_NO_TEMPLATES', ContentHandlingStrategy: 'CONVERT_TO_BINARY', TimeoutInMillis: 10000, From 5458ee7e2601bc772b2d0e76ba0641de2115e365 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 09:46:22 +0100 Subject: [PATCH 5/7] feat: add contentHandling support for WebSocketLambdaIntegration --- .../WebSocketApiInteg.assets.json | 4 +- .../WebSocketApiInteg.template.json | 1 + .../integ.lambda.js.snapshot/manifest.json | 2 +- .../integ.lambda.js.snapshot/tree.json | 197 +++++++++--------- .../test/websocket/integ.lambda.ts | 9 +- .../lib/websocket/lambda.ts | 11 + .../test/websocket/lambda.test.ts | 10 +- 7 files changed, 128 insertions(+), 106 deletions(-) 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 f17489e73e483..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": "36.0.0", "files": { - "a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894": { + "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": "a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894.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 c45d7d6e8fe18..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": [ 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 dff3a6e0238f0..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 @@ -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}/a375a1b42c144b1a87ed46ada116a51c8c249ac8f08df1f08fce63e4f55eb894.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f542f97a9aa5e38fc369d5e5530a480ab81374b9796bc3e79ae4f98411f2900b.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ 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 7abceb0fd8ac1..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-lib.aws_apigatewayv2.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-lib.aws_apigatewayv2.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-lib.aws_apigatewayv2.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-lib.aws_apigatewayv2.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": [ @@ -750,14 +751,14 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -785,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-lib.aws_apigatewayv2.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "sendmessage-Route": { @@ -840,8 +841,8 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "SendMessageIntegration": { @@ -884,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-lib.aws_apigatewayv2.WebSocketIntegration", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "Resource": { @@ -919,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-lib.aws_apigatewayv2.WebSocketRoute", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "aws-cdk-lib.aws_apigatewayv2.WebSocketApi", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.3.0" } }, "mystage": { @@ -953,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-lib.aws_apigatewayv2.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": { @@ -1003,8 +1004,8 @@ } }, "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 ae9274e981f11..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,4 +1,4 @@ -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, 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, { timeout: Duration.seconds(10) }) }, + 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/lib/websocket/lambda.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/websocket/lambda.ts index 5f18035c00720..c9f0fb71a5832 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,6 +3,7 @@ import { WebSocketIntegrationType, WebSocketRouteIntegrationBindOptions, WebSocketRouteIntegrationConfig, + ContentHandling, } from '../../../aws-apigatewayv2'; import { ServicePrincipal } from '../../../aws-iam'; import { IFunction } from '../../../aws-lambda'; @@ -19,6 +20,14 @@ export interface WebSocketLambdaIntegrationProps { * @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; } /** @@ -65,6 +74,8 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { 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/lambda.test.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts index 80a846f6f163b..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,6 +1,6 @@ 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 { Duration, Stack } from '../../../core'; @@ -49,7 +49,7 @@ describe('LambdaWebSocketIntegration', () => { }); }); - test('can set a custom timeout', () => { + test('can set custom properties', () => { // GIVEN const stack = new Stack(); const fooFn = fooFunction(stack, 'Fn'); @@ -60,7 +60,10 @@ describe('LambdaWebSocketIntegration', () => { integration: new WebSocketLambdaIntegration( 'Integration', fooFn, - { timeout: Duration.seconds(10) }, + { + timeout: Duration.seconds(10), + contentHandling: ContentHandling.CONVERT_TO_TEXT, + }, ), }, }); @@ -70,6 +73,7 @@ describe('LambdaWebSocketIntegration', () => { IntegrationType: 'AWS_PROXY', IntegrationUri, TimeoutInMillis: 10000, + ContentHandlingStrategy: 'CONVERT_TO_TEXT', }); }); }); From 861b6120b79e1f1eda3cb0d13dd8777c14021545 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 10:03:29 +0100 Subject: [PATCH 6/7] chore: update README --- packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 From 58625787bd0027bb375a760271c5fed957ac6966 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 21 Mar 2024 16:59:30 +0100 Subject: [PATCH 7/7] chore: remove newline --- .../aws-apigatewayv2-integrations/lib/websocket/lambda.ts | 1 - 1 file changed, 1 deletion(-) 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 c9f0fb71a5832..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 @@ -74,7 +74,6 @@ export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { type: WebSocketIntegrationType.AWS_PROXY, uri: integrationUri, timeout: this.props.timeout, - contentHandling: this.props.contentHandling, }; }