From 9d987970165f8eabef3d095d43ae65a37d3b06db Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 6 Jan 2024 20:40:56 +0900 Subject: [PATCH 1/3] fix: add retry --- ...epfunctions-custom-state-integ.assets.json | 6 +-- ...functions-custom-state-integ.template.json | 4 +- .../integ.custom-state.js.snapshot/cdk.out | 2 +- .../integ.custom-state.js.snapshot/integ.json | 2 +- .../manifest.json | 5 ++- .../integ.custom-state.js.snapshot/tree.json | 38 +++++++++------- .../test/integ.custom-state.ts | 5 +++ .../aws-cdk-lib/aws-stepfunctions/README.md | 7 +++ .../lib/states/custom-state.ts | 13 +++++- .../test/custom-state.test.ts | 43 +++++++++++++++++++ 10 files changed, 100 insertions(+), 25 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.assets.json index 852466be8943d..673c6aba98278 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.assets.json @@ -1,7 +1,7 @@ { - "version": "30.0.0", + "version": "36.0.0", "files": { - "88187762ebb3676ec68ded03ce92c045563205c6497ae5a104f13a32dbf4ef43": { + "009040dbb1873c31d45ee6be45381ed16bbf81f9a642799664531ba2f3c56832": { "source": { "path": "aws-stepfunctions-custom-state-integ.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "88187762ebb3676ec68ded03ce92c045563205c6497ae5a104f13a32dbf4ef43.json", + "objectKey": "009040dbb1873c31d45ee6be45381ed16bbf81f9a642799664531ba2f3c56832.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.template.json index b090502f0294b..be6ebd9dd8583 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/aws-stepfunctions-custom-state-integ.template.json @@ -20,13 +20,13 @@ "StateMachine2E01A3A5": { "Type": "AWS::StepFunctions::StateMachine", "Properties": { + "DefinitionString": "{\"StartAt\":\"my custom task\",\"States\":{\"my custom task\":{\"Next\":\"final step\",\"Type\":\"Task\",\"Resource\":\"arn:aws:states:::dynamodb:putItem\",\"Parameters\":{\"TableName\":\"my-cool-table\",\"Item\":{\"id\":{\"S\":\"my-entry\"}}},\"ResultPath\":null,\"Retry\":[{\"ErrorEquals\":[\"States.ALL\"],\"IntervalSeconds\":10,\"MaxAttempts\":5}],\"Catch\":[{\"ErrorEquals\":[\"States.ALL\"],\"Next\":\"failed\"}]},\"final step\":{\"Type\":\"Pass\",\"End\":true},\"failed\":{\"Type\":\"Fail\",\"Error\":\"DidNotWork\",\"Cause\":\"We got stuck\"}},\"TimeoutSeconds\":30}", "RoleArn": { "Fn::GetAtt": [ "StateMachineRoleB840431D", "Arn" ] - }, - "DefinitionString": "{\"StartAt\":\"my custom task\",\"States\":{\"my custom task\":{\"Next\":\"final step\",\"Type\":\"Task\",\"Resource\":\"arn:aws:states:::dynamodb:putItem\",\"Parameters\":{\"TableName\":\"my-cool-table\",\"Item\":{\"id\":{\"S\":\"my-entry\"}}},\"ResultPath\":null,\"Catch\":[{\"ErrorEquals\":[\"States.ALL\"],\"Next\":\"failed\"}]},\"final step\":{\"Type\":\"Pass\",\"End\":true},\"failed\":{\"Type\":\"Fail\",\"Error\":\"DidNotWork\",\"Cause\":\"We got stuck\"}},\"TimeoutSeconds\":30}" + } }, "DependsOn": [ "StateMachineRoleB840431D" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/cdk.out index ae4b03c54e770..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.0.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/integ.json index 624779da650bd..3c6ca76f840ab 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "36.0.0", "testCases": { "integ.custom-state": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/manifest.json index 1607ee7800b57..0bd5238d6c5f6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "30.0.0", + "version": "36.0.0", "artifacts": { "aws-stepfunctions-custom-state-integ.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-stepfunctions-custom-state-integ.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/88187762ebb3676ec68ded03ce92c045563205c6497ae5a104f13a32dbf4ef43.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/009040dbb1873c31d45ee6be45381ed16bbf81f9a642799664531ba2f3c56832.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/tree.json index 6544935df1c46..c33567eaa9d4c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.js.snapshot/tree.json @@ -12,7 +12,15 @@ "id": "final step", "path": "aws-stepfunctions-custom-state-integ/final step", "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.Pass", + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "failed": { + "id": "failed", + "path": "aws-stepfunctions-custom-state-integ/failed", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Fail", "version": "0.0.0" } }, @@ -20,7 +28,7 @@ "id": "my custom task", "path": "aws-stepfunctions-custom-state-integ/my custom task", "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.CustomState", + "fqn": "aws-cdk-lib.aws_stepfunctions.CustomState", "version": "0.0.0" } }, @@ -36,7 +44,7 @@ "id": "ImportRole", "path": "aws-stepfunctions-custom-state-integ/StateMachine/Role/ImportRole", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", + "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" } }, @@ -61,13 +69,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -77,23 +85,23 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"my custom task\",\"States\":{\"my custom task\":{\"Next\":\"final step\",\"Type\":\"Task\",\"Resource\":\"arn:aws:states:::dynamodb:putItem\",\"Parameters\":{\"TableName\":\"my-cool-table\",\"Item\":{\"id\":{\"S\":\"my-entry\"}}},\"ResultPath\":null,\"Retry\":[{\"ErrorEquals\":[\"States.ALL\"],\"IntervalSeconds\":10,\"MaxAttempts\":5}],\"Catch\":[{\"ErrorEquals\":[\"States.ALL\"],\"Next\":\"failed\"}]},\"final step\":{\"Type\":\"Pass\",\"End\":true},\"failed\":{\"Type\":\"Fail\",\"Error\":\"DidNotWork\",\"Cause\":\"We got stuck\"}},\"TimeoutSeconds\":30}", "roleArn": { "Fn::GetAtt": [ "StateMachineRoleB840431D", "Arn" ] - }, - "definitionString": "{\"StartAt\":\"my custom task\",\"States\":{\"my custom task\":{\"Next\":\"final step\",\"Type\":\"Task\",\"Resource\":\"arn:aws:states:::dynamodb:putItem\",\"Parameters\":{\"TableName\":\"my-cool-table\",\"Item\":{\"id\":{\"S\":\"my-entry\"}}},\"ResultPath\":null},\"final step\":{\"Type\":\"Pass\",\"End\":true}},\"TimeoutSeconds\":30}" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.CfnStateMachine", + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-stepfunctions.StateMachine", + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", "version": "0.0.0" } }, @@ -101,7 +109,7 @@ "id": "StateMachineARN", "path": "aws-stepfunctions-custom-state-integ/StateMachineARN", "constructInfo": { - "fqn": "@aws-cdk/core.CfnOutput", + "fqn": "aws-cdk-lib.CfnOutput", "version": "0.0.0" } }, @@ -109,7 +117,7 @@ "id": "BootstrapVersion", "path": "aws-stepfunctions-custom-state-integ/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", + "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" } }, @@ -117,13 +125,13 @@ "id": "CheckBootstrapVersion", "path": "aws-stepfunctions-custom-state-integ/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", + "fqn": "aws-cdk-lib.Stack", "version": "0.0.0" } }, @@ -132,12 +140,12 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.237" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.App", + "fqn": "aws-cdk-lib.App", "version": "0.0.0" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts index 5d28b12436975..b2f1037e57259 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts @@ -35,6 +35,11 @@ const custom = new sfn.CustomState(stack, 'my custom task', { }); custom.addCatch(failure); +custom.addRetry({ + errors: ['States.ALL'], + interval: cdk.Duration.seconds(10), + maxAttempts: 5, +}); const chain = sfn.Chain.start(custom).next(finalStatus); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/README.md b/packages/aws-cdk-lib/aws-stepfunctions/README.md index aef1e2ffaa631..8d21893b5ac5a 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions/README.md @@ -602,6 +602,13 @@ const custom = new sfn.CustomState(this, 'my custom task', { const errorHandler = new sfn.Pass(this, 'handle failure'); custom.addCatch(errorHandler); +// retry the task if something goes wrong +custom.addRetry({ + errors: ['States.ALL'], + interval: cdk.Duration.seconds(10), + maxAttempts: 5, +}); + const chain = sfn.Chain.start(custom) .next(finalStatus); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/custom-state.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/custom-state.ts index db66a5a8de17f..fd247118c6347 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/custom-state.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/custom-state.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import { State } from './state'; import { Chain } from '..'; -import { CatchProps, IChainable, INextable } from '../types'; +import { CatchProps, IChainable, INextable, RetryProps } from '../types'; /** * Properties for defining a custom state definition @@ -34,6 +34,17 @@ export class CustomState extends State implements IChainable, INextable { this.stateJson = props.stateJson; } + /** + * Add retry configuration for this state + * + * This controls if and how the execution will be retried if a particular + * error occurs. + */ + public addRetry(props: RetryProps = {}): CustomState { + super._addRetry(props); + return this; + } + /** * Add a recovery handler for this state * diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts index 766b8ac659abe..41d19173de780 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts @@ -120,4 +120,47 @@ describe('Custom State', () => { }, ); }); + + test('can add a retry state', () => { + // GIVEN + const custom = new sfn.CustomState(stack, 'Custom', { + stateJson, + }); + const chain = sfn.Chain.start(custom); + + // WHEN + custom.addRetry({ + errors: ['States.ALL'], + interval: cdk.Duration.seconds(10), + maxAttempts: 5, + }); + + // THEN + expect(render(stack, chain)).toStrictEqual( + { + StartAt: 'Custom', + States: { + Custom: { + Type: 'Task', + Resource: 'arn:aws:states:::dynamodb:putItem', + Parameters: { + TableName: 'MyTable', + Item: { + id: { + S: 'MyEntry', + }, + }, + }, + ResultPath: null, + Retry: [{ + ErrorEquals: ['States.ALL'], + IntervalSeconds: 10, + MaxAttempts: 5, + }], + End: true, + }, + }, + }, + ); + }); }); \ No newline at end of file From e5273e37bb096be66136d8de515970f6f9647904 Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 6 Jan 2024 21:30:09 +0900 Subject: [PATCH 2/3] chore: use Errors class --- .../test/aws-stepfunctions/test/integ.custom-state.ts | 2 +- packages/aws-cdk-lib/aws-stepfunctions/README.md | 2 +- .../aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts index b2f1037e57259..0d30c3d1b771b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.custom-state.ts @@ -36,7 +36,7 @@ const custom = new sfn.CustomState(stack, 'my custom task', { custom.addCatch(failure); custom.addRetry({ - errors: ['States.ALL'], + errors: [sfn.Errors.ALL], interval: cdk.Duration.seconds(10), maxAttempts: 5, }); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/README.md b/packages/aws-cdk-lib/aws-stepfunctions/README.md index 8d21893b5ac5a..e6a1e4f8c4bdd 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions/README.md @@ -604,7 +604,7 @@ custom.addCatch(errorHandler); // retry the task if something goes wrong custom.addRetry({ - errors: ['States.ALL'], + errors: [sfn.Errors.ALL], interval: cdk.Duration.seconds(10), maxAttempts: 5, }); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts index 41d19173de780..7935f911e9977 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts @@ -130,7 +130,7 @@ describe('Custom State', () => { // WHEN custom.addRetry({ - errors: ['States.ALL'], + errors: [sfn.Errors.ALL], interval: cdk.Duration.seconds(10), maxAttempts: 5, }); From 16e5d909940d7ec5e10e5b3078efe52ffb1a8732 Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 6 Jan 2024 21:35:37 +0900 Subject: [PATCH 3/3] fix: readme --- packages/aws-cdk-lib/aws-stepfunctions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-stepfunctions/README.md b/packages/aws-cdk-lib/aws-stepfunctions/README.md index e6a1e4f8c4bdd..6ddae341b2506 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions/README.md @@ -605,7 +605,7 @@ custom.addCatch(errorHandler); // retry the task if something goes wrong custom.addRetry({ errors: [sfn.Errors.ALL], - interval: cdk.Duration.seconds(10), + interval: Duration.seconds(10), maxAttempts: 5, });