Skip to content

Commit

Permalink
fix(stepfunctions-tasks): allow camelCase for parameters of CallAwsSe…
Browse files Browse the repository at this point in the history
…rviceCrossRegion (#30795)

### Issue # (if applicable)
closes #30799

### Reason for this change

I found some AWS services uses camelCase for API parameters, such as [api-gateway](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/GetRestApiCommand/) or [bedrock-runtime](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/bedrock-runtime/command/InvokeModelCommand/). However, currently `CallAwsServiceCrossRegion` allows only PascalCase for parameters, and it throws an error if parameters are not in PascalCase.

### Description of changes

Because we do not precisely know which service uses camelCase, this PR just removes the validation logic to allow both camelCase and PascalCase for parameters. This will also reduce maintanance cost in the future.

### Description of how you validated changes

Added a unit test.

### Checklist
- [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
tmokmss committed Jul 15, 2024
1 parent 31b9e03 commit 5d6ace8
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CrossRegionAwsSdkSingletonFunction } from '../../../custom-resource-han
*/
export interface CallAwsServiceCrossRegionProps extends sfn.TaskStateBaseProps {
/**
* The AWS service to call in AWS SDK for JavaScript v3 style.
* The AWS service to call in AWS SDK for JavaScript v3 format.
*
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/
* @example 's3'
Expand All @@ -26,9 +26,7 @@ export interface CallAwsServiceCrossRegionProps extends sfn.TaskStateBaseProps {
readonly action: string;

/**
* Parameters for the API action call.
*
* Use PascalCase for the parameter names.
* Parameters for the API action call in AWS SDK for JavaScript v3 format.
*
* @default - no parameters
*/
Expand Down Expand Up @@ -112,12 +110,6 @@ export class CallAwsServiceCrossRegion extends sfn.TaskStateBase {
if (!Token.isUnresolved(props.action) && !props.action.startsWith(props.action[0]?.toLowerCase())) {
throw new Error(`action must be camelCase, got: ${props.action}`);
}
if (props.parameters) {
const invalidKeys = Object.keys(props.parameters).filter((key) => !key.startsWith(key[0]?.toUpperCase()));
if (invalidKeys.length) {
throw new Error(`parameter names must be PascalCase, got: ${invalidKeys.join(', ')}`);
}
}

// props.service expects a service name in the AWS SDK for JavaScript v3 format.
// In some services, this format differs from the one used in IAM.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,40 @@ test('with custom IAM action', () => {
});
});

test('parameters with camelCase', () => {
// WHEN
const task = new tasks.CallAwsServiceCrossRegion(stack, 'GetRestApi', {
service: 'api-gateway',
action: 'getRestApi',
parameters: {
restApiId: 'id',
},
region: 'us-east-1',
iamResources: ['*'],
retryOnServiceExceptions: false,
});

// THEN
expect(stack.resolve(task.toStateJson())).toEqual({
Type: 'Task',
Resource: {
'Fn::GetAtt': [
'CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F',
'Arn',
],
},
End: true,
Parameters: {
action: 'getRestApi',
region: 'us-east-1',
service: 'api-gateway',
parameters: {
restApiId: 'id',
},
},
});
});

test('throws with invalid integration pattern', () => {
expect(() => new tasks.CallAwsServiceCrossRegion(stack, 'GetObject', {
integrationPattern: sfn.IntegrationPattern.RUN_JOB,
Expand Down Expand Up @@ -189,19 +223,6 @@ test('throws if action is not camelCase', () => {
})).toThrow(/action must be camelCase, got: GetObject/);
});

test('throws if parameters has keys as not PascalCase', () => {
expect(() => new tasks.CallAwsServiceCrossRegion(stack, 'GetObject', {
service: 's3',
action: 'getObject',
parameters: {
bucket: 'my-bucket',
key: sfn.JsonPath.stringAt('$.key'),
},
region: 'us-east-1',
iamResources: ['*'],
})).toThrow(/parameter names must be PascalCase, got: bucket, key/);
});

test('can pass additional IAM statements', () => {
// WHEN
const task = new tasks.CallAwsServiceCrossRegion(stack, 'DetectLabels', {
Expand Down

0 comments on commit 5d6ace8

Please sign in to comment.