Skip to content

Commit 841cf99

Browse files
authored
fix(apigateway): SAM CLI asset metadata missing from SpecRestApi (#17293)
Adds Assets metadata to RestApi resource in case if AssetApiDefinition is used. This Metadata will enable SAM CLI to find local assets used by RestApi in the template. It follows the same design in document [design/code-asset-metadata.md](https://github.com/aws/aws-cdk/pull/design/code-asset-metadata.md) Fixes #14593 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 5900548 commit 841cf99

22 files changed

+94
-45
lines changed

packages/@aws-cdk/aws-apigateway/lib/api-definition.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import * as s3_assets from '@aws-cdk/aws-s3-assets';
33

44
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
55
// eslint-disable-next-line no-duplicate-imports, import/order
6+
import * as cxapi from '@aws-cdk/cx-api';
7+
import { Node } from 'constructs';
8+
import { CfnRestApi } from './apigateway.generated';
9+
import { IRestApi } from './restapi';
610
import { Construct } from '@aws-cdk/core';
711

812
/**
@@ -82,6 +86,15 @@ export abstract class ApiDefinition {
8286
* assume it's initialized. You may just use it as a construct scope.
8387
*/
8488
public abstract bind(scope: Construct): ApiDefinitionConfig;
89+
90+
/**
91+
* Called after the CFN RestApi resource has been created to allow the Api
92+
* Definition to bind to it. Specifically it's required to allow assets to add
93+
* metadata for tooling like SAM CLI to be able to find their origins.
94+
*/
95+
public bindAfterCreate(_scope: Construct, _restApi: IRestApi) {
96+
return;
97+
}
8598
}
8699

87100
/**
@@ -198,4 +211,18 @@ export class AssetApiDefinition extends ApiDefinition {
198211
},
199212
};
200213
}
214+
215+
public bindAfterCreate(scope: Construct, restApi: IRestApi) {
216+
if (!scope.node.tryGetContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT)) {
217+
return; // not enabled
218+
}
219+
220+
if (!this.asset) {
221+
throw new Error('bindToResource() must be called after bind()');
222+
}
223+
224+
const child = Node.of(restApi).defaultChild as CfnRestApi;
225+
child.addMetadata(cxapi.ASSET_RESOURCE_METADATA_PATH_KEY, this.asset.assetPath);
226+
child.addMetadata(cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY, 'BodyS3Location');
227+
}
201228
}

packages/@aws-cdk/aws-apigateway/lib/restapi.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ export class SpecRestApi extends RestApiBase {
626626
endpointConfiguration: this._configureEndpoints(props),
627627
parameters: props.parameters,
628628
});
629+
630+
props.apiDefinition.bindAfterCreate(this, this);
631+
629632
this.node.defaultChild = resource;
630633
this.restApiId = resource.ref;
631634
this.restApiRootResourceId = resource.attrRootResourceId;

packages/@aws-cdk/aws-apigateway/test/api-definition.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import '@aws-cdk/assert-internal/jest';
22
import * as path from 'path';
3+
import { ResourcePart } from '@aws-cdk/assert-internal';
34
import * as s3 from '@aws-cdk/aws-s3';
45
import * as cdk from '@aws-cdk/core';
6+
import * as cxapi from '@aws-cdk/cx-api';
57
import * as apigw from '../lib';
68

79
describe('api definition', () => {
@@ -73,6 +75,23 @@ describe('api definition', () => {
7375
expect(synthesized.assets.length).toEqual(1);
7476

7577
});
78+
79+
test('asset metadata added to RestApi resource that contains Asset Api Definition', () => {
80+
const stack = new cdk.Stack();
81+
stack.node.setContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT, true);
82+
const assetApiDefinition = apigw.ApiDefinition.fromAsset(path.join(__dirname, 'sample-definition.yaml'));
83+
new apigw.SpecRestApi(stack, 'API', {
84+
apiDefinition: assetApiDefinition,
85+
});
86+
87+
expect(stack).toHaveResource('AWS::ApiGateway::RestApi', {
88+
Metadata: {
89+
'aws:asset:path': 'asset.68497ac876de4e963fc8f7b5f1b28844c18ecc95e3f7c6e9e0bf250e03c037fb.yaml',
90+
'aws:asset:property': 'BodyS3Location',
91+
},
92+
}, ResourcePart.CompleteDefinition);
93+
94+
});
7695
});
7796

7897
describe('apigateway.ApiDefinition.fromBucket', () => {

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.expected.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@
7272
]
7373
}
7474
},
75-
"Handler": "index.handler",
7675
"Role": {
7776
"Fn::GetAtt": [
7877
"MyAuthorizerFunctionServiceRole8A34C19E",
7978
"Arn"
8079
]
8180
},
82-
"Runtime": "nodejs10.x"
81+
"Handler": "index.handler",
82+
"Runtime": "nodejs14.x"
8383
},
8484
"DependsOn": [
8585
"MyAuthorizerFunctionServiceRole8A34C19E"
@@ -313,4 +313,4 @@
313313
}
314314
}
315315
}
316-
}
316+
}

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.lit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const app = new App();
1515
const stack = new Stack(app, 'RequestAuthorizerInteg');
1616

1717
const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', {
18-
runtime: lambda.Runtime.NODEJS_10_X,
18+
runtime: lambda.Runtime.NODEJS_14_X,
1919
handler: 'index.handler',
2020
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.request-authorizer.handler')),
2121
});

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@
7272
]
7373
}
7474
},
75-
"Handler": "index.handler",
7675
"Role": {
7776
"Fn::GetAtt": [
7877
"MyAuthorizerFunctionServiceRole8A34C19E",
7978
"Arn"
8079
]
8180
},
82-
"Runtime": "nodejs10.x"
81+
"Handler": "index.handler",
82+
"Runtime": "nodejs14.x"
8383
},
8484
"DependsOn": [
8585
"MyAuthorizerFunctionServiceRole8A34C19E"

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const app = new App();
1616
const stack = new Stack(app, 'TokenAuthorizerIAMRoleInteg');
1717

1818
const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', {
19-
runtime: lambda.Runtime.NODEJS_10_X,
19+
runtime: lambda.Runtime.NODEJS_14_X,
2020
handler: 'index.handler',
2121
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')),
2222
});

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.expected.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@
7272
]
7373
}
7474
},
75-
"Handler": "index.handler",
7675
"Role": {
7776
"Fn::GetAtt": [
7877
"MyAuthorizerFunctionServiceRole8A34C19E",
7978
"Arn"
8079
]
8180
},
82-
"Runtime": "nodejs10.x"
81+
"Handler": "index.handler",
82+
"Runtime": "nodejs14.x"
8383
},
8484
"DependsOn": [
8585
"MyAuthorizerFunctionServiceRole8A34C19E"
@@ -313,4 +313,4 @@
313313
}
314314
}
315315
}
316-
}
316+
}

packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const app = new App();
1515
const stack = new Stack(app, 'TokenAuthorizerInteg');
1616

1717
const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', {
18-
runtime: lambda.Runtime.NODEJS_10_X,
18+
runtime: lambda.Runtime.NODEJS_14_X,
1919
handler: 'index.handler',
2020
code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')),
2121
});

packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,14 +564,14 @@
564564
]
565565
}
566566
},
567-
"Handler": "index.handler",
568567
"Role": {
569568
"Fn::GetAtt": [
570569
"handlerServiceRole187D5A5A",
571570
"Arn"
572571
]
573572
},
574-
"Runtime": "nodejs10.x"
573+
"Handler": "index.handler",
574+
"Runtime": "nodejs14.x"
575575
},
576576
"DependsOn": [
577577
"handlerServiceRole187D5A5A"

0 commit comments

Comments
 (0)