Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(integ-tests): cannot use v3 package name in an awsApiCall #28895

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/@aws-cdk/integ-tests-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,20 @@ integ.assertions.awsApiCall('SQS', 'receiveMessage', {
});
```

You must specify the `service` and the `api` when using The `AwsApiCall` construct.
The `service` is the name of an AWS service, in one of the following forms:

- An AWS SDK for JavaScript v3 package name (`@aws-sdk/client-api-gateway`)
- An AWS SDK for JavaScript v3 client name (`api-gateway`)
- An AWS SDK for JavaScript v2 constructor name (`APIGateway`)
- A lowercase AWS SDK for JavaScript v2 constructor name (`apigateway`)

The `api` is the name of an AWS API call, in one of the following forms:

- An API call name as found in the API Reference documentation (`GetObject`)
- The API call name starting with a lowercase letter (`getObject`)
- The AWS SDK for JavaScript v3 command class name (`GetObjectCommand`)

By default, the `AwsApiCall` construct will automatically add the correct IAM policies
to allow the Lambda function to make the API call. It does this based on the `service`
and `api` that is provided. In the above example the service is `SQS` and the api is
Expand Down
10 changes: 8 additions & 2 deletions packages/@aws-cdk/integ-tests-alpha/lib/assertions/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ export class AwsApiCall extends ApiCallBase {
outputPaths: Lazy.list({ produce: () => this.outputPaths }),
salt: Date.now().toString(),
},
resourceType: `${SDK_RESOURCE_TYPE_PREFIX}${this.name}`.substring(0, 60),
// Remove the slash from the resource type because when using the v3 package name as the service name,
// the `service` props includes the slash, but the resource type name cannot contain the slash
// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html#aws-resource-cloudformation-customresource--remarks
resourceType: `${SDK_RESOURCE_TYPE_PREFIX}${this.name}`.substring(0, 60).replace(/[\/]/g, ''),
});
// Needed so that all the policies set up by the provider should be available before the custom resource is provisioned.
this.apiCallResource.node.addDependency(this.provider);
Expand All @@ -112,7 +115,10 @@ export class AwsApiCall extends ApiCallBase {

new CfnOutput(node, 'AssertionResults', {
value: result,
}).overrideLogicalId(`AssertionResults${id}`);
// Remove the at sign, slash, and hyphen because when using the v3 package name or client name as the service name,
// the `id` includes them, but they are not allowed in the `CfnOutput` logical id
// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html#outputs-section-syntax
}).overrideLogicalId(`AssertionResults${id}`.replace(/[\@\/\-]/g, ''));
}
}
},
Expand Down
13 changes: 12 additions & 1 deletion packages/@aws-cdk/integ-tests-alpha/lib/assertions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,21 @@ import { LambdaInvokeFunctionProps } from './sdk';
*/
export interface IDeployAssert {
/**
* Query AWS using JavaScript SDK V2 API calls. This can be used to either
* Query AWS using JavaScript SDK API calls. This can be used to either
* trigger an action or to return a result that can then be asserted against
* an expected value
*
* The `service` is the name of an AWS service, in one of the following forms:
* - An AWS SDK for JavaScript v3 package name (`@aws-sdk/client-api-gateway`)
* - An AWS SDK for JavaScript v3 client name (`api-gateway`)
* - An AWS SDK for JavaScript v2 constructor name (`APIGateway`)
* - A lowercase AWS SDK for JavaScript v2 constructor name (`apigateway`)
*
* The `api` is the name of an AWS API call, in one of the following forms:
* - An API call name as found in the API Reference documentation (`GetObject`)
* - The API call name starting with a lowercase letter (`getObject`)
* - The AWS SDK for JavaScript v3 command class name (`GetObjectCommand`)
*
* @example
* declare const app: App;
* declare const integ: IntegTest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,57 @@ describe('DeployAssert', () => {
template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourceCountIs(truncatedType, 1);
});

test('can use v3 package name and command class name', () => {
// GIVEN
const app = new App();

// WHEN
const deplossert = new DeployAssert(app);
deplossert.awsApiCall('@aws-sdk/client-ssm', 'GetParameterCommand');

// THEN
const template = Template.fromStack(deplossert.scope);

template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourcePropertiesCountIs(
'Custom::DeployAssert@SdkCall@aws-sdkclient-ssmGetParameterC',
{
service: '@aws-sdk/client-ssm',
api: 'GetParameterCommand',
},
1,
);
});

test('can use v3 package name and command class name with assertions', () => {
// GIVEN
const app = new App();

// WHEN
const deplossert = new DeployAssert(app);
deplossert.awsApiCall('@aws-sdk/client-ssm', 'GetParameterCommand').expect(
ExpectedResult.objectLike({}),
);;

// THEN
const template = Template.fromStack(deplossert.scope);

template.resourceCountIs('AWS::Lambda::Function', 1);
template.resourcePropertiesCountIs(
'Custom::DeployAssert@SdkCall@aws-sdkclient-ssmGetParameterC',
{
service: '@aws-sdk/client-ssm',
api: 'GetParameterCommand',
},
1,
);
template.hasOutput('AssertionResultsAwsApiCallawssdkclientssmGetParameterCommand', {
Value: {
'Fn::GetAtt': ['AwsApiCallawssdkclientssmGetParameterCommand', 'assertion'],
},
});
});
});

describe('httpApiCall', () => {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.