Skip to content

Commit 5035080

Browse files
authored
fix(integ-tests): cannot use v3 package name in an awsApiCall (#28895)
When using the `awsApiCall` of integ-tests, several possible ways exist to specify the `service` and `api`. This is made possible by the following PR. https://github.com/aws/aws-cdk/pull/27313/files#diff-3ab65cbf843775673ff370c9c90deceba5f0ead8a3e016e0c2f243d27bf84609 However, currently, when specifying the package name or client name in SDK V3, the resource type in custom resource or the logical id in CloudFormation Output contains non-alphanumeric (`@`, `/`, `-`), which results in an error. For custom resources, the resource type can include alphanumeric characters and the following characters: `_@-` https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#aws-resource-cloudformation-customresource--remarks For `CfnOutput`, the logical id can include only alphanumeric. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html#outputs-section-syntax This PR fixes to remove these strings that cannot be included and allows users to specify the SDK v3 package name and client name when using `awsApiCall`. Closes #28844 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent ffcae2f commit 5035080

File tree

12 files changed

+370
-24
lines changed

12 files changed

+370
-24
lines changed

packages/@aws-cdk/integ-tests-alpha/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,20 @@ integ.assertions.awsApiCall('SQS', 'receiveMessage', {
306306
});
307307
```
308308

309+
You must specify the `service` and the `api` when using The `AwsApiCall` construct.
310+
The `service` is the name of an AWS service, in one of the following forms:
311+
312+
- An AWS SDK for JavaScript v3 package name (`@aws-sdk/client-api-gateway`)
313+
- An AWS SDK for JavaScript v3 client name (`api-gateway`)
314+
- An AWS SDK for JavaScript v2 constructor name (`APIGateway`)
315+
- A lowercase AWS SDK for JavaScript v2 constructor name (`apigateway`)
316+
317+
The `api` is the name of an AWS API call, in one of the following forms:
318+
319+
- An API call name as found in the API Reference documentation (`GetObject`)
320+
- The API call name starting with a lowercase letter (`getObject`)
321+
- The AWS SDK for JavaScript v3 command class name (`GetObjectCommand`)
322+
309323
By default, the `AwsApiCall` construct will automatically add the correct IAM policies
310324
to allow the Lambda function to make the API call. It does this based on the `service`
311325
and `api` that is provided. In the above example the service is `SQS` and the api is

packages/@aws-cdk/integ-tests-alpha/lib/assertions/sdk.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ export class AwsApiCall extends ApiCallBase {
9797
outputPaths: Lazy.list({ produce: () => this.outputPaths }),
9898
salt: Date.now().toString(),
9999
},
100-
resourceType: `${SDK_RESOURCE_TYPE_PREFIX}${this.name}`.substring(0, 60),
100+
// Remove the slash from the resource type because when using the v3 package name as the service name,
101+
// the `service` props includes the slash, but the resource type name cannot contain the slash
102+
// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#aws-resource-cloudformation-customresource--remarks
103+
resourceType: `${SDK_RESOURCE_TYPE_PREFIX}${this.name}`.substring(0, 60).replace(/[\/]/g, ''),
101104
});
102105
// Needed so that all the policies set up by the provider should be available before the custom resource is provisioned.
103106
this.apiCallResource.node.addDependency(this.provider);
@@ -112,7 +115,10 @@ export class AwsApiCall extends ApiCallBase {
112115

113116
new CfnOutput(node, 'AssertionResults', {
114117
value: result,
115-
}).overrideLogicalId(`AssertionResults${id}`);
118+
// Remove the at sign, slash, and hyphen because when using the v3 package name or client name as the service name,
119+
// the `id` includes them, but they are not allowed in the `CfnOutput` logical id
120+
// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html#outputs-section-syntax
121+
}).overrideLogicalId(`AssertionResults${id}`.replace(/[\@\/\-]/g, ''));
116122
}
117123
}
118124
},

packages/@aws-cdk/integ-tests-alpha/lib/assertions/types.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,21 @@ import { LambdaInvokeFunctionProps } from './sdk';
1010
*/
1111
export interface IDeployAssert {
1212
/**
13-
* Query AWS using JavaScript SDK V2 API calls. This can be used to either
13+
* Query AWS using JavaScript SDK API calls. This can be used to either
1414
* trigger an action or to return a result that can then be asserted against
1515
* an expected value
1616
*
17+
* The `service` is the name of an AWS service, in one of the following forms:
18+
* - An AWS SDK for JavaScript v3 package name (`@aws-sdk/client-api-gateway`)
19+
* - An AWS SDK for JavaScript v3 client name (`api-gateway`)
20+
* - An AWS SDK for JavaScript v2 constructor name (`APIGateway`)
21+
* - A lowercase AWS SDK for JavaScript v2 constructor name (`apigateway`)
22+
*
23+
* The `api` is the name of an AWS API call, in one of the following forms:
24+
* - An API call name as found in the API Reference documentation (`GetObject`)
25+
* - The API call name starting with a lowercase letter (`getObject`)
26+
* - The AWS SDK for JavaScript v3 command class name (`GetObjectCommand`)
27+
*
1728
* @example
1829
* declare const app: App;
1930
* declare const integ: IntegTest;

packages/@aws-cdk/integ-tests-alpha/test/assertions/deploy-assert.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,57 @@ describe('DeployAssert', () => {
191191
template.resourceCountIs('AWS::Lambda::Function', 1);
192192
template.resourceCountIs(truncatedType, 1);
193193
});
194+
195+
test('can use v3 package name and command class name', () => {
196+
// GIVEN
197+
const app = new App();
198+
199+
// WHEN
200+
const deplossert = new DeployAssert(app);
201+
deplossert.awsApiCall('@aws-sdk/client-ssm', 'GetParameterCommand');
202+
203+
// THEN
204+
const template = Template.fromStack(deplossert.scope);
205+
206+
template.resourceCountIs('AWS::Lambda::Function', 1);
207+
template.resourcePropertiesCountIs(
208+
'Custom::DeployAssert@SdkCall@aws-sdkclient-ssmGetParameterC',
209+
{
210+
service: '@aws-sdk/client-ssm',
211+
api: 'GetParameterCommand',
212+
},
213+
1,
214+
);
215+
});
216+
217+
test('can use v3 package name and command class name with assertions', () => {
218+
// GIVEN
219+
const app = new App();
220+
221+
// WHEN
222+
const deplossert = new DeployAssert(app);
223+
deplossert.awsApiCall('@aws-sdk/client-ssm', 'GetParameterCommand').expect(
224+
ExpectedResult.objectLike({}),
225+
);;
226+
227+
// THEN
228+
const template = Template.fromStack(deplossert.scope);
229+
230+
template.resourceCountIs('AWS::Lambda::Function', 1);
231+
template.resourcePropertiesCountIs(
232+
'Custom::DeployAssert@SdkCall@aws-sdkclient-ssmGetParameterC',
233+
{
234+
service: '@aws-sdk/client-ssm',
235+
api: 'GetParameterCommand',
236+
},
237+
1,
238+
);
239+
template.hasOutput('AssertionResultsAwsApiCallawssdkclientssmGetParameterCommand', {
240+
Value: {
241+
'Fn::GetAtt': ['AwsApiCallawssdkclientssmGetParameterCommand', 'assertion'],
242+
},
243+
});
244+
});
194245
});
195246

196247
describe('httpApiCall', () => {

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/Assertions.assets.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/AssertionsTestDefaultTestDeployAssertDC0672BB.assets.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/AssertionsTestDefaultTestDeployAssertDC0672BB.template.json

Lines changed: 109 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/cdk.out

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/integ.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/integ.assertions.js.snapshot/manifest.json

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)