-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
10d5a9f
commit bc37725
Showing
3 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/http/invoke.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import { Construct } from 'constructs'; | ||
import * as iam from '../../../aws-iam'; | ||
import * as sfn from '../../../aws-stepfunctions'; | ||
import { integrationResourceArn } from '../private/task-utils'; | ||
|
||
export enum URLEncodingArrayFormat { | ||
/** | ||
* Encode arrays using brackets. For example, {"array": ["a","b","c"]} encodes to "array[]=a&array[]=b&array[]=c" | ||
*/ | ||
BRACKETS = 'BRACKETS', | ||
/** | ||
* Encode arrays using commas. For example, {"array": ["a","b","c"]} encodes to "array=a,b,c,d" | ||
*/ | ||
COMMAS = 'COMMAS', | ||
/** | ||
* Encode arrays using the index value. For example, {"array": ["a","b","c"]} encodes to "array[0]=a&array[1]=b&array[2]=c" | ||
*/ | ||
INDICES = 'INDICES', | ||
/** | ||
* Repeat key for each item in the array. For example, {"array": ["a","b","c"]} encodes to "array[]=a&array[]=b&array[]=c" | ||
*/ | ||
REPEAT = 'REPEAT', | ||
} | ||
|
||
/** | ||
* Properties for calling an external HTTP endpoint with HttpInvoke. | ||
*/ | ||
export interface HttpInvokeProps extends sfn.TaskStateBaseProps { | ||
/** | ||
* The API apiEndpoint to call. | ||
*/ | ||
readonly apiEndpoint: string; | ||
|
||
/** | ||
* The HTTP method to use. | ||
* | ||
*/ | ||
readonly method: string; | ||
|
||
/** | ||
* The EventBridge Connection ARN to use for authentication. | ||
* | ||
*/ | ||
readonly connectionArn: string; | ||
|
||
/** | ||
* The body to send to the HTTP endpoint. | ||
* | ||
* @default - No body. | ||
*/ | ||
readonly body?: string; | ||
|
||
/** | ||
* The headers to send to the HTTP endpoint. | ||
* | ||
* @default - No headers. | ||
*/ | ||
readonly headers?: { [key: string]: string }; | ||
|
||
/** | ||
* The query string parameters to send to the HTTP endpoint. | ||
* | ||
* @default - No query string parameters. | ||
*/ | ||
readonly queryStringParameters?: { [key: string]: string }; | ||
|
||
/** | ||
* Whether to URL-encode the request body. | ||
* If set to true, also sets 'content-type' header to 'application/x-www-form-urlencoded' | ||
* | ||
* @default - No encoding. | ||
*/ | ||
readonly urlEncodeBody?: boolean; | ||
|
||
/** | ||
* The format of the array encoding if urlEncodeBody is set to true. | ||
* | ||
* @default - ArrayEncodingFormat.INDICES | ||
*/ | ||
readonly arrayEncodingFormat?: URLEncodingArrayFormat; | ||
} | ||
|
||
export class HttpInvoke extends sfn.TaskStateBase { | ||
protected readonly taskMetrics?: sfn.TaskMetricsConfig; | ||
protected readonly taskPolicies?: iam.PolicyStatement[]; | ||
|
||
constructor( | ||
scope: Construct, | ||
id: string, | ||
private readonly props: HttpInvokeProps, | ||
) { | ||
super(scope, id, props); | ||
|
||
this.taskPolicies = []; | ||
} | ||
|
||
/** | ||
* Provides the HTTP Invoke service integration task configuration. | ||
*/ | ||
/** | ||
* @internal | ||
*/ | ||
protected _renderTask(): any { | ||
return { | ||
Resource: integrationResourceArn('http', 'invoke'), | ||
Parameters: sfn.FieldUtils.renderObject({ | ||
Method: this.props.method, | ||
ApiEndpoint: this.props.apiEndpoint, | ||
Authentication: { | ||
ConnectionArn: this.props.connectionArn, | ||
}, | ||
RequestBody: this.props.body, | ||
Headers: this.props.headers, | ||
QueryParameters: this.props.queryStringParameters, | ||
Transform: | ||
this.props.urlEncodeBody != null | ||
? { | ||
RequestBodyEncoding: 'URL_ENCODED', | ||
RequestEncodingOptions: { | ||
ArrayFormat: | ||
this.props.arrayEncodingFormat ?? | ||
URLEncodingArrayFormat.INDICES, | ||
}, | ||
} | ||
: undefined, | ||
}), | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
packages/aws-cdk-lib/aws-stepfunctions-tasks/test/http/invoke.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import { Stack } from '../../../core'; | ||
import * as lib from '../../lib'; | ||
|
||
let stack: Stack; | ||
const connectionArn = | ||
'arn:aws:events:us-test-1:123456789012:connection/connectionName'; | ||
|
||
const expectTaskWithParameters = (task: lib.HttpInvoke, parameters: any) => { | ||
expect(stack.resolve(task.toStateJson())).toEqual({ | ||
Type: 'Task', | ||
Resource: { | ||
'Fn::Join': [ | ||
'', | ||
[ | ||
'arn:', | ||
{ | ||
Ref: 'AWS::Partition', | ||
}, | ||
':states:::http:invoke', | ||
], | ||
], | ||
}, | ||
End: true, | ||
Parameters: parameters, | ||
}); | ||
}; | ||
|
||
describe('AWS::StepFunctions::Tasks::HttpInvoke', () => { | ||
beforeEach(() => { | ||
stack = new Stack(); | ||
}); | ||
|
||
test('invoke with default props', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
connectionArn, | ||
method: 'POST', | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
}); | ||
}); | ||
|
||
test('invoke with request body', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
body: JSON.stringify({ foo: 'bar' }), | ||
connectionArn, | ||
method: 'POST', | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
RequestBody: JSON.stringify({ foo: 'bar' }), | ||
}); | ||
}); | ||
|
||
test('invoke with headers', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
connectionArn, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
method: 'POST', | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
Headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
}); | ||
|
||
test('invoke with query string parameters', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
connectionArn, | ||
method: 'POST', | ||
queryStringParameters: { | ||
foo: 'bar', | ||
}, | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
QueryParameters: { | ||
foo: 'bar', | ||
}, | ||
}); | ||
}); | ||
|
||
test('invoke with request body encoding and default arrayEncodingFormat', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
method: 'POST', | ||
connectionArn, | ||
urlEncodeBody: true, | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
Transform: { | ||
RequestBodyEncoding: 'URL_ENCODED', | ||
RequestEncodingOptions: { | ||
ArrayFormat: lib.URLEncodingArrayFormat.INDICES, | ||
}, | ||
}, | ||
}); | ||
}); | ||
|
||
test('invoke with request body encoding and arrayEncodingFormat', () => { | ||
const task = new lib.HttpInvoke(stack, 'Task', { | ||
apiEndpoint: 'https://api.example.com', | ||
arrayEncodingFormat: lib.URLEncodingArrayFormat.BRACKETS, | ||
connectionArn, | ||
method: 'POST', | ||
urlEncodeBody: true, | ||
}); | ||
|
||
expectTaskWithParameters(task, { | ||
ApiEndpoint: 'https://api.example.com', | ||
Authentication: { | ||
ConnectionArn: connectionArn, | ||
}, | ||
Method: 'POST', | ||
Transform: { | ||
RequestBodyEncoding: 'URL_ENCODED', | ||
RequestEncodingOptions: { | ||
ArrayFormat: lib.URLEncodingArrayFormat.BRACKETS, | ||
}, | ||
}, | ||
}); | ||
}); | ||
}); |