Skip to content

Commit 61be7a6

Browse files
authored
feat(stepfunctions): adding custom state name prop (#27306)
Closes #23532 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent beac675 commit 61be7a6

18 files changed

+168
-12
lines changed

packages/aws-cdk-lib/aws-stepfunctions/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ becomes new the new Data object. This behavior can be modified by supplying valu
124124

125125
These properties impact how each individual step interacts with the state machine data:
126126

127+
* `stateName`: the name of the state in the state machine definition. If not supplied, defaults to the construct id.
127128
* `inputPath`: the part of the data object that gets passed to the step (`itemsPath` for `Map` states)
128129
* `resultSelector`: the part of the step result that should be added to the state machine data
129130
* `resultPath`: where in the state machine data the step result should be inserted
@@ -285,6 +286,7 @@ and also injects a field called `otherData`.
285286

286287
```ts
287288
const pass = new sfn.Pass(this, 'Filter input and inject data', {
289+
stateName: 'my-pass-state', // the custom state name for the Pass state, defaults to 'Filter input and inject data' as the state name
288290
parameters: { // input to the pass state
289291
input: sfn.JsonPath.stringAt('$.input.greeting'),
290292
otherData: 'some-extra-stuff',

packages/aws-cdk-lib/aws-stepfunctions/lib/state-machine.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export interface StateMachineProps {
101101
readonly definitionBody?: DefinitionBody;
102102

103103
/**
104-
* substitutions for the definition body aas a key-value map
104+
* substitutions for the definition body as a key-value map
105105
*/
106106
readonly definitionSubstitutions?: { [key: string]: string };
107107

packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import { IChainable, INextable } from '../types';
99
* Properties for defining a Choice state
1010
*/
1111
export interface ChoiceProps {
12+
/**
13+
* Optional name for this state
14+
*
15+
* @default - The construct ID will be used as state name
16+
*/
17+
readonly stateName?: string;
18+
1219
/**
1320
* An optional description for this state
1421
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/fail.ts

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import { INextable } from '../types';
77
* Properties for defining a Fail state
88
*/
99
export interface FailProps {
10+
/**
11+
* Optional name for this state
12+
*
13+
* @default - The construct ID will be used as state name
14+
*/
15+
readonly stateName?: string;
16+
1017
/**
1118
* An optional description for this state
1219
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ import { CatchProps, IChainable, INextable, RetryProps } from '../types';
1111
* Properties for defining a Map state
1212
*/
1313
export interface MapProps {
14+
/**
15+
* Optional name for this state
16+
*
17+
* @default - The construct ID will be used as state name
18+
*/
19+
readonly stateName?: string;
20+
1421
/**
1522
* An optional description for this state
1623
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/parallel.ts

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import { CatchProps, IChainable, INextable, RetryProps } from '../types';
99
* Properties for defining a Parallel state
1010
*/
1111
export interface ParallelProps {
12+
/**
13+
* Optional name for this state
14+
*
15+
* @default - The construct ID will be used as state name
16+
*/
17+
readonly stateName?: string;
18+
1219
/**
1320
* An optional description for this state
1421
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/pass.ts

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ export class Result {
5656
* Properties for defining a Pass state
5757
*/
5858
export interface PassProps {
59+
/**
60+
* Optional name for this state
61+
*
62+
* @default - The construct ID will be used as state name
63+
*/
64+
readonly stateName?: string;
65+
5966
/**
6067
* An optional description for this state
6168
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import { CatchProps, Errors, IChainable, INextable, RetryProps } from '../types'
99
* Properties shared by all states
1010
*/
1111
export interface StateProps {
12+
/**
13+
* Optional name for this state
14+
*
15+
* @default - The construct ID will be used as state name
16+
*/
17+
readonly stateName?: string;
18+
1219
/**
1320
* A comment describing this state
1421
*
@@ -155,6 +162,7 @@ export abstract class State extends Construct implements IChainable {
155162
// features are shared by a couple of states, and it becomes cumbersome to
156163
// slice it out across all states. This is not great design, but it is
157164
// pragmatic!
165+
protected readonly stateName?: string;
158166
protected readonly comment?: string;
159167
protected readonly inputPath?: string;
160168
protected readonly parameters?: object;
@@ -194,6 +202,7 @@ export abstract class State extends Construct implements IChainable {
194202

195203
this.startState = this;
196204

205+
this.stateName = props.stateName;
197206
this.comment = props.comment;
198207
this.inputPath = props.inputPath;
199208
this.parameters = props.parameters;
@@ -219,7 +228,7 @@ export abstract class State extends Construct implements IChainable {
219228
* Tokenized string that evaluates to the state's ID
220229
*/
221230
public get stateId(): string {
222-
return this.prefixes.concat(this.id).join('');
231+
return this.prefixes.concat(this.stateName? this.stateName: this.id).join('');
223232
}
224233

225234
/**

packages/aws-cdk-lib/aws-stepfunctions/lib/states/succeed.ts

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ import { INextable } from '../types';
77
* Properties for defining a Succeed state
88
*/
99
export interface SucceedProps {
10+
/**
11+
* Optional name for this state
12+
*
13+
* @default - The construct ID will be used as state name
14+
*/
15+
readonly stateName?: string;
16+
1017
/**
1118
* An optional description for this state
1219
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/task-base.ts

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ import { CatchProps, IChainable, INextable, RetryProps } from '../types';
1313
* Props that are common to all tasks
1414
*/
1515
export interface TaskStateBaseProps {
16+
/**
17+
* Optional name for this state
18+
*
19+
* @default - The construct ID will be used as state name
20+
*/
21+
readonly stateName?: string;
22+
1623
/**
1724
* An optional description for this state
1825
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ export interface TaskProps {
2121
*/
2222
readonly task: IStepFunctionsTask;
2323

24+
/**
25+
* Optional name for this state
26+
*
27+
* @default - The construct ID will be used as state name
28+
*/
29+
readonly stateName?: string;
30+
2431
/**
2532
* An optional description for this state
2633
*

packages/aws-cdk-lib/aws-stepfunctions/lib/states/wait.ts

+7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ export class WaitTime {
5050
* Properties for defining a Wait state
5151
*/
5252
export interface WaitProps {
53+
/**
54+
* Optional name for this state
55+
*
56+
* @default - The construct ID will be used as state name
57+
*/
58+
readonly stateName?: string;
59+
5360
/**
5461
* An optional description for this state
5562
*

packages/aws-cdk-lib/aws-stepfunctions/test/custom-state.test.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ describe('Custom State', () => {
4141
// WHEN
4242
const definition = new sfn.CustomState(stack, 'Custom', {
4343
stateJson,
44-
}).next(new sfn.Pass(stack, 'MyPass'));
44+
}).next(new sfn.Pass(stack, 'MyPass', {
45+
stateName: 'my-pass-state',
46+
}));
4547

4648
// THEN
4749
expect(render(stack, definition)).toStrictEqual(
4850
{
4951
StartAt: 'Custom',
5052
States: {
51-
Custom: {
52-
Next: 'MyPass',
53+
'Custom': {
54+
Next: 'my-pass-state',
5355
Type: 'Task',
5456
Resource: 'arn:aws:states:::dynamodb:putItem',
5557
Parameters: {
@@ -62,7 +64,7 @@ describe('Custom State', () => {
6264
},
6365
ResultPath: null,
6466
},
65-
MyPass: {
67+
'my-pass-state': {
6668
Type: 'Pass',
6769
End: true,
6870
},
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,67 @@
1+
import { render } from './private/render-util';
12
import * as cdk from '../../core';
23
import * as stepfunctions from '../lib';
34

45
describe('Fail State', () => {
5-
test('Props are optional', () => {
6-
const stack = new cdk.Stack();
6+
let stack: cdk.Stack;
7+
let stateJson: any;
8+
9+
beforeEach(() => {
10+
// GIVEN
11+
stack = new cdk.Stack();
12+
stateJson = {
13+
Type: 'Task',
14+
Resource: 'arn:aws:states:::dynamodb:putItem',
15+
Parameters: {
16+
TableName: 'MyTable',
17+
Item: {
18+
id: {
19+
S: 'MyEntry',
20+
},
21+
},
22+
},
23+
ResultPath: null,
24+
};
25+
});
726

27+
test('Props are optional', () => {
828
new stepfunctions.Fail(stack, 'Fail');
929
});
30+
31+
test('can add a fail state to the chain with custom state name', () => {
32+
// WHEN
33+
const definition = new stepfunctions.CustomState(stack, 'Custom1', {
34+
stateJson,
35+
}).next(new stepfunctions.Pass(stack, 'MyPass'))
36+
.next(new stepfunctions.Fail(stack, 'Fail', {
37+
stateName: 'my-fail-state',
38+
comment: 'failing state',
39+
errorPath: stepfunctions.JsonPath.stringAt('$.error'),
40+
causePath: stepfunctions.JsonPath.stringAt('$.cause'),
41+
}));
42+
43+
// THEN
44+
expect(render(stack, definition)).toStrictEqual(
45+
{
46+
StartAt: 'Custom1',
47+
States: {
48+
'Custom1': {
49+
Next: 'MyPass',
50+
Type: 'Task',
51+
...stateJson,
52+
},
53+
'MyPass': {
54+
Type: 'Pass',
55+
Next: 'my-fail-state',
56+
},
57+
'my-fail-state': {
58+
Comment: 'failing state',
59+
Type: 'Fail',
60+
CausePath: '$.cause',
61+
ErrorPath: '$.error',
62+
},
63+
},
64+
},
65+
);
66+
});
1067
});

packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ describe('Map State', () => {
88

99
// WHEN
1010
const map = new stepfunctions.Map(stack, 'Map State', {
11+
stateName: 'My-Map-State',
1112
maxConcurrency: 1,
1213
itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'),
1314
parameters: {
@@ -19,9 +20,9 @@ describe('Map State', () => {
1920

2021
// THEN
2122
expect(render(map)).toStrictEqual({
22-
StartAt: 'Map State',
23+
StartAt: 'My-Map-State',
2324
States: {
24-
'Map State': {
25+
'My-Map-State': {
2526
Type: 'Map',
2627
End: true,
2728
Parameters: {

packages/aws-cdk-lib/aws-stepfunctions/test/parallel.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe('Parallel State', () => {
88

99
// WHEN
1010
const parallel = new stepfunctions.Parallel(stack, 'Parallel State');
11-
parallel.branch(new stepfunctions.Pass(stack, 'Branch 1'));
11+
parallel.branch(new stepfunctions.Pass(stack, 'Branch 1', { stateName: 'first-pass-state' }));
1212
parallel.branch(new stepfunctions.Pass(stack, 'Branch 2'));
1313

1414
// THEN
@@ -19,7 +19,7 @@ describe('Parallel State', () => {
1919
Type: 'Parallel',
2020
End: true,
2121
Branches: [
22-
{ StartAt: 'Branch 1', States: { 'Branch 1': { Type: 'Pass', End: true } } },
22+
{ StartAt: 'first-pass-state', States: { 'first-pass-state': { Type: 'Pass', End: true } } },
2323
{ StartAt: 'Branch 2', States: { 'Branch 2': { Type: 'Pass', End: true } } },
2424
],
2525
},

packages/aws-cdk-lib/aws-stepfunctions/test/state-machine-resources.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ describe('State Machine Resources', () => {
642642
// GIVEN
643643
const stack = new cdk.Stack();
644644
const task = new stepfunctions.Pass(stack, 'Pass', {
645+
stateName: 'my-pass-state',
645646
inputPath: '$',
646647
outputPath: '$.state',
647648
parameters: {

packages/aws-cdk-lib/aws-stepfunctions/test/wait.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,25 @@ describe('Wait State', () => {
7575
});
7676
});
7777

78+
test('supports adding a custom state name', () => {
79+
// GIVEN
80+
const stack = new cdk.Stack();
81+
const waitTime = new Wait(stack, 'myWaitState', {
82+
stateName: 'wait-state-custom-name',
83+
time: WaitTime.duration(cdk.Duration.seconds(30)),
84+
});
85+
86+
// THEN
87+
expect(render(stack, waitTime)).toEqual({
88+
StartAt: 'wait-state-custom-name',
89+
States: {
90+
'wait-state-custom-name': {
91+
Seconds: 30,
92+
Type: 'Wait',
93+
End: true,
94+
},
95+
},
96+
});
97+
});
98+
7899
});

0 commit comments

Comments
 (0)