From 11630714c412e0d44999c039e0b210bd8c516042 Mon Sep 17 00:00:00 2001 From: SankyRed Date: Tue, 3 Oct 2023 10:21:20 -0500 Subject: [PATCH] Fix to use the custom state name if provided else default to the construct id --- .../aws-stepfunctions/lib/states/choice.ts | 2 +- .../lib/states/custom-state.ts | 9 ++- .../aws-stepfunctions/lib/states/fail.ts | 2 +- .../aws-stepfunctions/lib/states/map.ts | 2 +- .../aws-stepfunctions/lib/states/parallel.ts | 2 +- .../aws-stepfunctions/lib/states/pass.ts | 2 +- .../aws-stepfunctions/lib/states/state.ts | 4 +- .../aws-stepfunctions/lib/states/succeed.ts | 2 +- .../aws-stepfunctions/lib/states/task-base.ts | 2 +- .../aws-stepfunctions/lib/states/task.ts | 2 +- .../aws-stepfunctions/lib/states/wait.ts | 2 +- .../test/custom-state.test.ts | 8 ++- .../aws-stepfunctions/test/fail.test.ts | 62 ++++++++++++++++++- .../aws-stepfunctions/test/map.test.ts | 5 +- .../aws-stepfunctions/test/parallel.test.ts | 4 +- .../test/state-machine-resources.test.ts | 1 + .../aws-stepfunctions/test/wait.test.ts | 21 +++++++ 17 files changed, 111 insertions(+), 21 deletions(-) diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts index 1b35552b08a0b..e524b35cdb684 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts @@ -54,7 +54,7 @@ export class Choice extends State { public readonly endStates: INextable[] = []; constructor(scope: Construct, id: string, props: ChoiceProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); } /** 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 3bf14fc249b80..a663c2a2b8d5e 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 @@ -7,6 +7,13 @@ import { IChainable, INextable } from '../types'; * Properties for defining a custom state definition */ export interface CustomStateProps { + /** + * Optional name for this state + * + * @default - The construct ID will be used as state name + */ + readonly stateName: string; + /** * Amazon States Language (JSON-based) definition of the state * @@ -28,7 +35,7 @@ export class CustomState extends State implements IChainable, INextable { private readonly stateJson: { [key: string]: any}; constructor(scope: Construct, id: string, props: CustomStateProps) { - super(scope, id, {}); + super(scope, props.stateName? props.stateName: id, {}); this.endStates = [this]; this.stateJson = props.stateJson; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/fail.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/fail.ts index efe067c8ba3a5..7517f241d6443 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/fail.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/fail.ts @@ -64,7 +64,7 @@ export class Fail extends State { private readonly causePath?: string; constructor(scope: Construct, id: string, props: FailProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.error = props.error; this.errorPath = props.errorPath; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts index b42de5fafee4c..b4a8af86e1876 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts @@ -124,7 +124,7 @@ export class Map extends State implements INextable { private readonly itemsPath?: string; constructor(scope: Construct, id: string, props: MapProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.endStates = [this]; this.maxConcurrency = props.maxConcurrency; this.itemsPath = props.itemsPath; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/parallel.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/parallel.ts index 1199f3d84e8b7..24fdf2a02cd7d 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/parallel.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/parallel.ts @@ -81,7 +81,7 @@ export class Parallel extends State implements INextable { private readonly _branches: IChainable[] = []; constructor(scope: Construct, id: string, props: ParallelProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.endStates = [this]; } diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/pass.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/pass.ts index 2a2a19db7d47c..26b8b640b003a 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/pass.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/pass.ts @@ -131,7 +131,7 @@ export class Pass extends State implements INextable { private readonly result?: Result; constructor(scope: Construct, id: string, props: PassProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.result = props.result; this.endStates = [this]; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts index ecb8dd52ec7c3..eac5f343b541e 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts @@ -12,7 +12,7 @@ export interface StateProps { /** * Optional name for this state * - * @default LogicalResourceId + * @default - The construct ID will be used as state name */ readonly stateName?: string; @@ -198,7 +198,7 @@ export abstract class State extends Construct implements IChainable { private readonly incomingStates: State[] = []; constructor(scope: Construct, id: string, props: StateProps) { - super(scope, id); + super(scope, props.stateName? props.stateName: id); this.startState = this; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/succeed.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/succeed.ts index 80eab204832c4..6ed2d1a7d1899 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/succeed.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/succeed.ts @@ -52,7 +52,7 @@ export class Succeed extends State { public readonly endStates: INextable[] = []; constructor(scope: Construct, id: string, props: SucceedProps = {}) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); } /** diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task-base.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task-base.ts index 37db0828ab8d0..add498ad7bba7 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task-base.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task-base.ts @@ -157,7 +157,7 @@ export abstract class TaskStateBase extends State implements INextable { private readonly credentials?: Credentials; constructor(scope: Construct, id: string, props: TaskStateBaseProps) { - super(scope, id, props); + super(scope, props.stateName ? props.stateName: id, props); this.endStates = [this]; this.timeout = props.timeout; diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts index 0e43839b301eb..3ceef616f6a5c 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts @@ -117,7 +117,7 @@ export class Task extends State implements INextable { private readonly taskProps: StepFunctionsTaskConfig; constructor(scope: Construct, id: string, props: TaskProps) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.timeout = props.timeout; const taskProps = props.task.bind(this); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/wait.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/wait.ts index d81042f1e2909..a305601300e51 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/wait.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/wait.ts @@ -81,7 +81,7 @@ export class Wait extends State implements INextable { private readonly time: WaitTime; constructor(scope: Construct, id: string, props: WaitProps) { - super(scope, id, props); + super(scope, props.stateName? props.stateName: id, props); this.time = props.time; this.endStates = [this]; 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 daa069b15e37d..f5b2a03e58d92 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 @@ -27,6 +27,7 @@ describe('Custom State', () => { test('maintains the state Json provided during construction', () => { // WHEN const customState = new sfn.CustomState(stack, 'Custom', { + stateName: 'my-custom-state-name', stateJson, }); @@ -40,15 +41,16 @@ describe('Custom State', () => { test('can add a next state to the chain', () => { // WHEN const definition = new sfn.CustomState(stack, 'Custom', { + stateName: 'my-custom-state-name', stateJson, }).next(new sfn.Pass(stack, 'MyPass')); // THEN expect(render(stack, definition)).toStrictEqual( { - StartAt: 'Custom', + StartAt: 'my-custom-state-name', States: { - Custom: { + 'my-custom-state-name': { Next: 'MyPass', Type: 'Task', Resource: 'arn:aws:states:::dynamodb:putItem', @@ -62,7 +64,7 @@ describe('Custom State', () => { }, ResultPath: null, }, - MyPass: { + 'MyPass': { Type: 'Pass', End: true, }, diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/fail.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/fail.test.ts index dcb38e3c4976c..e1dc0ee2ac006 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/fail.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/fail.test.ts @@ -1,10 +1,68 @@ import * as cdk from '../../core'; import * as stepfunctions from '../lib'; +import { render } from './private/render-util'; describe('Fail State', () => { - test('Props are optional', () => { - const stack = new cdk.Stack(); + let stack: cdk.Stack; + let stateJson: any; + + beforeEach(() => { + // GIVEN + stack = new cdk.Stack(); + stateJson = { + Type: 'Task', + Resource: 'arn:aws:states:::dynamodb:putItem', + Parameters: { + TableName: 'MyTable', + Item: { + id: { + S: 'MyEntry', + }, + }, + }, + ResultPath: null, + }; + }); + test('Props are optional', () => { new stepfunctions.Fail(stack, 'Fail'); }); + + test('can add a fail state to the chain with custom state name', () => { + // WHEN + const definition = new stepfunctions.CustomState(stack, 'Custom1', { + stateName: 'my-custom-state-name', + stateJson, + }).next(new stepfunctions.Pass(stack, 'MyPass')) + .next(new stepfunctions.Fail(stack, 'Fail', { + stateName: 'my-fail-state', + comment: 'failing state', + errorPath: stepfunctions.JsonPath.stringAt('$.error'), + causePath: stepfunctions.JsonPath.stringAt('$.cause'), + })); + + // THEN + expect(render(stack, definition)).toStrictEqual( + { + StartAt: 'my-custom-state-name', + States: { + 'my-custom-state-name': { + Next: 'MyPass', + Type: 'Task', + ...stateJson, + }, + 'MyPass': { + Type: 'Pass', + Next: 'my-fail-state', + }, + 'my-fail-state': { + Comment: 'failing state', + Type: 'Fail', + CausePath: '$.cause', + ErrorPath: '$.error', + }, + }, + }, + ); + }); }); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts index 9ea5dd0ee4f64..44a4417bdcd9d 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts @@ -8,6 +8,7 @@ describe('Map State', () => { // WHEN const map = new stepfunctions.Map(stack, 'Map State', { + stateName: 'My-Map-State', maxConcurrency: 1, itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), parameters: { @@ -19,9 +20,9 @@ describe('Map State', () => { // THEN expect(render(map)).toStrictEqual({ - StartAt: 'Map State', + StartAt: 'My-Map-State', States: { - 'Map State': { + 'My-Map-State': { Type: 'Map', End: true, Parameters: { diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/parallel.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/parallel.test.ts index 5744cb50ac595..2b8eb8b80dda6 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/parallel.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/parallel.test.ts @@ -8,7 +8,7 @@ describe('Parallel State', () => { // WHEN const parallel = new stepfunctions.Parallel(stack, 'Parallel State'); - parallel.branch(new stepfunctions.Pass(stack, 'Branch 1')); + parallel.branch(new stepfunctions.Pass(stack, 'Branch 1', { stateName: 'first-pass-state' })); parallel.branch(new stepfunctions.Pass(stack, 'Branch 2')); // THEN @@ -19,7 +19,7 @@ describe('Parallel State', () => { Type: 'Parallel', End: true, Branches: [ - { StartAt: 'Branch 1', States: { 'Branch 1': { Type: 'Pass', End: true } } }, + { StartAt: 'first-pass-state', States: { 'first-pass-state': { Type: 'Pass', End: true } } }, { StartAt: 'Branch 2', States: { 'Branch 2': { Type: 'Pass', End: true } } }, ], }, diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine-resources.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine-resources.test.ts index d9ebf9219f9a3..69d0a24e1a5d0 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine-resources.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/state-machine-resources.test.ts @@ -642,6 +642,7 @@ describe('State Machine Resources', () => { // GIVEN const stack = new cdk.Stack(); const task = new stepfunctions.Pass(stack, 'Pass', { + stateName: 'my-pass-state', inputPath: '$', outputPath: '$.state', parameters: { diff --git a/packages/aws-cdk-lib/aws-stepfunctions/test/wait.test.ts b/packages/aws-cdk-lib/aws-stepfunctions/test/wait.test.ts index cb24ed19c0037..599baeaf44cf3 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/wait.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/wait.test.ts @@ -75,4 +75,25 @@ describe('Wait State', () => { }); }); + test('supports adding a custom state name', () => { + // GIVEN + const stack = new cdk.Stack(); + const waitTime = new Wait(stack, 'myWaitState', { + stateName: 'wait-state-custom-name', + time: WaitTime.duration(cdk.Duration.seconds(30)), + }); + + // THEN + expect(render(stack, waitTime)).toEqual({ + StartAt: 'wait-state-custom-name', + States: { + 'wait-state-custom-name': { + Seconds: 30, + Type: 'Wait', + End: true, + }, + }, + }); + }); + }); \ No newline at end of file