From ac417301348f3bc2f0b7352c032802c2aff8d721 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Fri, 15 Dec 2023 01:24:33 +0100 Subject: [PATCH] feat(stepfunctions): support Map ItemProcessor (#27913) Adds support for Map's [`ItemProcessor`](https://docs.aws.amazon.com/step-functions/latest/dg/use-dist-map-orchestrate-large-scale-parallel-workloads.html#distitemprocessor) required field and deprecates [`Iterator`](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-asl-use-map-state-inline.html#iterator). Closes #27878. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...unctions-map-distributed-stack.assets.json | 19 ++ ...ctions-map-distributed-stack.template.json | 79 +++++++ .../integ.map-distributed.js.snapshot/cdk.out | 1 + ...efaultTestDeployAssert69F30423.assets.json | 19 ++ ...aultTestDeployAssert69F30423.template.json | 36 ++++ .../integ.json | 12 ++ .../manifest.json | 125 +++++++++++ .../tree.json | 198 ++++++++++++++++++ .../test/integ.map-distributed.ts | 40 ++++ ...stepfunctions-map-inline-stack.assets.json | 19 ++ ...epfunctions-map-inline-stack.template.json | 79 +++++++ .../test/integ.map-inline.js.snapshot/cdk.out | 1 + ...efaultTestDeployAssertD29BA3EB.assets.json | 19 ++ ...aultTestDeployAssertD29BA3EB.template.json | 36 ++++ .../integ.map-inline.js.snapshot/integ.json | 12 ++ .../manifest.json | 125 +++++++++++ .../integ.map-inline.js.snapshot/tree.json | 198 ++++++++++++++++++ .../test/integ.map-inline.ts | 37 ++++ .../aws-cdk-lib/aws-stepfunctions/README.md | 23 +- .../aws-stepfunctions/lib/states/map.ts | 35 +++- .../aws-stepfunctions/lib/states/state.ts | 56 ++++- .../aws-stepfunctions/lib/types.ts | 51 +++++ .../aws-stepfunctions/test/map.test.ts | 162 +++++++++++++- 23 files changed, 1369 insertions(+), 13 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.ts create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.assets.json new file mode 100644 index 0000000000000..a71a5fd674bd0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "9947de492887a96f39e8510bfffd6b8914e1677fe0dab27eb0c043f0c2f6d17a": { + "source": { + "path": "cdk-stepfunctions-map-distributed-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "9947de492887a96f39e8510bfffd6b8914e1677fe0dab27eb0c043f0c2f6d17a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.template.json new file mode 100644 index 0000000000000..0dbcc08458793 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk-stepfunctions-map-distributed-stack.template.json @@ -0,0 +1,79 @@ +{ + "Resources": { + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"My-Map-State\",\"States\":{\"My-Map-State\":{\"Type\":\"Map\",\"End\":true,\"Parameters\":{\"foo\":\"foo\",\"bar.$\":\"$.bar\"},\"ItemsPath\":\"$.inputForMap\",\"ItemProcessor\":{\"ProcessorConfig\":{\"Mode\":\"DISTRIBUTED\",\"ExecutionType\":\"STANDARD\"},\"StartAt\":\"Pass State\",\"States\":{\"Pass State\":{\"Type\":\"Pass\",\"End\":true}}},\"MaxConcurrency\":1}},\"TimeoutSeconds\":30}", + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + }, + "DependsOn": [ + "StateMachineRoleB840431D" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Outputs": { + "StateMachineARN": { + "Value": { + "Ref": "StateMachine2E01A3A5" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets.json new file mode 100644 index 0000000000000..4ea723044a871 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/integ.json new file mode 100644 index 0000000000000..49c5aed19a1c4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "cdk-stepfunctions-map-distributed-integ/DefaultTest": { + "stacks": [ + "cdk-stepfunctions-map-distributed-stack" + ], + "assertionStack": "cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert", + "assertionStackName": "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/manifest.json new file mode 100644 index 0000000000000..1dead0f510155 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "34.0.0", + "artifacts": { + "cdk-stepfunctions-map-distributed-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdk-stepfunctions-map-distributed-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdk-stepfunctions-map-distributed-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdk-stepfunctions-map-distributed-stack.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}/9947de492887a96f39e8510bfffd6b8914e1677fe0dab27eb0c043f0c2f6d17a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdk-stepfunctions-map-distributed-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdk-stepfunctions-map-distributed-stack.assets" + ], + "metadata": { + "/cdk-stepfunctions-map-distributed-stack/StateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleB840431D" + } + ], + "/cdk-stepfunctions-map-distributed-stack/StateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachine2E01A3A5" + } + ], + "/cdk-stepfunctions-map-distributed-stack/StateMachineARN": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineARN" + } + ], + "/cdk-stepfunctions-map-distributed-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-stepfunctions-map-distributed-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-stepfunctions-map-distributed-stack" + }, + "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdkstepfunctionsmapdistributedintegDefaultTestDeployAssert69F30423.assets" + ], + "metadata": { + "/cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/tree.json new file mode 100644 index 0000000000000..ed58194eadb4f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.js.snapshot/tree.json @@ -0,0 +1,198 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cdk-stepfunctions-map-distributed-stack": { + "id": "cdk-stepfunctions-map-distributed-stack", + "path": "cdk-stepfunctions-map-distributed-stack", + "children": { + "Map": { + "id": "Map", + "path": "cdk-stepfunctions-map-distributed-stack/Map", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Map", + "version": "0.0.0" + } + }, + "Pass State": { + "id": "Pass State", + "path": "cdk-stepfunctions-map-distributed-stack/Pass State", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "StateMachine": { + "id": "StateMachine", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachine", + "children": { + "Role": { + "id": "Role", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachine/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"My-Map-State\",\"States\":{\"My-Map-State\":{\"Type\":\"Map\",\"End\":true,\"Parameters\":{\"foo\":\"foo\",\"bar.$\":\"$.bar\"},\"ItemsPath\":\"$.inputForMap\",\"ItemProcessor\":{\"ProcessorConfig\":{\"Mode\":\"DISTRIBUTED\",\"ExecutionType\":\"STANDARD\"},\"StartAt\":\"Pass State\",\"States\":{\"Pass State\":{\"Type\":\"Pass\",\"End\":true}}},\"MaxConcurrency\":1}},\"TimeoutSeconds\":30}", + "roleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "StateMachineARN": { + "id": "StateMachineARN", + "path": "cdk-stepfunctions-map-distributed-stack/StateMachineARN", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-stepfunctions-map-distributed-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-stepfunctions-map-distributed-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "cdk-stepfunctions-map-distributed-integ": { + "id": "cdk-stepfunctions-map-distributed-integ", + "path": "cdk-stepfunctions-map-distributed-integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-stepfunctions-map-distributed-integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-stepfunctions-map-distributed-integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-stepfunctions-map-distributed-integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.ts new file mode 100644 index 0000000000000..bb99002f11e69 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-distributed.ts @@ -0,0 +1,40 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; + +/** + * Stack verification steps: + * + * -- aws stepfunctions describe-state-machine --state-machine-arn has a status of `ACTIVE` + */ +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'cdk-stepfunctions-map-distributed-stack'); + +const map = new sfn.Map(stack, 'Map', { + stateName: 'My-Map-State', + maxConcurrency: 1, + itemsPath: sfn.JsonPath.stringAt('$.inputForMap'), + parameters: { + foo: 'foo', + bar: sfn.JsonPath.stringAt('$.bar'), + }, +}); +map.itemProcessor(new sfn.Pass(stack, 'Pass State'), { + mode: sfn.ProcessorMode.DISTRIBUTED, + executionType: sfn.ProcessorType.STANDARD, +}); + +const sm = new sfn.StateMachine(stack, 'StateMachine', { + definition: map, + timeout: cdk.Duration.seconds(30), +}); + +new cdk.CfnOutput(stack, 'StateMachineARN', { + value: sm.stateMachineArn, +}); + +new IntegTest(app, 'cdk-stepfunctions-map-distributed-integ', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.assets.json new file mode 100644 index 0000000000000..f34c7dcac2037 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "b6fa203c42a78ef53fd6c49b72e44a6a8fafa7f99e5bb3929a28e77bce9c4b1a": { + "source": { + "path": "cdk-stepfunctions-map-inline-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b6fa203c42a78ef53fd6c49b72e44a6a8fafa7f99e5bb3929a28e77bce9c4b1a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.template.json new file mode 100644 index 0000000000000..f10c9c1659c5a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk-stepfunctions-map-inline-stack.template.json @@ -0,0 +1,79 @@ +{ + "Resources": { + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"My-Map-State\",\"States\":{\"My-Map-State\":{\"Type\":\"Map\",\"End\":true,\"Parameters\":{\"foo\":\"foo\",\"bar.$\":\"$.bar\"},\"ItemsPath\":\"$.inputForMap\",\"ItemProcessor\":{\"ProcessorConfig\":{\"Mode\":\"INLINE\"},\"StartAt\":\"Pass State\",\"States\":{\"Pass State\":{\"Type\":\"Pass\",\"End\":true}}},\"MaxConcurrency\":1}},\"TimeoutSeconds\":30}", + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + }, + "DependsOn": [ + "StateMachineRoleB840431D" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Outputs": { + "StateMachineARN": { + "Value": { + "Ref": "StateMachine2E01A3A5" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets.json new file mode 100644 index 0000000000000..31d51e68eb434 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/integ.json new file mode 100644 index 0000000000000..a29bde12ec607 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "cdk-stepfunctions-map-inline-integ/DefaultTest": { + "stacks": [ + "cdk-stepfunctions-map-inline-stack" + ], + "assertionStack": "cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert", + "assertionStackName": "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/manifest.json new file mode 100644 index 0000000000000..9872b24608d9c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "34.0.0", + "artifacts": { + "cdk-stepfunctions-map-inline-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdk-stepfunctions-map-inline-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdk-stepfunctions-map-inline-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdk-stepfunctions-map-inline-stack.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}/b6fa203c42a78ef53fd6c49b72e44a6a8fafa7f99e5bb3929a28e77bce9c4b1a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdk-stepfunctions-map-inline-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdk-stepfunctions-map-inline-stack.assets" + ], + "metadata": { + "/cdk-stepfunctions-map-inline-stack/StateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleB840431D" + } + ], + "/cdk-stepfunctions-map-inline-stack/StateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachine2E01A3A5" + } + ], + "/cdk-stepfunctions-map-inline-stack/StateMachineARN": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineARN" + } + ], + "/cdk-stepfunctions-map-inline-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-stepfunctions-map-inline-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-stepfunctions-map-inline-stack" + }, + "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdkstepfunctionsmapinlineintegDefaultTestDeployAssertD29BA3EB.assets" + ], + "metadata": { + "/cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/tree.json new file mode 100644 index 0000000000000..a27cb6e5883da --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.js.snapshot/tree.json @@ -0,0 +1,198 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cdk-stepfunctions-map-inline-stack": { + "id": "cdk-stepfunctions-map-inline-stack", + "path": "cdk-stepfunctions-map-inline-stack", + "children": { + "Map": { + "id": "Map", + "path": "cdk-stepfunctions-map-inline-stack/Map", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Map", + "version": "0.0.0" + } + }, + "Pass State": { + "id": "Pass State", + "path": "cdk-stepfunctions-map-inline-stack/Pass State", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "StateMachine": { + "id": "StateMachine", + "path": "cdk-stepfunctions-map-inline-stack/StateMachine", + "children": { + "Role": { + "id": "Role", + "path": "cdk-stepfunctions-map-inline-stack/StateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "cdk-stepfunctions-map-inline-stack/StateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-stepfunctions-map-inline-stack/StateMachine/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-stepfunctions-map-inline-stack/StateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"My-Map-State\",\"States\":{\"My-Map-State\":{\"Type\":\"Map\",\"End\":true,\"Parameters\":{\"foo\":\"foo\",\"bar.$\":\"$.bar\"},\"ItemsPath\":\"$.inputForMap\",\"ItemProcessor\":{\"ProcessorConfig\":{\"Mode\":\"INLINE\"},\"StartAt\":\"Pass State\",\"States\":{\"Pass State\":{\"Type\":\"Pass\",\"End\":true}}},\"MaxConcurrency\":1}},\"TimeoutSeconds\":30}", + "roleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "StateMachineARN": { + "id": "StateMachineARN", + "path": "cdk-stepfunctions-map-inline-stack/StateMachineARN", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-stepfunctions-map-inline-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-stepfunctions-map-inline-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "cdk-stepfunctions-map-inline-integ": { + "id": "cdk-stepfunctions-map-inline-integ", + "path": "cdk-stepfunctions-map-inline-integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-stepfunctions-map-inline-integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-stepfunctions-map-inline-integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-stepfunctions-map-inline-integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.ts new file mode 100644 index 0000000000000..8b717a34f7399 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions/test/integ.map-inline.ts @@ -0,0 +1,37 @@ +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; + +/** + * Stack verification steps: + * + * -- aws stepfunctions describe-state-machine --state-machine-arn has a status of `ACTIVE` + */ +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'cdk-stepfunctions-map-inline-stack'); + +const map = new sfn.Map(stack, 'Map', { + stateName: 'My-Map-State', + maxConcurrency: 1, + itemsPath: sfn.JsonPath.stringAt('$.inputForMap'), + parameters: { + foo: 'foo', + bar: sfn.JsonPath.stringAt('$.bar'), + }, +}); +map.itemProcessor(new sfn.Pass(stack, 'Pass State')); + +const sm = new sfn.StateMachine(stack, 'StateMachine', { + definition: map, + timeout: cdk.Duration.seconds(30), +}); + +new cdk.CfnOutput(stack, 'StateMachineARN', { + value: sm.stateMachineArn, +}); + +new IntegTest(app, 'cdk-stepfunctions-map-inline-integ', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-stepfunctions/README.md b/packages/aws-cdk-lib/aws-stepfunctions/README.md index d837201f2fcb7..ab142c0f1ddbd 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions/README.md @@ -518,9 +518,30 @@ const definition = choice .afterwards() .next(finish); -map.iterator(definition); +map.itemProcessor(definition); ``` +To define a distributed `Map` state set `itemProcessors` mode to `ProcessorMode.DISTRIBUTED`. +An `executionType` must be specified for the distributed `Map` workflow. + +```ts +const map = new sfn.Map(this, 'Map State', { + maxConcurrency: 1, + itemsPath: sfn.JsonPath.stringAt('$.inputForMap'), + parameters: { + item: sfn.JsonPath.stringAt('$$.Map.Item.Value'), + }, + resultPath: '$.mapOutput', +}); + +map.itemProcessor(new sfn.Pass(this, 'Pass State'), { + mode: sfn.ProcessorMode.DISTRIBUTED, + executionType: sfn.ProcessorType.STANDARD, +}); +``` + +> Visit [Using Map state in Distributed mode to orchestrate large-scale parallel workloads](https://docs.aws.amazon.com/step-functions/latest/dg/use-dist-map-orchestrate-large-scale-parallel-workloads.html) for more details. + ### Custom State It's possible that the high-level constructs for the states or `stepfunctions-tasks` do not have 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..8ac82640fa8ec 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/map.ts @@ -5,7 +5,7 @@ import { Token } from '../../../core'; import { Chain } from '../chain'; import { FieldUtils } from '../fields'; import { StateGraph } from '../state-graph'; -import { CatchProps, IChainable, INextable, RetryProps } from '../types'; +import { CatchProps, IChainable, INextable, ProcessorConfig, ProcessorMode, RetryProps } from '../types'; /** * Properties for defining a Map state @@ -161,7 +161,11 @@ export class Map extends State implements INextable { } /** - * Define iterator state machine in Map + * Define iterator state machine in Map. + * + * A Map must either have a non-empty iterator or a non-empty item processor, not both. + * + * @deprecated - use `itemProcessor` instead. */ public iterator(iterator: IChainable): Map { const name = `Map ${this.stateId} Iterator`; @@ -169,6 +173,18 @@ export class Map extends State implements INextable { return this; } + /** + * Define item processor in Map. + * + * A Map must either have a non-empty iterator or a non-empty item processor, not both. + */ + public itemProcessor(processor: IChainable, config: ProcessorConfig = {}): Map { + const name = `Map ${this.stateId} Item Processor`; + const stateGraph = new StateGraph(processor.startState, name); + super.addItemProcessor(stateGraph, config); + return this; + } + /** * Return the Amazon States Language object for this state */ @@ -184,6 +200,7 @@ export class Map extends State implements INextable { ...this.renderRetryCatch(), ...this.renderIterator(), ...this.renderItemsPath(), + ...this.renderItemProcessor(), MaxConcurrency: this.maxConcurrency, }; } @@ -194,11 +211,19 @@ export class Map extends State implements INextable { protected validateState(): string[] { const errors: string[] = []; - if (this.iteration === undefined) { - errors.push('Map state must have a non-empty iterator'); + if (!this.iteration && !this.processor) { + errors.push('Map state must either have a non-empty iterator or a non-empty item processor'); + } + + if (this.iteration && this.processor) { + errors.push('Map state cannot have both an iterator and an item processor'); + } + + if (this.processorConfig?.mode === ProcessorMode.DISTRIBUTED && !this.processorConfig?.executionType) { + errors.push('You must specify an execution type for the distributed Map workflow'); } - if (this.maxConcurrency !== undefined && !Token.isUnresolved(this.maxConcurrency) && !isPositiveInteger(this.maxConcurrency)) { + if (this.maxConcurrency && !Token.isUnresolved(this.maxConcurrency) && !isPositiveInteger(this.maxConcurrency)) { errors.push('maxConcurrency has to be a positive integer'); } 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 7598f092a396b..7eab65e4fe366 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/states/state.ts @@ -3,7 +3,7 @@ import { Token } from '../../../core'; import { Condition } from '../condition'; import { FieldUtils } from '../fields'; import { StateGraph } from '../state-graph'; -import { CatchProps, Errors, IChainable, INextable, RetryProps } from '../types'; +import { CatchProps, Errors, IChainable, INextable, ProcessorConfig, ProcessorMode, RetryProps } from '../types'; /** * Properties shared by all states @@ -171,6 +171,8 @@ export abstract class State extends Construct implements IChainable { protected readonly resultSelector?: object; protected readonly branches: StateGraph[] = []; protected iteration?: StateGraph; + protected processor?: StateGraph; + protected processorConfig?: ProcessorConfig; protected defaultChoice?: State; /** @@ -269,6 +271,9 @@ export abstract class State extends Construct implements IChainable { if (!!this.iteration) { this.iteration.registerSuperGraph(this.containingGraph); } + if (!!this.processor) { + this.processor.registerSuperGraph(this.containingGraph); + } } /** @@ -355,6 +360,17 @@ export abstract class State extends Construct implements IChainable { } } + /** + * Add a item processor to this state + */ + protected addItemProcessor(processor: StateGraph, config: ProcessorConfig = {}) { + this.processor = processor; + this.processorConfig = config; + if (this.containingGraph) { + processor.registerSuperGraph(this.containingGraph); + } + } + /** * Make the indicated state the default choice transition of this state */ @@ -411,9 +427,7 @@ export abstract class State extends Construct implements IChainable { * Render map iterator in ASL JSON format */ protected renderIterator(): any { - if (!this.iteration) { - throw new Error('Iterator must not be undefined !'); - } + if (!this.iteration) return undefined; return { Iterator: this.iteration.toGraphJson(), }; @@ -438,6 +452,40 @@ export abstract class State extends Construct implements IChainable { }); } + /** + * Render ItemProcessor in ASL JSON format + */ + protected renderItemProcessor(): any { + if (!this.processor) return undefined; + return { + ItemProcessor: { + ...this.renderProcessorConfig(), + ...this.processor.toGraphJson(), + }, + }; + } + + /** + * Render ProcessorConfig in ASL JSON format + */ + private renderProcessorConfig() { + const mode = this.processorConfig?.mode?.toString() ?? ProcessorMode.INLINE; + if (mode === ProcessorMode.INLINE) { + return { + ProcessorConfig: { + Mode: mode, + }, + }; + } + const executionType = this.processorConfig?.executionType?.toString(); + return { + ProcessorConfig: { + Mode: mode, + ExecutionType: executionType, + }, + }; + } + /** * Called whenever this state is bound to a graph * diff --git a/packages/aws-cdk-lib/aws-stepfunctions/lib/types.ts b/packages/aws-cdk-lib/aws-stepfunctions/lib/types.ts index 29b058098a07a..0bdfd1f4c33db 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/lib/types.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/lib/types.ts @@ -183,6 +183,57 @@ export interface CatchProps { readonly resultPath?: string; } +/** + * Mode of the Map workflow. + */ +export enum ProcessorMode { + /** + * Inline Map mode. + */ + INLINE = 'INLINE', + + /** + * Distributed Map mode. + */ + DISTRIBUTED = 'DISTRIBUTED', +} + +/** + * Execution type for the Map workflow. + */ +export enum ProcessorType { + /** + * Standard execution type. + */ + STANDARD = 'STANDARD', + + /** + * Express execution type. + */ + EXPRESS = 'EXPRESS', +} + +/** + * Specifies the configuration for the processor Map state. + */ +export interface ProcessorConfig { + /** + * Specifies the execution mode for the Map workflow. + * + * @default - ProcessorMode.INLINE + */ + readonly mode?: ProcessorMode; + + /** + * Specifies the execution type for the Map workflow. + * + * You must provide this field if you specified `DISTRIBUTED` for the `mode` sub-field. + * + * @default - no execution type + */ + readonly executionType?: ProcessorType; +} + /** * Special string value to discard state input, output or result * @deprecated use JsonPath.DISCARD 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 44a4417bdcd9d..1dddad4beb531 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions/test/map.test.ts @@ -87,7 +87,103 @@ describe('Map State', () => { }); }), - test('synth is successful', () => { + test('State Machine With Map State and Item Processor', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const map = new stepfunctions.Map(stack, 'Map State', { + stateName: 'My-Map-State', + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + parameters: { + foo: 'foo', + bar: stepfunctions.JsonPath.stringAt('$.bar'), + }, + }); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State')); + + // THEN + expect(render(map)).toStrictEqual({ + StartAt: 'My-Map-State', + States: { + 'My-Map-State': { + Type: 'Map', + End: true, + Parameters: { + 'foo': 'foo', + 'bar.$': '$.bar', + }, + ItemProcessor: { + ProcessorConfig: { + Mode: 'INLINE', + }, + StartAt: 'Pass State', + States: { + 'Pass State': { + Type: 'Pass', + End: true, + }, + }, + }, + ItemsPath: '$.inputForMap', + MaxConcurrency: 1, + }, + }, + }); + }), + + test('State Machine With Map State and Item Processor in distributed mode', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const map = new stepfunctions.Map(stack, 'Map State', { + stateName: 'My-Map-State', + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + parameters: { + foo: 'foo', + bar: stepfunctions.JsonPath.stringAt('$.bar'), + }, + }); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State'), { + mode: stepfunctions.ProcessorMode.DISTRIBUTED, + executionType: stepfunctions.ProcessorType.STANDARD, + }); + + // THEN + expect(render(map)).toStrictEqual({ + StartAt: 'My-Map-State', + States: { + 'My-Map-State': { + Type: 'Map', + End: true, + Parameters: { + 'foo': 'foo', + 'bar.$': '$.bar', + }, + ItemProcessor: { + ProcessorConfig: { + Mode: 'DISTRIBUTED', + ExecutionType: 'STANDARD', + }, + StartAt: 'Pass State', + States: { + 'Pass State': { + Type: 'Pass', + End: true, + }, + }, + }, + ItemsPath: '$.inputForMap', + MaxConcurrency: 1, + }, + }, + }); + }), + + test('synth is successful with iterator', () => { const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1, @@ -100,17 +196,77 @@ describe('Map State', () => { app.synth(); }), - test('fails in synthesis if iterator is missing', () => { + test('synth is successful with item processor and inline mode', () => { + const app = createAppWithMap((stack) => { + const map = new stepfunctions.Map(stack, 'Map State', { + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + }); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State')); + return map; + }); + + app.synth(); + }), + + test('synth is successful with item processor and distributed mode', () => { + const app = createAppWithMap((stack) => { + const map = new stepfunctions.Map(stack, 'Map State', { + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + }); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State'), { + mode: stepfunctions.ProcessorMode.DISTRIBUTED, + executionType: stepfunctions.ProcessorType.STANDARD, + }); + return map; + }); + + app.synth(); + }), + + test('fails in synthesis if iterator and item processor are missing', () => { + const app = createAppWithMap((stack) => { + const map = new stepfunctions.Map(stack, 'Map State', { + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + }); + + return map; + }); + + expect(() => app.synth()).toThrow(/Map state must either have a non-empty iterator or a non-empty item processor/); + }), + + test('fails in synthesis if both iterator and item processor are defined', () => { + const app = createAppWithMap((stack) => { + const map = new stepfunctions.Map(stack, 'Map State', { + maxConcurrency: 1, + itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), + }); + map.iterator(new stepfunctions.Pass(stack, 'Pass State 1')); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State 2')); + + return map; + }); + + expect(() => app.synth()).toThrow(/Map state cannot have both an iterator and an item processor/); + }), + + test('fails in synthesis if distributed mode and execution type is not defined', () => { const app = createAppWithMap((stack) => { const map = new stepfunctions.Map(stack, 'Map State', { maxConcurrency: 1, itemsPath: stepfunctions.JsonPath.stringAt('$.inputForMap'), }); + map.itemProcessor(new stepfunctions.Pass(stack, 'Pass State'), { + mode: stepfunctions.ProcessorMode.DISTRIBUTED, + }); return map; }); - expect(() => app.synth()).toThrow(/Map state must have a non-empty iterator/); + expect(() => app.synth()).toThrow(/You must specify an execution type for the distributed Map workflow/); }), test('fails in synthesis when maxConcurrency is a float', () => {