From 604b344ca34130c8c2a74d821adb02352be37ec3 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Tue, 30 Jun 2020 13:08:07 +0100 Subject: [PATCH 1/5] fix(apigateway): permission error in lambda integration when function name is modified Changing function name triggers a resource replacement - the old function is removed and replaced with a new function. However, the RestApi deployment remains untouched and is still pointing at the ARN of the, now stale, function. The fix is to trigger a new deployment if the function name changes. fixes #5306 --- .../aws-apigateway/lib/integration.ts | 16 ++++++++++-- .../aws-apigateway/lib/integrations/aws.ts | 5 ++-- .../aws-apigateway/lib/integrations/lambda.ts | 15 ++++++++--- .../@aws-cdk/aws-apigateway/lib/method.ts | 26 ++++++++----------- .../integ.restapi.multistack.expected.json | 4 +-- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integration.ts b/packages/@aws-cdk/aws-apigateway/lib/integration.ts index d7a9ec74f3b34..a2afbb8a41331 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integration.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integration.ts @@ -134,6 +134,18 @@ export interface IntegrationProps { readonly options?: IntegrationOptions; } +/** + * Result of binding an Integration to the Method + */ +export interface IntegrationConfig { + /** + * Triggers a new Deployment if the value of this property changes. + * Use this property to trigger new deployments for changes to values in this integration. + * @default - deployments are not triggered for any change of this integration. + */ + readonly triggerDeployment?: any; +} + /** * Base class for backend integrations for an API Gateway method. * @@ -156,8 +168,8 @@ export class Integration { * Can be overridden by subclasses to allow the integration to interact with the method * being integrated, access the REST API object, method ARNs, etc. */ - public bind(_method: Method) { - return; + public bind(_method: Method): IntegrationConfig { + return {}; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts index cd3854e2abd22..c2b7cc46d4cf1 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts @@ -1,5 +1,5 @@ import * as cdk from '@aws-cdk/core'; -import { Integration, IntegrationOptions, IntegrationType } from '../integration'; +import { Integration, IntegrationConfig, IntegrationOptions, IntegrationType } from '../integration'; import { Method } from '../method'; import { parseAwsApiCall } from '../util'; @@ -92,7 +92,8 @@ export class AwsIntegration extends Integration { }); } - public bind(method: Method) { + public bind(method: Method): IntegrationConfig { this.scope = method; + return {}; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index fe5e81678e85e..98f372bef032c 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -1,7 +1,7 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; -import { Lazy } from '@aws-cdk/core'; -import { IntegrationOptions } from '../integration'; +import { Lazy, Token } from '@aws-cdk/core'; +import { IntegrationConfig, IntegrationOptions } from '../integration'; import { Method } from '../method'; import { AwsIntegration } from './aws'; @@ -52,7 +52,7 @@ export class LambdaIntegration extends AwsIntegration { this.enableTest = options.allowTestInvoke === undefined ? true : false; } - public bind(method: Method) { + public bind(method: Method): IntegrationConfig { super.bind(method); const principal = new iam.ServicePrincipal('apigateway.amazonaws.com'); @@ -72,5 +72,14 @@ export class LambdaIntegration extends AwsIntegration { sourceArn: method.testMethodArn, }); } + + const cfnFunction = this.handler.node.defaultChild as lambda.CfnFunction; + let triggerDeployment; + if (!Token.isUnresolved(cfnFunction.functionName)) { + triggerDeployment = { functionName: cfnFunction.functionName }; + } + return { + triggerDeployment, + }; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index 8721d9e9da114..b4077c0daac83 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -192,6 +192,9 @@ export class Method extends Resource { authorizer._attachToApi(this.api); } + const integration = props.integration ?? this.resource.defaultIntegration ?? new MockIntegration(); + const bindResult = integration.bind(this); + const methodProps: CfnMethodProps = { resourceId: props.resource.resourceId, restApiId: this.api.restApiId, @@ -201,7 +204,7 @@ export class Method extends Resource { authorizationType, authorizerId, requestParameters: options.requestParameters || defaultMethodOptions.requestParameters, - integration: this.renderIntegration(props.integration), + integration: this.renderIntegration(integration), methodResponses: this.renderMethodResponses(options.methodResponses), requestModels: this.renderRequestModels(options.requestModels), requestValidatorId: this.requestValidatorId(options), @@ -219,7 +222,12 @@ export class Method extends Resource { const deployment = props.resource.api.latestDeployment; if (deployment) { deployment.node.addDependency(resource); - deployment.addToLogicalId({ method: methodProps }); + deployment.addToLogicalId({ + method: { + ...methodProps, + ...bindResult?.triggerDeployment, + }, + }); } } @@ -255,19 +263,7 @@ export class Method extends Resource { return this.api.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), 'test-invoke-stage'); } - private renderIntegration(integration?: Integration): CfnMethod.IntegrationProperty { - if (!integration) { - // use defaultIntegration from API if defined - if (this.resource.defaultIntegration) { - return this.renderIntegration(this.resource.defaultIntegration); - } - - // fallback to mock - return this.renderIntegration(new MockIntegration()); - } - - integration.bind(this); - + private renderIntegration(integration: Integration): CfnMethod.IntegrationProperty { const options = integration._props.options || { }; let credentials; diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json index 3404f37880155..22c144974ed4d 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json @@ -120,7 +120,7 @@ "BooksApi60AC975F" ] }, - "BooksApiDeployment86CA39AF7e6c771d47a1a3777eba99bffc037822": { + "BooksApiDeployment86CA39AFdfee6753c946e6cbf8b3d649e0cf1377": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -141,7 +141,7 @@ "Ref": "BooksApi60AC975F" }, "DeploymentId": { - "Ref": "BooksApiDeployment86CA39AF7e6c771d47a1a3777eba99bffc037822" + "Ref": "BooksApiDeployment86CA39AFdfee6753c946e6cbf8b3d649e0cf1377" }, "StageName": "prod" } From fe0fac4703b83d0ea6dad79037497eb27bb9ddf5 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Tue, 30 Jun 2020 16:56:03 +0100 Subject: [PATCH 2/5] PR feedback --- .../aws-apigateway/lib/integration.ts | 11 ++--- .../aws-apigateway/lib/integrations/aws.ts | 4 +- .../aws-apigateway/lib/integrations/lambda.ts | 11 +++-- .../@aws-cdk/aws-apigateway/lib/method.ts | 2 +- .../integ.restapi.multistack.expected.json | 4 +- .../aws-apigateway/test/test.lambda.ts | 44 +++++++++++++++++++ 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integration.ts b/packages/@aws-cdk/aws-apigateway/lib/integration.ts index a2afbb8a41331..ea7d8f2cad3c8 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integration.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integration.ts @@ -139,11 +139,12 @@ export interface IntegrationProps { */ export interface IntegrationConfig { /** - * Triggers a new Deployment if the value of this property changes. - * Use this property to trigger new deployments for changes to values in this integration. + * This value is included in computing the Deployment's fingerprint. When the fingerprint + * changes a new deployment is triggered. + * This property should carry a different value when the Deployment needs to be refreshed. * @default - deployments are not triggered for any change of this integration. */ - readonly triggerDeployment?: any; + readonly deploymentFingerprint?: string; } /** @@ -168,8 +169,8 @@ export class Integration { * Can be overridden by subclasses to allow the integration to interact with the method * being integrated, access the REST API object, method ARNs, etc. */ - public bind(_method: Method): IntegrationConfig { - return {}; + public bind(_method: Method): IntegrationConfig | undefined { + return; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts index c2b7cc46d4cf1..6300c3b77379d 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts @@ -92,8 +92,8 @@ export class AwsIntegration extends Integration { }); } - public bind(method: Method): IntegrationConfig { + public bind(method: Method): IntegrationConfig | undefined { this.scope = method; - return {}; + return; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index 98f372bef032c..93064fd4d977d 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -1,6 +1,7 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { Lazy, Token } from '@aws-cdk/core'; +import * as crypto from 'crypto'; import { IntegrationConfig, IntegrationOptions } from '../integration'; import { Method } from '../method'; import { AwsIntegration } from './aws'; @@ -52,7 +53,7 @@ export class LambdaIntegration extends AwsIntegration { this.enableTest = options.allowTestInvoke === undefined ? true : false; } - public bind(method: Method): IntegrationConfig { + public bind(method: Method): IntegrationConfig | undefined { super.bind(method); const principal = new iam.ServicePrincipal('apigateway.amazonaws.com'); @@ -74,12 +75,14 @@ export class LambdaIntegration extends AwsIntegration { } const cfnFunction = this.handler.node.defaultChild as lambda.CfnFunction; - let triggerDeployment; + let deploymentFingerprint; if (!Token.isUnresolved(cfnFunction.functionName)) { - triggerDeployment = { functionName: cfnFunction.functionName }; + const md5 = crypto.createHash('md5'); + md5.update(JSON.stringify({ functionName: cfnFunction.functionName })); + deploymentFingerprint = md5.digest('hex'); } return { - triggerDeployment, + deploymentFingerprint, }; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index b4077c0daac83..f389e09ceea2d 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -225,7 +225,7 @@ export class Method extends Resource { deployment.addToLogicalId({ method: { ...methodProps, - ...bindResult?.triggerDeployment, + integrationFingerprint: bindResult?.deploymentFingerprint, }, }); } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json index 22c144974ed4d..3092da250eb75 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json @@ -120,7 +120,7 @@ "BooksApi60AC975F" ] }, - "BooksApiDeployment86CA39AFdfee6753c946e6cbf8b3d649e0cf1377": { + "BooksApiDeployment86CA39AF56d02ab7284ced4885bcbbf29f6d01a6": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -141,7 +141,7 @@ "Ref": "BooksApi60AC975F" }, "DeploymentId": { - "Ref": "BooksApiDeployment86CA39AFdfee6753c946e6cbf8b3d649e0cf1377" + "Ref": "BooksApiDeployment86CA39AF56d02ab7284ced4885bcbbf29f6d01a6" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts index 4a979e7671f85..4397b8fd9d380 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts @@ -215,4 +215,48 @@ export = { test.done(); }, + + 'fingerprint is computed when functionName is specified'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const restapi = new apigateway.RestApi(stack, 'RestApi'); + const method = restapi.root.addMethod('ANY'); + const handler = new lambda.Function(stack, 'MyFunc', { + functionName: 'ThisFunction', + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline('loo'), + }); + const integration = new apigateway.LambdaIntegration(handler); + + // WHEN + const bindResult = integration.bind(method); + + // THEN + test.ok(bindResult?.deploymentFingerprint); + test.equals(bindResult!.deploymentFingerprint, '2092bc5e2b20cfce7e5eea5952f10c50'); + + test.done(); + }, + + 'fingerprint is not computed when functionName is not specified'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const restapi = new apigateway.RestApi(stack, 'RestApi'); + const method = restapi.root.addMethod('ANY'); + const handler = new lambda.Function(stack, 'MyFunc', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline('loo'), + }); + const integration = new apigateway.LambdaIntegration(handler); + + // WHEN + const bindResult = integration.bind(method); + + // THEN + test.equals(bindResult?.deploymentFingerprint, undefined); + + test.done(); + }, }; From 1d987b1b1d997ca37572eb1baa658d737366fe07 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 1 Jul 2020 15:15:33 +0100 Subject: [PATCH 3/5] PR feedback --- packages/@aws-cdk/aws-apigateway/lib/integration.ts | 9 +++++---- .../@aws-cdk/aws-apigateway/lib/integrations/lambda.ts | 9 +++------ packages/@aws-cdk/aws-apigateway/lib/method.ts | 2 +- .../test/integ.restapi.multistack.expected.json | 4 ++-- packages/@aws-cdk/aws-apigateway/test/test.lambda.ts | 6 +++--- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integration.ts b/packages/@aws-cdk/aws-apigateway/lib/integration.ts index ea7d8f2cad3c8..221987e77d04f 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integration.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integration.ts @@ -140,11 +140,12 @@ export interface IntegrationProps { export interface IntegrationConfig { /** * This value is included in computing the Deployment's fingerprint. When the fingerprint - * changes a new deployment is triggered. - * This property should carry a different value when the Deployment needs to be refreshed. - * @default - deployments are not triggered for any change of this integration. + * changes, a new deployment is triggered. + * This property should contain values associated with the Integration that upon changing + * should trigger a fresh the Deployment needs to be refreshed. + * @default undefined deployments are not triggered for any change to this integration. */ - readonly deploymentFingerprint?: string; + readonly deploymentToken?: { [key: string]: string }; } /** diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index 93064fd4d977d..71a17c23a7730 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -1,7 +1,6 @@ import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { Lazy, Token } from '@aws-cdk/core'; -import * as crypto from 'crypto'; import { IntegrationConfig, IntegrationOptions } from '../integration'; import { Method } from '../method'; import { AwsIntegration } from './aws'; @@ -75,14 +74,12 @@ export class LambdaIntegration extends AwsIntegration { } const cfnFunction = this.handler.node.defaultChild as lambda.CfnFunction; - let deploymentFingerprint; + let deploymentToken; if (!Token.isUnresolved(cfnFunction.functionName)) { - const md5 = crypto.createHash('md5'); - md5.update(JSON.stringify({ functionName: cfnFunction.functionName })); - deploymentFingerprint = md5.digest('hex'); + deploymentToken = { functionName: cfnFunction.functionName! }; // exclamation (!) -> isUnresolved() returns true when undefined is passed. } return { - deploymentFingerprint, + deploymentToken, }; } } diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index f389e09ceea2d..b9a9143df6506 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -225,7 +225,7 @@ export class Method extends Resource { deployment.addToLogicalId({ method: { ...methodProps, - integrationFingerprint: bindResult?.deploymentFingerprint, + integrationToken: bindResult?.deploymentToken, }, }); } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json index 3092da250eb75..fe765c46a576d 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json @@ -120,7 +120,7 @@ "BooksApi60AC975F" ] }, - "BooksApiDeployment86CA39AF56d02ab7284ced4885bcbbf29f6d01a6": { + "BooksApiDeployment86CA39AF207534cf9410d936d403a42e9ca0caa2": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -141,7 +141,7 @@ "Ref": "BooksApi60AC975F" }, "DeploymentId": { - "Ref": "BooksApiDeployment86CA39AF56d02ab7284ced4885bcbbf29f6d01a6" + "Ref": "BooksApiDeployment86CA39AF207534cf9410d936d403a42e9ca0caa2" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts index 4397b8fd9d380..09dadfec3165a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts @@ -233,8 +233,8 @@ export = { const bindResult = integration.bind(method); // THEN - test.ok(bindResult?.deploymentFingerprint); - test.equals(bindResult!.deploymentFingerprint, '2092bc5e2b20cfce7e5eea5952f10c50'); + test.ok(bindResult?.deploymentToken); + test.deepEqual(bindResult!.deploymentToken, { functionName: 'ThisFunction' }); test.done(); }, @@ -255,7 +255,7 @@ export = { const bindResult = integration.bind(method); // THEN - test.equals(bindResult?.deploymentFingerprint, undefined); + test.equals(bindResult?.deploymentToken, undefined); test.done(); }, From 889d44ba44405bad9df88dba0093964a4777aa85 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 1 Jul 2020 18:29:53 +0100 Subject: [PATCH 4/5] PR feedback --- packages/@aws-cdk/aws-apigateway/lib/integration.ts | 2 +- packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts | 3 ++- .../test/integ.restapi.multistack.expected.json | 4 ++-- packages/@aws-cdk/aws-apigateway/test/test.lambda.ts | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integration.ts b/packages/@aws-cdk/aws-apigateway/lib/integration.ts index 221987e77d04f..6f305e2932efb 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integration.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integration.ts @@ -145,7 +145,7 @@ export interface IntegrationConfig { * should trigger a fresh the Deployment needs to be refreshed. * @default undefined deployments are not triggered for any change to this integration. */ - readonly deploymentToken?: { [key: string]: string }; + readonly deploymentToken?: string; } /** diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index 71a17c23a7730..221521e532556 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -76,7 +76,8 @@ export class LambdaIntegration extends AwsIntegration { const cfnFunction = this.handler.node.defaultChild as lambda.CfnFunction; let deploymentToken; if (!Token.isUnresolved(cfnFunction.functionName)) { - deploymentToken = { functionName: cfnFunction.functionName! }; // exclamation (!) -> isUnresolved() returns true when undefined is passed. + // functionName cannot be undefined since isUnresolved() filteres undefined. So use exclamation (!) + deploymentToken = JSON.stringify({ functionName: cfnFunction.functionName! }); } return { deploymentToken, diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json index fe765c46a576d..92ca8ad632bfc 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json @@ -120,7 +120,7 @@ "BooksApi60AC975F" ] }, - "BooksApiDeployment86CA39AF207534cf9410d936d403a42e9ca0caa2": { + "BooksApiDeployment86CA39AFc1570c78b1ea90526c0309cd74b7b8d0": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -141,7 +141,7 @@ "Ref": "BooksApi60AC975F" }, "DeploymentId": { - "Ref": "BooksApiDeployment86CA39AF207534cf9410d936d403a42e9ca0caa2" + "Ref": "BooksApiDeployment86CA39AFc1570c78b1ea90526c0309cd74b7b8d0" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts index 09dadfec3165a..afc1a2230e848 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.lambda.ts @@ -234,7 +234,7 @@ export = { // THEN test.ok(bindResult?.deploymentToken); - test.deepEqual(bindResult!.deploymentToken, { functionName: 'ThisFunction' }); + test.deepEqual(bindResult!.deploymentToken, '{"functionName":"ThisFunction"}'); test.done(); }, From e8c043cc275675445e161bc4fda2e870d5a28c5d Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 1 Jul 2020 19:10:57 +0100 Subject: [PATCH 5/5] drop exclamation --- packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts index 221521e532556..715c1d91237fe 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/lambda.ts @@ -76,8 +76,7 @@ export class LambdaIntegration extends AwsIntegration { const cfnFunction = this.handler.node.defaultChild as lambda.CfnFunction; let deploymentToken; if (!Token.isUnresolved(cfnFunction.functionName)) { - // functionName cannot be undefined since isUnresolved() filteres undefined. So use exclamation (!) - deploymentToken = JSON.stringify({ functionName: cfnFunction.functionName! }); + deploymentToken = JSON.stringify({ functionName: cfnFunction.functionName }); } return { deploymentToken,