Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stepfunctions): add comment ability for when condition #27010

Merged
merged 10 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "32.0.0",
"version": "34.0.0",
"files": {
"2b683032648fa932811d781e11acb71f29e8dcde21411e7cf232807cc2565770": {
"6fc80a94a8b95de238e82bf832c22a76af712d24dc10c332baa36571da0a4a41": {
"source": {
"path": "aws-stepfunctions-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "2b683032648fa932811d781e11acb71f29e8dcde21411e7cf232807cc2565770.json",
"objectKey": "6fc80a94a8b95de238e82bf832c22a76af712d24dc10c332baa36571da0a4a41.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@
"StateMachine2E01A3A5": {
"Type": "AWS::StepFunctions::StateMachine",
"Properties": {
"DefinitionString": "{\"StartAt\":\"wait time\",\"States\":{\"wait time\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.waitSeconds\",\"Next\":\"choice\"},\"choice\":{\"Type\":\"Choice\",\"Comment\":\"this is a comment for the choice state\",\"Choices\":[{\"Variable\":\"$.success\",\"IsPresent\":true,\"Next\":\"success\",\"Comment\":\"this is a comment for the when condition\"},{\"Variable\":\"$.noComment\",\"IsPresent\":true,\"Next\":\"short wait time\"}],\"Default\":\"success\"},\"success\":{\"Type\":\"Succeed\"},\"short wait time\":{\"Type\":\"Wait\",\"Seconds\":1,\"Next\":\"success\"}},\"Comment\":\"a super cool state machine\"}",
"RoleArn": {
"Fn::GetAtt": [
"StateMachineRoleB840431D",
"Arn"
]
},
"DefinitionString": "{\"StartAt\":\"wait time\",\"States\":{\"wait time\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.waitSeconds\",\"End\":true}},\"Comment\":\"a super cool state machine\"}"
}
},
"DependsOn": [
"StateMachineRoleB840431D"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"32.0.0"}
{"version":"34.0.0"}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "32.0.0",
"version": "34.0.0",
"testCases": {
"integ.state-machine": {
"stacks": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "32.0.0",
"version": "34.0.0",
"artifacts": {
"aws-stepfunctions-integ.assets": {
"type": "cdk:asset-manifest",
Expand All @@ -17,7 +17,7 @@
"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}/2b683032648fa932811d781e11acb71f29e8dcde21411e7cf232807cc2565770.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6fc80a94a8b95de238e82bf832c22a76af712d24dc10c332baa36571da0a4a41.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,32 @@
"id": "wait time",
"path": "aws-stepfunctions-integ/wait time",
"constructInfo": {
"fqn": "aws-cdk-lib.aws_stepfunctions.Wait",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"short wait time": {
"id": "short wait time",
"path": "aws-stepfunctions-integ/short wait time",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"choice": {
"id": "choice",
"path": "aws-stepfunctions-integ/choice",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"success": {
"id": "success",
"path": "aws-stepfunctions-integ/success",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"Role": {
Expand All @@ -24,8 +48,8 @@
"id": "ImportRole",
"path": "aws-stepfunctions-integ/Role/ImportRole",
"constructInfo": {
"fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"Resource": {
Expand All @@ -49,8 +73,8 @@
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.CfnRole",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"DefaultPolicy": {
Expand Down Expand Up @@ -139,20 +163,20 @@
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.Policy",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.Role",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"StateMachine": {
Expand All @@ -167,8 +191,8 @@
"id": "ImportRole",
"path": "aws-stepfunctions-integ/StateMachine/Role/ImportRole",
"constructInfo": {
"fqn": "aws-cdk-lib.Resource",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"Resource": {
Expand All @@ -192,14 +216,14 @@
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.CfnRole",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_iam.Role",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"Resource": {
Expand All @@ -208,60 +232,60 @@
"attributes": {
"aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine",
"aws:cdk:cloudformation:props": {
"definitionString": "{\"StartAt\":\"wait time\",\"States\":{\"wait time\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.waitSeconds\",\"Next\":\"choice\"},\"choice\":{\"Type\":\"Choice\",\"Comment\":\"this is a comment for the choice state\",\"Choices\":[{\"Variable\":\"$.success\",\"IsPresent\":true,\"Next\":\"success\",\"Comment\":\"this is a comment for the when condition\"},{\"Variable\":\"$.noComment\",\"IsPresent\":true,\"Next\":\"short wait time\"}],\"Default\":\"success\"},\"success\":{\"Type\":\"Succeed\"},\"short wait time\":{\"Type\":\"Wait\",\"Seconds\":1,\"Next\":\"success\"}},\"Comment\":\"a super cool state machine\"}",
"roleArn": {
"Fn::GetAtt": [
"StateMachineRoleB840431D",
"Arn"
]
},
"definitionString": "{\"StartAt\":\"wait time\",\"States\":{\"wait time\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.waitSeconds\",\"End\":true}},\"Comment\":\"a super cool state machine\"}"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"BootstrapVersion": {
"id": "BootstrapVersion",
"path": "aws-stepfunctions-integ/BootstrapVersion",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnParameter",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"CheckBootstrapVersion": {
"id": "CheckBootstrapVersion",
"path": "aws-stepfunctions-integ/CheckBootstrapVersion",
"constructInfo": {
"fqn": "aws-cdk-lib.CfnRule",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.Stack",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
},
"Tree": {
"id": "Tree",
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.2.26"
"version": "10.2.70"
}
}
},
"constructInfo": {
"fqn": "aws-cdk-lib.App",
"version": "0.0.0"
"fqn": "constructs.Construct",
"version": "10.2.70"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,30 @@ const wait = new sfn.Wait(stack, 'wait time', {
time: sfn.WaitTime.secondsPath('$.waitSeconds'),
});

const shortWait = new sfn.Wait(stack, 'short wait time', {
time: sfn.WaitTime.duration(cdk.Duration.seconds(1)),
});

const choice = new sfn.Choice(stack, 'choice', {
comment: 'this is a comment for the choice state',
});

const success = new sfn.Succeed(stack, 'success');

choice.when(sfn.Condition.isPresent('$.success'), success, {
comment: 'this is a comment for the when condition',
});
choice.when(sfn.Condition.isPresent('$.noComment'), shortWait);
choice.otherwise(success);
wait.next(choice);
shortWait.next(success);

const role = new iam.Role(stack, 'Role', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});

const stateMachine = new sfn.StateMachine(stack, 'StateMachine', {
definition: wait,
definitionBody: sfn.DefinitionBody.fromChainable(wait),
comment: 'a super cool state machine',
});

Expand Down
14 changes: 14 additions & 0 deletions packages/aws-cdk-lib/aws-stepfunctions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,20 @@ const shipTheItem = new sfn.Pass(this, 'ShipTheItem');
choice.afterwards().next(shipTheItem);
```

You can add comments to `Choice` states as well as conditions that use `choice.when`.

```ts
const choice = new sfn.Choice(this, 'What color is it?', {
comment: 'color comment',
});
const handleBlueItem = new sfn.Pass(this, 'HandleBlueItem');
const handleOtherItemColor = new sfn.Pass(this, 'HanldeOtherItemColor');
choice.when(sfn.Condition.stringEquals('$.color', 'BLUE'), handleBlueItem, {
comment: 'blue item comment',
});
choice.otherwise(handleOtherItemColor);
```

If your `Choice` doesn't have an `otherwise()` and none of the conditions match
the JSON state, a `NoChoiceMatched` error will be thrown. Wrap the state machine
in a `Parallel` state if you want to catch and recover from this.
Expand Down
6 changes: 3 additions & 3 deletions packages/aws-cdk-lib/aws-stepfunctions/lib/states/choice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Construct } from 'constructs';
import { StateType } from './private/state-type';
import { State } from './state';
import { IChoiceTransitionOptions, State } from './state';
import { Chain } from '../chain';
import { Condition } from '../condition';
import { IChainable, INextable } from '../types';
Expand Down Expand Up @@ -53,8 +53,8 @@ export class Choice extends State {
/**
* If the given condition matches, continue execution with the given state
*/
public when(condition: Condition, next: IChainable): Choice {
super.addChoice(condition, next.startState);
public when(condition: Condition, next: IChainable, options?: IChoiceTransitionOptions): Choice {
super.addChoice(condition, next.startState, options);
return this;
}

Expand Down
21 changes: 17 additions & 4 deletions packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,16 @@ export abstract class State extends Construct implements IChainable {
/**
* Add a choice branch to this state
*/
protected addChoice(condition: Condition, next: State) {
this.choices.push({ condition, next });
protected addChoice(condition: Condition, next: State, options?: IChoiceTransitionOptions) {
this.choices.push({ condition, next, ...options });
next.startState.addIncoming(this);
if (this.containingGraph) {
next.startState.bindToGraph(this.containingGraph);
}
}

/**
* Add a paralle branch to this state
* Add a parallel branch to this state
*/
protected addBranch(branch: StateGraph) {
this.branches.push(branch);
Expand Down Expand Up @@ -479,7 +479,7 @@ export interface FindStateOptions {
/**
* A Choice Transition
*/
interface ChoiceTransition {
interface ChoiceTransition extends IChoiceTransitionOptions {
/**
* State to transition to
*/
Expand All @@ -491,13 +491,26 @@ interface ChoiceTransition {
condition: Condition;
}

/**
* Options for Choice Transition
*/
export interface IChoiceTransitionOptions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msambol what was the reason for naming this IChoiceTransitionOptions? I assume you ran into some linter rule that yelled at you? Want to find out because I don't think it makes sense here, and we should exempt this from that rule if thats the case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaizencc Yep, I got:

aws-cdk-lib:     The declaring class is introduced here
aws-cdk-lib: aws-stepfunctions/lib/states/state.ts:503:3 - error JSII3008: The "comment" property of struct "aws-cdk-lib.aws_stepfunctions.ChoiceTransitionOptions" must be "readonly". Rename "aws-cdk-lib.aws_stepfunctions.ChoiceTransitionOptions" to "IChoiceTransitionOptions" if it is meant to be a behavioral interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaizencc From what I'm reading there isn't a way to silence JSII errors? Hmm..

/**
* An optional description for the choice transition
*
* @default No comment
*/
comment?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this fix the JSII error maybe?

Suggested change
comment?: string;
readonly comment?: string;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jogold It did. Good shout, Jonathan. I was following the pattern of state and condition but there is no reason this can't be readonly.

}

/**
* Render a choice transition
*/
function renderChoice(c: ChoiceTransition) {
return {
...c.condition.renderCondition(),
Next: c.next.stateId,
Comment: c.comment,
};
}

Expand Down
Loading