diff --git a/packages/@aws-cdk/aws-apigateway/lib/api-definition.ts b/packages/@aws-cdk/aws-apigateway/lib/api-definition.ts index 850087920f152..96b9a5aced9e1 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/api-definition.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/api-definition.ts @@ -3,6 +3,10 @@ import * as s3_assets from '@aws-cdk/aws-s3-assets'; // keep this import separate from other imports to reduce chance for merge conflicts with v2-main // eslint-disable-next-line no-duplicate-imports, import/order +import * as cxapi from '@aws-cdk/cx-api'; +import { Node } from 'constructs'; +import { CfnRestApi } from './apigateway.generated'; +import { IRestApi } from './restapi'; import { Construct } from '@aws-cdk/core'; /** @@ -82,6 +86,15 @@ export abstract class ApiDefinition { * assume it's initialized. You may just use it as a construct scope. */ public abstract bind(scope: Construct): ApiDefinitionConfig; + + /** + * Called after the CFN RestApi resource has been created to allow the Api + * Definition to bind to it. Specifically it's required to allow assets to add + * metadata for tooling like SAM CLI to be able to find their origins. + */ + public bindAfterCreate(_scope: Construct, _restApi: IRestApi) { + return; + } } /** @@ -198,4 +211,18 @@ export class AssetApiDefinition extends ApiDefinition { }, }; } + + public bindAfterCreate(scope: Construct, restApi: IRestApi) { + if (!scope.node.tryGetContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT)) { + return; // not enabled + } + + if (!this.asset) { + throw new Error('bindToResource() must be called after bind()'); + } + + const child = Node.of(restApi).defaultChild as CfnRestApi; + child.addMetadata(cxapi.ASSET_RESOURCE_METADATA_PATH_KEY, this.asset.assetPath); + child.addMetadata(cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY, 'BodyS3Location'); + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts index e213ddad7f22f..7cfebff08c9e0 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/restapi.ts @@ -626,6 +626,9 @@ export class SpecRestApi extends RestApiBase { endpointConfiguration: this._configureEndpoints(props), parameters: props.parameters, }); + + props.apiDefinition.bindAfterCreate(this, this); + this.node.defaultChild = resource; this.restApiId = resource.ref; this.restApiRootResourceId = resource.attrRootResourceId; diff --git a/packages/@aws-cdk/aws-apigateway/test/api-definition.test.ts b/packages/@aws-cdk/aws-apigateway/test/api-definition.test.ts index 709900b36c71d..c4af056038451 100644 --- a/packages/@aws-cdk/aws-apigateway/test/api-definition.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/api-definition.test.ts @@ -1,7 +1,9 @@ import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { ResourcePart } from '@aws-cdk/assert-internal'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; +import * as cxapi from '@aws-cdk/cx-api'; import * as apigw from '../lib'; describe('api definition', () => { @@ -73,6 +75,23 @@ describe('api definition', () => { expect(synthesized.assets.length).toEqual(1); }); + + test('asset metadata added to RestApi resource that contains Asset Api Definition', () => { + const stack = new cdk.Stack(); + stack.node.setContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT, true); + const assetApiDefinition = apigw.ApiDefinition.fromAsset(path.join(__dirname, 'sample-definition.yaml')); + new apigw.SpecRestApi(stack, 'API', { + apiDefinition: assetApiDefinition, + }); + + expect(stack).toHaveResource('AWS::ApiGateway::RestApi', { + Metadata: { + 'aws:asset:path': 'asset.68497ac876de4e963fc8f7b5f1b28844c18ecc95e3f7c6e9e0bf250e03c037fb.yaml', + 'aws:asset:property': 'BodyS3Location', + }, + }, ResourcePart.CompleteDefinition); + + }); }); describe('apigateway.ApiDefinition.fromBucket', () => { diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.expected.json index e976e6426e0a5..e59d8e02743fc 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.expected.json @@ -72,14 +72,14 @@ ] } }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "MyAuthorizerFunctionServiceRole8A34C19E", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "MyAuthorizerFunctionServiceRole8A34C19E" @@ -313,4 +313,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.ts index d8160e3be6f49..066badbe4e0bb 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.ts +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.ts @@ -15,7 +15,7 @@ const app = new App(); const stack = new Stack(app, 'RequestAuthorizerInteg'); const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.request-authorizer.handler')), }); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json index 1f3a157fc36b9..27e2f89e8f631 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json @@ -72,14 +72,14 @@ ] } }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "MyAuthorizerFunctionServiceRole8A34C19E", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "MyAuthorizerFunctionServiceRole8A34C19E" diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.ts index 47d05cf481009..5890d03f9bc3a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.ts +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.ts @@ -16,7 +16,7 @@ const app = new App(); const stack = new Stack(app, 'TokenAuthorizerIAMRoleInteg'); const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), }); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.expected.json index bb4c493fac04b..8a56511175436 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.expected.json @@ -72,14 +72,14 @@ ] } }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "MyAuthorizerFunctionServiceRole8A34C19E", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "MyAuthorizerFunctionServiceRole8A34C19E" @@ -313,4 +313,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts index e62e476e8cd4a..655fa91962b1a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts @@ -15,7 +15,7 @@ const app = new App(); const stack = new Stack(app, 'TokenAuthorizerInteg'); const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), }); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json index 6d17b2e53232e..146d5220f7540 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json @@ -564,14 +564,14 @@ ] } }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "handlerServiceRole187D5A5A", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "handlerServiceRole187D5A5A" diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.cors.ts b/packages/@aws-cdk/aws-apigateway/test/integ.cors.ts index 5b3fc8bdc36c2..e5617f4c9b202 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.cors.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.cors.ts @@ -12,7 +12,7 @@ class TestStack extends Stack { const api = new apigw.RestApi(this, 'cors-api-test'); const handler = new lambda.Function(this, 'handler', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'integ.cors.handler')), }); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json index 17dd7ccf222e8..8cf5ef7c0e552 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json @@ -37,14 +37,14 @@ "Code": { "ZipFile": "foo" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "myfnServiceRole7822DC24", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "myfnServiceRole7822DC24" diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.ts b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.ts index d6176fdb78301..615c934f918fe 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.ts @@ -9,7 +9,7 @@ class LateBoundDeploymentStageStack extends Stack { const fn = new Function(this, 'myfn', { code: Code.fromInline('foo'), - runtime: Runtime.NODEJS_10_X, + runtime: Runtime.NODEJS_14_X, handler: 'index.handler', }); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json index 91af30b6ef8d4..a77027807057d 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json @@ -37,14 +37,14 @@ "Code": { "ZipFile": "exports.handler = function echoHandlerCode(event, _, callback) {\n return callback(undefined, {\n isBase64Encoded: false,\n statusCode: 200,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(event),\n });\n}" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "BooksHandlerServiceRole5B6A8847", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "BooksHandlerServiceRole5B6A8847" @@ -87,14 +87,14 @@ "Code": { "ZipFile": "exports.handler = function echoHandlerCode(event, _, callback) {\n return callback(undefined, {\n isBase64Encoded: false,\n statusCode: 200,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(event),\n });\n}" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "BookHandlerServiceRole894768AD", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "BookHandlerServiceRole894768AD" @@ -137,14 +137,14 @@ "Code": { "ZipFile": "exports.handler = function helloCode(_event, _context, callback) {\n return callback(undefined, {\n statusCode: 200,\n body: 'hello, world!',\n });\n}" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "HelloServiceRole1E55EA16", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "HelloServiceRole1E55EA16" diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts index 9c647c83dcebd..0ec001e3d1a3a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts @@ -7,19 +7,19 @@ class BookStack extends cdk.Stack { super(scope, id); const booksHandler = new apigw.LambdaIntegration(new lambda.Function(this, 'BooksHandler', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromInline(`exports.handler = ${echoHandlerCode}`), })); const bookHandler = new apigw.LambdaIntegration(new lambda.Function(this, 'BookHandler', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromInline(`exports.handler = ${echoHandlerCode}`), })); const hello = new apigw.LambdaIntegration(new lambda.Function(this, 'Hello', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromInline(`exports.handler = ${helloCode}`), })); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json index a0fb6357db3c7..606c5f2098a0d 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json @@ -651,14 +651,14 @@ "Code": { "ZipFile": "exports.handler = function handlerCode(event, _, callback) {\n return callback(undefined, {\n isBase64Encoded: false,\n statusCode: 200,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(event),\n });\n }" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "MyHandlerServiceRoleFFA06653", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "MyHandlerServiceRoleFFA06653" 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 5aa57732955bc..198d0e80231ae 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 @@ -38,15 +38,15 @@ "Code": { "ZipFile": "exports.handler = async function(event) {\n return {\n 'headers': { 'Content-Type': 'text/plain' },\n 'statusCode': 200\n }\n }" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "firstLambdaServiceRoleB6408C31", "Arn" ] }, - "Runtime": "nodejs10.x", - "FunctionName": "FirstLambda" + "FunctionName": "FirstLambda", + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "firstLambdaServiceRoleB6408C31" diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.ts index 0ac4e01241eba..75b6e219613de 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.ts @@ -20,7 +20,7 @@ class FirstStack extends cdk.Stack { } }`), handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, }); } } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json index 6a7cea680ef60..0ed3cb19c6aad 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json @@ -37,14 +37,14 @@ "Code": { "ZipFile": "exports.handler = function helloCode(_event, _context, callback) {\n return callback(undefined, {\n statusCode: 200,\n body: 'hello, world!',\n });\n}" }, - "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "HelloServiceRole1E55EA16", "Arn" ] }, - "Runtime": "nodejs10.x" + "Handler": "index.handler", + "Runtime": "nodejs14.x" }, "DependsOn": [ "HelloServiceRole1E55EA16" diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.ts index a248bf9041158..612bd0e83b963 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.ts @@ -7,7 +7,7 @@ class MultiStack extends cdk.Stack { super(scope, id); const hello = new apigw.LambdaIntegration(new lambda.Function(this, 'Hello', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.handler', code: lambda.Code.fromInline(`exports.handler = ${helloCode}`), })); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts index 10e3d357108d7..537ec3031d58a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts @@ -23,7 +23,7 @@ class Test extends cdk.Stack { }); const handler = new lambda.Function(this, 'MyHandler', { - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_14_X, code: lambda.Code.fromInline(`exports.handler = ${handlerCode}`), handler: 'index.handler', }); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json index 9051ff580c010..4279ff70893aa 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json @@ -95,15 +95,15 @@ "MyVpcPublicSubnet1NATGatewayAD3400C1": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet1EIP096967CB", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet1SubnetF6608456" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "MyVpcPublicSubnet2NATGateway91BFBEC9": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet2EIP8CCBA239", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" - }, "Tags": [ { "Key": "Name", @@ -289,15 +289,15 @@ "MyVpcPublicSubnet3NATGatewayD4B50EBE": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet3Subnet57EEE236" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet3EIPC5ACADAB", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet3Subnet57EEE236" - }, "Tags": [ { "Key": "Name",