-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stepfunctions-tasks): Support calling ApiGateway REST and HTTP A…
…PIs (#13033) feat(stepfunctions-tasks): Support calling APIGW REST and HTTP APIs Taking ownership of the original PR #11565 by @Sumeet-Badyal API as per documentation here: https://docs.aws.amazon.com/step-functions/latest/dg/connect-api-gateway.html https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html closes #11566 closes #11565 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
1 parent
78b265c
commit cc608d0
Showing
14 changed files
with
1,359 additions
and
0 deletions.
There are no files selected for viewing
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
79 changes: 79 additions & 0 deletions
79
packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/base-types.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,79 @@ | ||
import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
|
||
/** Http Methods that API Gateway supports */ | ||
export enum HttpMethod { | ||
/** Retreive data from a server at the specified resource */ | ||
GET = 'GET', | ||
|
||
/** Send data to the API endpoint to create or udpate a resource */ | ||
POST = 'POST', | ||
|
||
/** Send data to the API endpoint to update or create a resource */ | ||
PUT = 'PUT', | ||
|
||
/** Delete the resource at the specified endpoint */ | ||
DELETE = 'DELETE', | ||
|
||
/** Apply partial modifications to the resource */ | ||
PATCH = 'PATCH', | ||
|
||
/** Retreive data from a server at the specified resource without the response body */ | ||
HEAD = 'HEAD', | ||
|
||
/** Return data describing what other methods and operations the server supports */ | ||
OPTIONS = 'OPTIONS' | ||
} | ||
|
||
/** | ||
* The authentication method used to call the endpoint | ||
*/ | ||
export enum AuthType { | ||
/** Call the API direclty with no authorization method */ | ||
NO_AUTH = 'NO_AUTH', | ||
|
||
/** Use the IAM role associated with the current state machine for authorization */ | ||
IAM_ROLE = 'IAM_ROLE', | ||
|
||
/** Use the resource policy of the API for authorization */ | ||
RESOURCE_POLICY = 'RESOURCE_POLICY', | ||
} | ||
|
||
/** | ||
* Base CallApiGatewayEdnpoint Task Props | ||
*/ | ||
export interface CallApiGatewayEndpointBaseProps extends sfn.TaskStateBaseProps { | ||
/** | ||
* Http method for the API | ||
*/ | ||
readonly method: HttpMethod; | ||
|
||
/** | ||
* HTTP request information that does not relate to contents of the request | ||
* @default - No headers | ||
*/ | ||
readonly headers?: sfn.TaskInput; | ||
|
||
/** | ||
* Path parameters appended after API endpoint | ||
* @default - No path | ||
*/ | ||
readonly apiPath?: string; | ||
|
||
/** | ||
* Query strings attatched to end of request | ||
* @default - No query parameters | ||
*/ | ||
readonly queryParameters?: sfn.TaskInput; | ||
|
||
/** | ||
* HTTP Request body | ||
* @default - No request body | ||
*/ | ||
readonly requestBody?: sfn.TaskInput; | ||
|
||
/** | ||
* Authentication methods | ||
* @default AuthType.NO_AUTH | ||
*/ | ||
readonly authType?: AuthType; | ||
} |
69 changes: 69 additions & 0 deletions
69
packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/base.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,69 @@ | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
import { Construct } from 'constructs'; | ||
import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; | ||
import { AuthType, CallApiGatewayEndpointBaseProps } from './base-types'; | ||
|
||
/** | ||
* Base CallApiGatewayEndpoint Task | ||
* @internal | ||
*/ | ||
export abstract class CallApiGatewayEndpointBase extends sfn.TaskStateBase { | ||
private static readonly SUPPORTED_INTEGRATION_PATTERNS: sfn.IntegrationPattern[] = [ | ||
sfn.IntegrationPattern.REQUEST_RESPONSE, | ||
sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, | ||
]; | ||
|
||
private readonly baseProps: CallApiGatewayEndpointBaseProps; | ||
private readonly integrationPattern: sfn.IntegrationPattern; | ||
|
||
protected abstract readonly apiEndpoint: string; | ||
protected abstract readonly arnForExecuteApi: string; | ||
protected abstract readonly stageName?: string; | ||
|
||
constructor(scope: Construct, id: string, props: CallApiGatewayEndpointBaseProps) { | ||
super(scope, id, props); | ||
|
||
this.baseProps = props; | ||
this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE; | ||
validatePatternSupported(this.integrationPattern, CallApiGatewayEndpointBase.SUPPORTED_INTEGRATION_PATTERNS); | ||
|
||
if (this.integrationPattern === sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN) { | ||
if (!sfn.FieldUtils.containsTaskToken(this.baseProps.headers)) { | ||
throw new Error('Task Token is required in `headers` for WAIT_FOR_TASK_TOKEN pattern. Use JsonPath.taskToken to set the token.'); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
protected _renderTask() { | ||
return { | ||
Resource: integrationResourceArn('apigateway', 'invoke', this.integrationPattern), | ||
Parameters: sfn.FieldUtils.renderObject({ | ||
ApiEndpoint: this.apiEndpoint, | ||
Method: this.baseProps.method, | ||
Headers: this.baseProps.headers?.value, | ||
Stage: this.stageName, | ||
Path: this.baseProps.apiPath, | ||
QueryParameters: this.baseProps.queryParameters?.value, | ||
RequestBody: this.baseProps.requestBody?.value, | ||
AuthType: this.baseProps.authType ? this.baseProps.authType : 'NO_AUTH', | ||
}), | ||
}; | ||
} | ||
|
||
protected createPolicyStatements(): iam.PolicyStatement[] { | ||
if (this.baseProps.authType === AuthType.NO_AUTH) { | ||
return []; | ||
} | ||
|
||
return [ | ||
new iam.PolicyStatement({ | ||
resources: [this.arnForExecuteApi], | ||
actions: ['execute-api:Invoke'], | ||
}), | ||
]; | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-http-api.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,62 @@ | ||
import * as apigatewayv2 from '@aws-cdk/aws-apigatewayv2'; | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { CallApiGatewayEndpointBase } from './base'; | ||
import { CallApiGatewayEndpointBaseProps } from './base-types'; | ||
|
||
/** | ||
* Properties for calling an HTTP API Endpoint | ||
*/ | ||
export interface CallApiGatewayHttpApiEndpointProps extends CallApiGatewayEndpointBaseProps { | ||
/** | ||
* API to call | ||
*/ | ||
readonly api: apigatewayv2.IHttpApi; | ||
|
||
/** | ||
* Name of the stage where the API is deployed to in API Gateway | ||
* @default '$default' | ||
*/ | ||
readonly stageName?: string; | ||
} | ||
|
||
/** | ||
* Call HTTP API endpoint as a Task | ||
* | ||
* @see https://docs.aws.amazon.com/step-functions/latest/dg/connect-api-gateway.html | ||
*/ | ||
export class CallApiGatewayHttpApiEndpoint extends CallApiGatewayEndpointBase { | ||
protected readonly taskMetrics?: sfn.TaskMetricsConfig | undefined; | ||
protected readonly taskPolicies?: iam.PolicyStatement[] | undefined; | ||
|
||
protected readonly apiEndpoint: string; | ||
protected readonly arnForExecuteApi: string; | ||
protected readonly stageName?: string; | ||
|
||
constructor(scope: Construct, id: string, private readonly props: CallApiGatewayHttpApiEndpointProps) { | ||
super(scope, id, props); | ||
|
||
this.apiEndpoint = this.getApiEndpoint(); | ||
this.arnForExecuteApi = this.getArnForExecuteApi(); | ||
|
||
this.taskPolicies = this.createPolicyStatements(); | ||
} | ||
|
||
private getApiEndpoint(): string { | ||
const apiStack = cdk.Stack.of(this.props.api); | ||
return `${this.props.api.apiId}.execute-api.${apiStack.region}.${apiStack.urlSuffix}`; | ||
} | ||
|
||
private getArnForExecuteApi(): string { | ||
const { api, stageName, method, apiPath } = this.props; | ||
|
||
return cdk.Stack.of(api).formatArn({ | ||
service: 'execute-api', | ||
resource: api.apiId, | ||
sep: '/', | ||
resourceName: `${stageName}/${method}${apiPath}`, | ||
}); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-rest-api.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,51 @@ | ||
import * as apigateway from '@aws-cdk/aws-apigateway'; | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { CallApiGatewayEndpointBase } from './base'; | ||
import { CallApiGatewayEndpointBaseProps } from './base-types'; | ||
|
||
/** | ||
* Properties for calling an REST API Endpoint | ||
*/ | ||
export interface CallApiGatewayRestApiEndpointProps extends CallApiGatewayEndpointBaseProps { | ||
/** | ||
* API to call | ||
*/ | ||
readonly api: apigateway.IRestApi; | ||
|
||
/** | ||
* Name of the stage where the API is deployed to in API Gateway | ||
*/ | ||
readonly stageName: string; | ||
} | ||
|
||
/** | ||
* Call REST API endpoint as a Task | ||
* | ||
* @see https://docs.aws.amazon.com/step-functions/latest/dg/connect-api-gateway.html | ||
*/ | ||
export class CallApiGatewayRestApiEndpoint extends CallApiGatewayEndpointBase { | ||
protected readonly taskMetrics?: sfn.TaskMetricsConfig | undefined; | ||
protected readonly taskPolicies?: iam.PolicyStatement[] | undefined; | ||
|
||
protected readonly apiEndpoint: string; | ||
protected readonly arnForExecuteApi: string; | ||
protected readonly stageName?: string; | ||
|
||
constructor(scope: Construct, id: string, private readonly props: CallApiGatewayRestApiEndpointProps) { | ||
super(scope, id, props); | ||
|
||
this.apiEndpoint = this.getApiEndpoint(); | ||
this.arnForExecuteApi = props.api.arnForExecuteApi(props.method, props.apiPath, props.stageName); | ||
this.stageName = props.stageName; | ||
|
||
this.taskPolicies = this.createPolicyStatements(); | ||
} | ||
|
||
private getApiEndpoint(): string { | ||
const apiStack = cdk.Stack.of(this.props.api); | ||
return `${this.props.api.restApiId}.execute-api.${apiStack.region}.${apiStack.urlSuffix}`; | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/index.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,3 @@ | ||
export * from './base-types'; | ||
export * from './call-rest-api'; | ||
export * from './call-http-api'; |
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
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
Oops, something went wrong.