From d2ee6e51c086b3601e91c2412f8e0d8b9ec1c9ab Mon Sep 17 00:00:00 2001 From: Jorge Diaz Date: Fri, 27 Jun 2025 10:54:01 +0200 Subject: [PATCH] fix(stepfunctions-tasks): properly serialize CallAwsServiceCrossRegion Lambda responses --- ...efaultTestDeployAssertE3E7D2A4.assets.json | 33 + ...aultTestDeployAssertE3E7D2A4.template.json | 573 ++++++++++++++++++ .../index.js | 1 + ...vice-cross-region-lambda-integ.assets.json | 34 ++ ...ce-cross-region-lambda-integ.template.json | 416 +++++++++++++ .../cdk.out | 1 + .../integ.json | 13 + .../manifest.json | 529 ++++++++++++++++ .../tree.json | 1 + ...eg.call-aws-service-cross-region-lambda.ts | 97 +++ .../cross-region-aws-sdk-handler/index.ts | 15 +- .../cross-region-aws-sdk-handler.test.ts | 213 +++++++ 12 files changed, 1925 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/asset.e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.ts create mode 100644 packages/@aws-cdk/custom-resource-handlers/test/aws-stepfunctions-tasks/cross-region-aws-sdk-handler.test.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json new file mode 100644 index 0000000000000..583f16887b580 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json @@ -0,0 +1,33 @@ +{ + "version": "44.0.0", + "files": { + "c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96": { + "source": { + "path": "asset.c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96.bundle", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "aebbf74f08c89a84f0c1281c47960cfea0ea5866ecdd510ffc2ea8ecc2eace7d": { + "displayName": "IntegTestDefaultTestDeployAssertE3E7D2A4 Template", + "source": { + "path": "IntegTestDefaultTestDeployAssertE3E7D2A4.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "aebbf74f08c89a84f0c1281c47960cfea0ea5866ecdd510ffc2ea8ecc2eace7d.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-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json new file mode 100644 index 0000000000000..c0c460a53290d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/IntegTestDefaultTestDeployAssertE3E7D2A4.template.json @@ -0,0 +1,573 @@ +{ + "Resources": { + "AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa": { + "Type": "Custom::DeployAssert@SdkCallStepFunctionsstartExecution", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "StepFunctions", + "api": "startExecution", + "parameters": { + "stateMachineArn": { + "Fn::Join": [ + "", + [ + "\"", + { + "Fn::ImportValue": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ:ExportsOutputRefTestStateMachine3C216BE323AC47AE" + }, + "\"" + ] + ] + } + }, + "flattenResponse": "true", + "outputPaths": [ + "executionArn" + ], + "salt": "1751043897586" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "states:StartExecution" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, + { + "Action": [ + "states:DescribeExecution" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, + { + "Action": [ + "states:StartExecution" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + } + ] + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96.zip" + }, + "Timeout": 120, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + }, + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c": { + "Type": "Custom::DeployAssert@SdkCallStepFunctionsdescribeExecution", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "StepFunctions", + "api": "describeExecution", + "expected": "{\"$ObjectLike\":{\"output\":{\"$StringLike\":\".*\\\"statusCode\\\":200.*\\\"status\\\":\\\"success\\\".*\\\"message\\\":\\\"Hello from target Lambda\\\".*\"}}}", + "stateMachineArn": { + "Ref": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForEDC8A739" + }, + "parameters": { + "executionArn": { + "Fn::Join": [ + "", + [ + "\"", + { + "Fn::GetAtt": [ + "AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa", + "apiCallResponse.executionArn" + ] + }, + "\"" + ] + ] + } + }, + "flattenResponse": "false", + "salt": "1751043897586" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForIsCompleteProviderInvokeEF8ACA63": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "SingletonFunction76b3e830a873425f8453eddd85c86925Handler81461ECE", + "Arn" + ] + }, + "Principal": { + "Fn::GetAtt": [ + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E", + "Arn" + ] + } + } + }, + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForTimeoutProviderInvokeFCAFDA76": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aHandlerADF3E6EA", + "Arn" + ] + }, + "Principal": { + "Fn::GetAtt": [ + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E", + "Arn" + ] + } + } + }, + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ] + }, + "Policies": [ + { + "PolicyName": "InlineInvokeFunctions", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "SingletonFunction76b3e830a873425f8453eddd85c86925Handler81461ECE", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aHandlerADF3E6EA", + "Arn" + ] + } + ] + } + ] + } + } + ] + } + }, + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForEDC8A739": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"framework-isComplete-task\",\"States\":{\"framework-isComplete-task\":{\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"States.ALL\"],\"IntervalSeconds\":10,\"MaxAttempts\":30,\"BackoffRate\":1}],\"Catch\":[{\"ErrorEquals\":[\"States.ALL\"],\"Next\":\"framework-onTimeout-task\"}],\"Type\":\"Task\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "SingletonFunction76b3e830a873425f8453eddd85c86925Handler81461ECE", + "Arn" + ] + }, + "\"},\"framework-onTimeout-task\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aHandlerADF3E6EA", + "Arn" + ] + }, + "\"}}}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E", + "Arn" + ] + } + }, + "DependsOn": [ + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E" + ] + }, + "SingletonFunction76b3e830a873425f8453eddd85c86925Role918961BB": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "states:DescribeExecution" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + } + ] + } + } + ] + } + }, + "SingletonFunction76b3e830a873425f8453eddd85c86925Handler81461ECE": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96.zip" + }, + "Timeout": 120, + "Handler": "index.isComplete", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction76b3e830a873425f8453eddd85c86925Role918961BB", + "Arn" + ] + } + } + }, + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aRoleB84BD8CE": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aHandlerADF3E6EA": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "c74d4e3c82f2db3767a5b28f12d80d3dc43fdb041406fd738e1a754a716b9f96.zip" + }, + "Timeout": 120, + "Handler": "index.onTimeout", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aRoleB84BD8CE", + "Arn" + ] + } + } + } + }, + "Mappings": { + "LatestNodeRuntimeMap": { + "af-south-1": { + "value": "nodejs22.x" + }, + "ap-east-1": { + "value": "nodejs22.x" + }, + "ap-east-2": { + "value": "nodejs22.x" + }, + "ap-northeast-1": { + "value": "nodejs22.x" + }, + "ap-northeast-2": { + "value": "nodejs22.x" + }, + "ap-northeast-3": { + "value": "nodejs22.x" + }, + "ap-south-1": { + "value": "nodejs22.x" + }, + "ap-south-2": { + "value": "nodejs22.x" + }, + "ap-southeast-1": { + "value": "nodejs22.x" + }, + "ap-southeast-2": { + "value": "nodejs22.x" + }, + "ap-southeast-3": { + "value": "nodejs22.x" + }, + "ap-southeast-4": { + "value": "nodejs22.x" + }, + "ap-southeast-5": { + "value": "nodejs22.x" + }, + "ap-southeast-7": { + "value": "nodejs22.x" + }, + "ca-central-1": { + "value": "nodejs22.x" + }, + "ca-west-1": { + "value": "nodejs22.x" + }, + "cn-north-1": { + "value": "nodejs22.x" + }, + "cn-northwest-1": { + "value": "nodejs22.x" + }, + "eu-central-1": { + "value": "nodejs22.x" + }, + "eu-central-2": { + "value": "nodejs22.x" + }, + "eu-isoe-west-1": { + "value": "nodejs18.x" + }, + "eu-north-1": { + "value": "nodejs22.x" + }, + "eu-south-1": { + "value": "nodejs22.x" + }, + "eu-south-2": { + "value": "nodejs22.x" + }, + "eu-west-1": { + "value": "nodejs22.x" + }, + "eu-west-2": { + "value": "nodejs22.x" + }, + "eu-west-3": { + "value": "nodejs22.x" + }, + "il-central-1": { + "value": "nodejs22.x" + }, + "me-central-1": { + "value": "nodejs22.x" + }, + "me-south-1": { + "value": "nodejs22.x" + }, + "mx-central-1": { + "value": "nodejs22.x" + }, + "sa-east-1": { + "value": "nodejs22.x" + }, + "us-east-1": { + "value": "nodejs22.x" + }, + "us-east-2": { + "value": "nodejs22.x" + }, + "us-gov-east-1": { + "value": "nodejs22.x" + }, + "us-gov-west-1": { + "value": "nodejs22.x" + }, + "us-iso-east-1": { + "value": "nodejs18.x" + }, + "us-iso-west-1": { + "value": "nodejs18.x" + }, + "us-isob-east-1": { + "value": "nodejs18.x" + }, + "us-isob-west-1": { + "value": "nodejs18.x" + }, + "us-west-1": { + "value": "nodejs22.x" + }, + "us-west-2": { + "value": "nodejs22.x" + } + } + }, + "Outputs": { + "AssertionResultsAwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c": { + "Value": { + "Fn::GetAtt": [ + "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c", + "assertion" + ] + } + } + }, + "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-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/asset.e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/asset.e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e/index.js new file mode 100644 index 0000000000000..9730dbb7c41c3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/asset.e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e/index.js @@ -0,0 +1 @@ +"use strict";var i=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var g=(e,n)=>{for(var r in n)i(e,r,{get:n[r],enumerable:!0})},y=(e,n,r,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of m(n))!f.call(e,o)&&o!==r&&i(e,o,{get:()=>n[o],enumerable:!(a=l(n,o))||a.enumerable});return e};var p=e=>y(i({},"__esModule",{value:!0}),e);var P={};g(P,{handler:()=>u});module.exports=p(P);function w(e){let n=Object.entries(e).filter(([r])=>r.endsWith("Client")&&r!=="__Client");if(n.length==0)throw new Error("There is no *Client class in the package.");if(n.length>1)throw new Error(`There are more than one *Client classes in the package: ${n.map(r=>r[0]).join(",")}`);return n[0][1]}function h(e){return e.charAt(0).toUpperCase()+e.slice(1)}function C(e,n){let r=`${h(n)}Command`,a=Object.entries(e).find(([o])=>o.toLowerCase()===r.toLowerCase())?.[1];if(!a)throw new Error(`Unable to find command named: ${r} for action: ${n} in service package`);return a}var u=async e=>{console.log("Event: ",e);try{let n=require(`@aws-sdk/client-${e.service}`),r=w(n),a=C(n,e.action),o=new r({region:e.region,endpoint:e.endpoint}),c=new a(e.parameters??{}),t=await o.send(c);if(t.Payload&&(t.Payload instanceof Uint8Array||t.Payload instanceof Buffer))try{let s=new TextDecoder().decode(t.Payload);t.Payload=JSON.parse(s)}catch{t.Payload=new TextDecoder().decode(t.Payload)}let d=JSON.stringify(t);return JSON.parse(d)}catch(n){throw console.error("Error: ",n),n}};0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets.json new file mode 100644 index 0000000000000..d9c56439f5613 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets.json @@ -0,0 +1,34 @@ +{ + "version": "44.0.0", + "files": { + "e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e": { + "displayName": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Code", + "source": { + "path": "asset.e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "19cecb6e0ce3d76added8b06057e8d30f798a5b3c4c428bff3a722dfff5d7e88": { + "displayName": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ Template", + "source": { + "path": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19cecb6e0ce3d76added8b06057e8d30f798a5b3c4c428bff3a722dfff5d7e88.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-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json new file mode 100644 index 0000000000000..d82ce9e1e0d8f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json @@ -0,0 +1,416 @@ +{ + "Resources": { + "TargetLambdaServiceRole567EC23E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "TargetLambdaE6C763FE": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "\n exports.handler = async (event) => {\n console.log('Target Lambda received event:', JSON.stringify(event, null, 2));\n \n // Return a JSON response that should be properly serialized\n return {\n statusCode: 200,\n body: {\n status: 'success',\n message: 'Hello from target Lambda',\n receivedData: event\n }\n };\n };\n " + }, + "Description": "Target Lambda function for CallAwsServiceCrossRegion testing", + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "TargetLambdaServiceRole567EC23E", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "TargetLambdaServiceRole567EC23E" + ] + }, + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRoleDefaultPolicy63AE5FEF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TargetLambdaE6C763FE", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRoleDefaultPolicy63AE5FEF", + "Roles": [ + { + "Ref": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520" + } + ] + } + }, + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e.zip" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520", + "Arn" + ] + }, + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Timeout": 30 + }, + "DependsOn": [ + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRoleDefaultPolicy63AE5FEF", + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520" + ] + }, + "TestStateMachineRole2476F720": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TestStateMachineRoleDefaultPolicyB28F488D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TestStateMachineRoleDefaultPolicyB28F488D", + "Roles": [ + { + "Ref": "TestStateMachineRole2476F720" + } + ] + } + }, + "TestStateMachine3C216BE3": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"CrossRegionLambdaInvoke\",\"States\":{\"CrossRegionLambdaInvoke\":{\"QueryLanguage\":\"JSONata\",\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ClientExecutionTimeoutException\",\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Arguments\":{\"region\":\"us-east-1\",\"action\":\"invoke\",\"service\":\"lambda\",\"parameters\":{\"FunctionName\":\"", + { + "Fn::GetAtt": [ + "TargetLambdaE6C763FE", + "Arn" + ] + }, + "\",\"Payload\":\"{\\\"hello\\\":\\\"world\\\",\\\"testData\\\":\\\"reproduction\\\"}\"}},\"Resource\":\"", + { + "Fn::GetAtt": [ + "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F", + "Arn" + ] + }, + "\"}},\"TimeoutSeconds\":300,\"Comment\":\"State machine to reproduce issue 34768 - CallAwsServiceCrossRegion byte array bug\"}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "TestStateMachineRole2476F720", + "Arn" + ] + } + }, + "DependsOn": [ + "TestStateMachineRoleDefaultPolicyB28F488D", + "TestStateMachineRole2476F720" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Mappings": { + "LatestNodeRuntimeMap": { + "af-south-1": { + "value": "nodejs22.x" + }, + "ap-east-1": { + "value": "nodejs22.x" + }, + "ap-east-2": { + "value": "nodejs22.x" + }, + "ap-northeast-1": { + "value": "nodejs22.x" + }, + "ap-northeast-2": { + "value": "nodejs22.x" + }, + "ap-northeast-3": { + "value": "nodejs22.x" + }, + "ap-south-1": { + "value": "nodejs22.x" + }, + "ap-south-2": { + "value": "nodejs22.x" + }, + "ap-southeast-1": { + "value": "nodejs22.x" + }, + "ap-southeast-2": { + "value": "nodejs22.x" + }, + "ap-southeast-3": { + "value": "nodejs22.x" + }, + "ap-southeast-4": { + "value": "nodejs22.x" + }, + "ap-southeast-5": { + "value": "nodejs22.x" + }, + "ap-southeast-7": { + "value": "nodejs22.x" + }, + "ca-central-1": { + "value": "nodejs22.x" + }, + "ca-west-1": { + "value": "nodejs22.x" + }, + "cn-north-1": { + "value": "nodejs22.x" + }, + "cn-northwest-1": { + "value": "nodejs22.x" + }, + "eu-central-1": { + "value": "nodejs22.x" + }, + "eu-central-2": { + "value": "nodejs22.x" + }, + "eu-isoe-west-1": { + "value": "nodejs18.x" + }, + "eu-north-1": { + "value": "nodejs22.x" + }, + "eu-south-1": { + "value": "nodejs22.x" + }, + "eu-south-2": { + "value": "nodejs22.x" + }, + "eu-west-1": { + "value": "nodejs22.x" + }, + "eu-west-2": { + "value": "nodejs22.x" + }, + "eu-west-3": { + "value": "nodejs22.x" + }, + "il-central-1": { + "value": "nodejs22.x" + }, + "me-central-1": { + "value": "nodejs22.x" + }, + "me-south-1": { + "value": "nodejs22.x" + }, + "mx-central-1": { + "value": "nodejs22.x" + }, + "sa-east-1": { + "value": "nodejs22.x" + }, + "us-east-1": { + "value": "nodejs22.x" + }, + "us-east-2": { + "value": "nodejs22.x" + }, + "us-gov-east-1": { + "value": "nodejs22.x" + }, + "us-gov-west-1": { + "value": "nodejs22.x" + }, + "us-iso-east-1": { + "value": "nodejs18.x" + }, + "us-iso-west-1": { + "value": "nodejs18.x" + }, + "us-isob-east-1": { + "value": "nodejs18.x" + }, + "us-isob-west-1": { + "value": "nodejs18.x" + }, + "us-west-1": { + "value": "nodejs22.x" + }, + "us-west-2": { + "value": "nodejs22.x" + } + } + }, + "Outputs": { + "ExportsOutputRefTestStateMachine3C216BE323AC47AE": { + "Value": { + "Ref": "TestStateMachine3C216BE3" + }, + "Export": { + "Name": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ:ExportsOutputRefTestStateMachine3C216BE323AC47AE" + } + } + }, + "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-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/cdk.out new file mode 100644 index 0000000000000..b3a26d44a5f73 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"44.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/integ.json new file mode 100644 index 0000000000000..82a78be7f17e1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "44.0.0", + "testCases": { + "IntegTest/DefaultTest": { + "stacks": [ + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ" + ], + "assertionStack": "IntegTest/DefaultTest/DeployAssert", + "assertionStackName": "IntegTestDefaultTestDeployAssertE3E7D2A4" + } + }, + "minimumCliVersion": "2.1019.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/manifest.json new file mode 100644 index 0000000000000..995600648c62a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/manifest.json @@ -0,0 +1,529 @@ +{ + "version": "44.0.0", + "artifacts": { + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/19cecb6e0ce3d76added8b06057e8d30f798a5b3c4c428bff3a722dfff5d7e88.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.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": [ + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ.assets" + ], + "metadata": { + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "runtime": "*", + "handler": "*", + "code": "*", + "description": "*" + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "assumedBy": { + "principalAccount": "*", + "assumeRoleAction": "*" + }, + "managedPolicies": [ + { + "managedPolicyArn": "*" + } + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole/ImportServiceRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TargetLambdaServiceRole567EC23E" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TargetLambdaE6C763FE" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionLambdaInvoke/Handler": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "uuid": "*", + "lambdaPurpose": "*", + "timeout": "*", + "code": "*", + "handler": "*", + "runtime": "*" + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addMetadata": [ + "*", + true + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addMetadata": [ + "*", + "*" + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/LatestNodeRuntimeMap": [ + { + "type": "aws:cdk:logicalId", + "data": "LatestNodeRuntimeMap" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "timeout": "*", + "code": "*", + "handler": "*", + "runtime": "*" + } + }, + { + "type": "aws:cdk:is-custom-resource-handler-singleton", + "data": true + }, + { + "type": "aws:cdk:is-custom-resource-handler-runtime-family", + "data": 0 + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "assumedBy": { + "principalAccount": "*", + "assumeRoleAction": "*" + }, + "managedPolicies": [ + { + "managedPolicyArn": "*" + } + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/ImportServiceRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/DefaultPolicy": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRoleDefaultPolicy63AE5FEF" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "definitionBody": "*", + "timeout": "*", + "comment": "*" + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToRolePolicy": [ + {} + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "assumedBy": { + "principalAccount": "*", + "assumeRoleAction": "*" + } + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addToPrincipalPolicy": [ + {} + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachInlinePolicy": [ + "*" + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/ImportRole": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TestStateMachineRole2476F720" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/DefaultPolicy": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "attachToRole": [ + "*" + ] + } + }, + { + "type": "aws:cdk:analytics:method", + "data": { + "addStatements": [ + {} + ] + } + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TestStateMachineRoleDefaultPolicyB28F488D" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TestStateMachine3C216BE3" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/Exports/Output{\"Ref\":\"TestStateMachine3C216BE3\"}": [ + { + "type": "aws:cdk:logicalId", + "data": "ExportsOutputRefTestStateMachine3C216BE323AC47AE" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-stepfunctions-call-aws-service-cross-region-lambda-integ" + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegTestDefaultTestDeployAssertE3E7D2A4.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegTestDefaultTestDeployAssertE3E7D2A4": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegTestDefaultTestDeployAssertE3E7D2A4.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}/aebbf74f08c89a84f0c1281c47960cfea0ea5866ecdd510ffc2ea8ecc2eace7d.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegTestDefaultTestDeployAssertE3E7D2A4.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": [ + "aws-stepfunctions-call-aws-service-cross-region-lambda-integ", + "IntegTestDefaultTestDeployAssertE3E7D2A4.assets" + ], + "metadata": { + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/Default": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": "*" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F" + } + ], + "/IntegTest/DefaultTest/DeployAssert/LatestNodeRuntimeMap": [ + { + "type": "aws:cdk:logicalId", + "data": "LatestNodeRuntimeMap" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/Default": [ + { + "type": "aws:cdk:analytics:construct", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": "*" + }, + { + "type": "aws:cdk:analytics:method", + "data": "*" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/IsCompleteProvider/Invoke": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForIsCompleteProviderInvokeEF8ACA63" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/TimeoutProvider/Invoke": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForTimeoutProviderInvokeFCAFDA76" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForRoleD9C2DF7E" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11cWaitForEDC8A739" + } + ], + "/IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/AssertionResults": [ + { + "type": "aws:cdk:logicalId", + "data": "AssertionResultsAwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction76b3e830a873425f8453eddd85c86925Role918961BB" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction76b3e830a873425f8453eddd85c86925Handler81461ECE" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aRoleB84BD8CE" + } + ], + "/IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41aHandlerADF3E6EA" + } + ], + "/IntegTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "IntegTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + }, + "minimumCliVersion": "2.1019.2" +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/tree.json new file mode 100644 index 0000000000000..e9e98aa9b62f1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.js.snapshot/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-stepfunctions-call-aws-service-cross-region-lambda-integ":{"id":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"TargetLambda":{"id":"TargetLambda","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda","constructInfo":{"fqn":"aws-cdk-lib.aws_lambda.Function","version":"0.0.0","metadata":[{"runtime":"*","handler":"*","code":"*","description":"*"}]},"children":{"ServiceRole":{"id":"ServiceRole","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Role","version":"0.0.0","metadata":[{"assumedBy":{"principalAccount":"*","assumeRoleAction":"*"},"managedPolicies":[{"managedPolicyArn":"*"}]}]},"children":{"ImportServiceRole":{"id":"ImportServiceRole","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole/ImportServiceRole","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":["*"]}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/ServiceRole/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnRole","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::IAM::Role","aws:cdk:cloudformation:props":{"assumeRolePolicyDocument":{"Statement":[{"Action":"sts:AssumeRole","Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"}}],"Version":"2012-10-17"},"managedPolicyArns":[{"Fn::Join":["",["arn:",{"Ref":"AWS::Partition"},":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]]}]}}}}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TargetLambda/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_lambda.CfnFunction","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Lambda::Function","aws:cdk:cloudformation:props":{"code":{"zipFile":"\n exports.handler = async (event) => {\n console.log('Target Lambda received event:', JSON.stringify(event, null, 2));\n \n // Return a JSON response that should be properly serialized\n return {\n statusCode: 200,\n body: {\n status: 'success',\n message: 'Hello from target Lambda',\n receivedData: event\n }\n };\n };\n "},"description":"Target Lambda function for CallAwsServiceCrossRegion testing","handler":"index.handler","role":{"Fn::GetAtt":["TargetLambdaServiceRole567EC23E","Arn"]},"runtime":"nodejs18.x"}}}}},"CrossRegionLambdaInvoke":{"id":"CrossRegionLambdaInvoke","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionLambdaInvoke","constructInfo":{"fqn":"aws-cdk-lib.aws_stepfunctions_tasks.CallAwsServiceCrossRegion","version":"0.0.0"},"children":{"Handler":{"id":"Handler","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionLambdaInvoke/Handler","constructInfo":{"fqn":"aws-cdk-lib.aws_lambda.SingletonFunction","version":"0.0.0","metadata":[{"uuid":"*","lambdaPurpose":"*","timeout":"*","code":"*","handler":"*","runtime":"*"},{"addMetadata":["*",true]},{"addMetadata":["*","*"]}]}}}},"LatestNodeRuntimeMap":{"id":"LatestNodeRuntimeMap","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/LatestNodeRuntimeMap","constructInfo":{"fqn":"aws-cdk-lib.CfnMapping","version":"0.0.0"}},"CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e":{"id":"CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e","constructInfo":{"fqn":"aws-cdk-lib.aws_lambda.Function","version":"0.0.0","metadata":[{"timeout":"*","code":"*","handler":"*","runtime":"*"}]},"children":{"ServiceRole":{"id":"ServiceRole","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Role","version":"0.0.0","metadata":[{"assumedBy":{"principalAccount":"*","assumeRoleAction":"*"},"managedPolicies":[{"managedPolicyArn":"*"}]},{"addToPrincipalPolicy":[{}]},{"attachInlinePolicy":["*"]},{"attachInlinePolicy":["*"]}]},"children":{"ImportServiceRole":{"id":"ImportServiceRole","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/ImportServiceRole","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":["*"]}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnRole","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::IAM::Role","aws:cdk:cloudformation:props":{"assumeRolePolicyDocument":{"Statement":[{"Action":"sts:AssumeRole","Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"}}],"Version":"2012-10-17"},"managedPolicyArns":[{"Fn::Join":["",["arn:",{"Ref":"AWS::Partition"},":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]]}]}}},"DefaultPolicy":{"id":"DefaultPolicy","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/DefaultPolicy","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Policy","version":"0.0.0","metadata":["*",{"attachToRole":["*"]},{"attachToRole":["*"]},{"addStatements":[{}]}]},"children":{"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/ServiceRole/DefaultPolicy/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnPolicy","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::IAM::Policy","aws:cdk:cloudformation:props":{"policyDocument":{"Statement":[{"Action":"lambda:InvokeFunction","Effect":"Allow","Resource":{"Fn::GetAtt":["TargetLambdaE6C763FE","Arn"]}}],"Version":"2012-10-17"},"policyName":"CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRoleDefaultPolicy63AE5FEF","roles":[{"Ref":"CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520"}]}}}}}}},"Code":{"id":"Code","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Code","constructInfo":{"fqn":"aws-cdk-lib.aws_s3_assets.Asset","version":"0.0.0"},"children":{"Stage":{"id":"Stage","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Code/Stage","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"AssetBucket":{"id":"AssetBucket","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Code/AssetBucket","constructInfo":{"fqn":"aws-cdk-lib.aws_s3.BucketBase","version":"0.0.0","metadata":[]}}}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7e/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_lambda.CfnFunction","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Lambda::Function","aws:cdk:cloudformation:props":{"code":{"s3Bucket":{"Fn::Sub":"cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"},"s3Key":"e1c20a4808d556faa2fc55b65ebe08053d2625201f06e4dcf4c10f0dc1dde80e.zip"},"handler":"index.handler","role":{"Fn::GetAtt":["CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eServiceRole5D981520","Arn"]},"runtime":{"Fn::FindInMap":["LatestNodeRuntimeMap",{"Ref":"AWS::Region"},"value"]},"timeout":30}}}}},"TestStateMachine":{"id":"TestStateMachine","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine","constructInfo":{"fqn":"aws-cdk-lib.aws_stepfunctions.StateMachine","version":"0.0.0","metadata":[{"definitionBody":"*","timeout":"*","comment":"*"},{"addToRolePolicy":[{}]}]},"children":{"Role":{"id":"Role","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Role","version":"0.0.0","metadata":[{"assumedBy":{"principalAccount":"*","assumeRoleAction":"*"}},{"addToPrincipalPolicy":[{}]},{"attachInlinePolicy":["*"]},{"attachInlinePolicy":["*"]}]},"children":{"ImportRole":{"id":"ImportRole","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/ImportRole","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":["*"]}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnRole","version":"0.0.0"},"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"}}}},"DefaultPolicy":{"id":"DefaultPolicy","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/DefaultPolicy","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.Policy","version":"0.0.0","metadata":["*",{"attachToRole":["*"]},{"attachToRole":["*"]},{"addStatements":[{}]}]},"children":{"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Role/DefaultPolicy/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_iam.CfnPolicy","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::IAM::Policy","aws:cdk:cloudformation:props":{"policyDocument":{"Statement":[{"Action":"lambda:InvokeFunction","Effect":"Allow","Resource":[{"Fn::GetAtt":["CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F","Arn"]},{"Fn::Join":["",[{"Fn::GetAtt":["CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F","Arn"]},":*"]]}]}],"Version":"2012-10-17"},"policyName":"TestStateMachineRoleDefaultPolicyB28F488D","roles":[{"Ref":"TestStateMachineRole2476F720"}]}}}}}}},"Resource":{"id":"Resource","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/TestStateMachine/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_stepfunctions.CfnStateMachine","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::StepFunctions::StateMachine","aws:cdk:cloudformation:props":{"definitionString":{"Fn::Join":["",["{\"StartAt\":\"CrossRegionLambdaInvoke\",\"States\":{\"CrossRegionLambdaInvoke\":{\"QueryLanguage\":\"JSONata\",\"End\":true,\"Retry\":[{\"ErrorEquals\":[\"Lambda.ClientExecutionTimeoutException\",\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Arguments\":{\"region\":\"us-east-1\",\"action\":\"invoke\",\"service\":\"lambda\",\"parameters\":{\"FunctionName\":\"",{"Fn::GetAtt":["TargetLambdaE6C763FE","Arn"]},"\",\"Payload\":\"{\\\"hello\\\":\\\"world\\\",\\\"testData\\\":\\\"reproduction\\\"}\"}},\"Resource\":\"",{"Fn::GetAtt":["CrossRegionAwsSdk8a0c93f3dbef4b71ac137aaf2048ce7eF7430F4F","Arn"]},"\"}},\"TimeoutSeconds\":300,\"Comment\":\"State machine to reproduce issue 34768 - CallAwsServiceCrossRegion byte array bug\"}"]]},"roleArn":{"Fn::GetAtt":["TestStateMachineRole2476F720","Arn"]}}}}}},"Exports":{"id":"Exports","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/Exports","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"},"children":{"Output{\"Ref\":\"TestStateMachine3C216BE3\"}":{"id":"Output{\"Ref\":\"TestStateMachine3C216BE3\"}","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/Exports/Output{\"Ref\":\"TestStateMachine3C216BE3\"}","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-stepfunctions-call-aws-service-cross-region-lambda-integ/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"IntegTest":{"id":"IntegTest","path":"IntegTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"IntegTest/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"IntegTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"IntegTest/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa":{"id":"AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AwsApiCall","version":"0.0.0"},"children":{"SdkProvider":{"id":"SdkProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/SdkProvider","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AssertionsProvider","version":"0.0.0"},"children":{"AssertionsProvider":{"id":"AssertionsProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/SdkProvider/AssertionsProvider","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}},"Default":{"id":"Default","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/Default","constructInfo":{"fqn":"aws-cdk-lib.CustomResource","version":"0.0.0","metadata":["*","*","*"]},"children":{"Default":{"id":"Default","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsstartExecution35b0a9d12ae4d5363f5b001a832be9fa/Default/Default","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}}}},"SingletonFunction1488541a7b23466481b69b4408076b81":{"id":"SingletonFunction1488541a7b23466481b69b4408076b81","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"},"children":{"Staging":{"id":"Staging","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Staging","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"Role":{"id":"Role","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Handler":{"id":"Handler","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"LatestNodeRuntimeMap":{"id":"LatestNodeRuntimeMap","path":"IntegTest/DefaultTest/DeployAssert/LatestNodeRuntimeMap","constructInfo":{"fqn":"aws-cdk-lib.CfnMapping","version":"0.0.0"}},"AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c":{"id":"AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AwsApiCall","version":"0.0.0"},"children":{"SdkProvider":{"id":"SdkProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/SdkProvider","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AssertionsProvider","version":"0.0.0"},"children":{"AssertionsProvider":{"id":"AssertionsProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/SdkProvider/AssertionsProvider","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}},"Default":{"id":"Default","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/Default","constructInfo":{"fqn":"aws-cdk-lib.CustomResource","version":"0.0.0","metadata":["*","*","*"]},"children":{"Default":{"id":"Default","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/Default/Default","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"WaitFor":{"id":"WaitFor","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.WaiterStateMachine","version":"0.0.0"},"children":{"IsCompleteProvider":{"id":"IsCompleteProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/IsCompleteProvider","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AssertionsProvider","version":"0.0.0"},"children":{"AssertionsProvider":{"id":"AssertionsProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/IsCompleteProvider/AssertionsProvider","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"Invoke":{"id":"Invoke","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/IsCompleteProvider/Invoke","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"TimeoutProvider":{"id":"TimeoutProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/TimeoutProvider","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.AssertionsProvider","version":"0.0.0"},"children":{"AssertionsProvider":{"id":"AssertionsProvider","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/TimeoutProvider/AssertionsProvider","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"Invoke":{"id":"Invoke","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/TimeoutProvider/Invoke","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"Role":{"id":"Role","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Resource":{"id":"Resource","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/WaitFor/Resource","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"AssertionResults":{"id":"AssertionResults","path":"IntegTest/DefaultTest/DeployAssert/AwsApiCallStepFunctionsdescribeExecutionc1260931b5d4e71b1ac6f9bbc15dd11c/AssertionResults","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}}}},"SingletonFunction76b3e830a873425f8453eddd85c86925":{"id":"SingletonFunction76b3e830a873425f8453eddd85c86925","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"},"children":{"Staging":{"id":"Staging","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925/Staging","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"Role":{"id":"Role","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Handler":{"id":"Handler","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction76b3e830a873425f8453eddd85c86925/Handler","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a":{"id":"SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"},"children":{"Staging":{"id":"Staging","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a/Staging","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"Role":{"id":"Role","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Handler":{"id":"Handler","path":"IntegTest/DefaultTest/DeployAssert/SingletonFunction5c1898e096fb4e3e95d5f6c67f3ce41a/Handler","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"IntegTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"IntegTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.ts new file mode 100644 index 0000000000000..b2e8a7188126a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/lambda/integ.call-aws-service-cross-region-lambda.ts @@ -0,0 +1,97 @@ +import * as cdk from 'aws-cdk-lib'; +import * as lambda from 'aws-cdk-lib/aws-lambda'; +import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks'; +import { ExpectedResult, IntegTest, Match } from '@aws-cdk/integ-tests-alpha'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; + +class TestStack extends cdk.Stack { + public readonly stateMachine: sfn.StateMachine; + constructor(scope: cdk.App, id: string, props: cdk.StackProps = {}) { + super(scope, id, props); + // Create a target Lambda function that returns JSON response + const targetLambda = new lambda.Function(this, 'TargetLambda', { + runtime: lambda.Runtime.NODEJS_18_X, + handler: 'index.handler', + code: lambda.Code.fromInline(` + exports.handler = async (event) => { + console.log('Target Lambda received event:', JSON.stringify(event, null, 2)); + + // Return a JSON response that should be properly serialized + return { + statusCode: 200, + body: { + status: 'success', + message: 'Hello from target Lambda', + receivedData: event + } + }; + }; + `), + description: 'Target Lambda function for CallAwsServiceCrossRegion testing', + }); + + // Create a cross-region Lambda invoke task using CallAwsServiceCrossRegion + const crossRegionInvokeTask = tasks.CallAwsServiceCrossRegion.jsonata(this, 'CrossRegionLambdaInvoke', { + service: 'lambda', + action: 'invoke', + region: 'us-east-1', + parameters: { + FunctionName: targetLambda.functionArn, + Payload: JSON.stringify({ + hello: 'world', + testData: 'reproduction', + }), + }, + iamResources: [targetLambda.functionArn], + iamAction: 'lambda:InvokeFunction', + }); + + // Create a Step Functions state machine to execute the cross-region task + this.stateMachine = new sfn.StateMachine(this, 'TestStateMachine', { + definitionBody: sfn.DefinitionBody.fromChainable(crossRegionInvokeTask), + timeout: cdk.Duration.minutes(5), + comment: 'State machine to reproduce issue 34768 - CallAwsServiceCrossRegion byte array bug', + }); + } +} + +const app = new cdk.App({ + postCliContext: { + '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false, + '@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy': false, + }, +}); + +const stack = new TestStack(app, 'aws-stepfunctions-call-aws-service-cross-region-lambda-integ'); + +const integ = new IntegTest(app, 'IntegTest', { + testCases: [stack], +}); + +// Start the Step Functions execution +const res = integ.assertions.awsApiCall('StepFunctions', 'startExecution', { + stateMachineArn: stack.stateMachine.stateMachineArn, +}); + +const executionArn = res.getAttString('executionArn'); + +// Describe the execution to see the output +const describe = integ.assertions + .awsApiCall('StepFunctions', 'describeExecution', { + executionArn, + }) + .expect(ExpectedResult.objectLike({ + status: 'SUCCEEDED', + })) + .waitForAssertions({ + totalTimeout: cdk.Duration.minutes(5), + interval: cdk.Duration.seconds(10), + }); + +// Verify that the output contains the expected Lambda response structure as JSON +// This ensures the response is properly serialized as JSON, not as byte array +describe.expect(ExpectedResult.objectLike({ + output: Match.stringLikeRegexp('.*"statusCode":200.*"status":"success".*"message":"Hello from target Lambda".*'), +})); + +app.synth(); diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/aws-stepfunctions-tasks/cross-region-aws-sdk-handler/index.ts b/packages/@aws-cdk/custom-resource-handlers/lib/aws-stepfunctions-tasks/cross-region-aws-sdk-handler/index.ts index 132348bcfb088..9cf4935ca647b 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/aws-stepfunctions-tasks/cross-region-aws-sdk-handler/index.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/aws-stepfunctions-tasks/cross-region-aws-sdk-handler/index.ts @@ -78,7 +78,20 @@ export const handler = async (event: Event) => { const command = new Command(event.parameters ?? {}); const res = await client.send(command); - return res; + // Special handling for Lambda invoke responses + if (res.Payload && (res.Payload instanceof Uint8Array || res.Payload instanceof Buffer)) { + try { + const payloadString = new TextDecoder().decode(res.Payload); + res.Payload = JSON.parse(payloadString); + } catch (error) { + // If parsing fails, keep as decoded string + res.Payload = new TextDecoder().decode(res.Payload); + } + } + + // Serialize the entire response to ensure all other binary data is handled + const serializedRes = JSON.stringify(res); + return JSON.parse(serializedRes); } catch (error) { console.error('Error: ', error); throw error; diff --git a/packages/@aws-cdk/custom-resource-handlers/test/aws-stepfunctions-tasks/cross-region-aws-sdk-handler.test.ts b/packages/@aws-cdk/custom-resource-handlers/test/aws-stepfunctions-tasks/cross-region-aws-sdk-handler.test.ts new file mode 100644 index 0000000000000..dd7bc4907f4fa --- /dev/null +++ b/packages/@aws-cdk/custom-resource-handlers/test/aws-stepfunctions-tasks/cross-region-aws-sdk-handler.test.ts @@ -0,0 +1,213 @@ +import { handler } from '../../lib/aws-stepfunctions-tasks/cross-region-aws-sdk-handler'; + +// Mock AWS SDK +const mockSend = jest.fn(); +jest.mock('@aws-sdk/client-lambda', () => ({ + LambdaClient: jest.fn().mockImplementation(() => ({ + send: mockSend, + })), + InvokeCommand: jest.fn().mockImplementation((params) => params), +})); + +jest.mock('@aws-sdk/client-dynamodb', () => ({ + DynamoDBClient: jest.fn().mockImplementation(() => ({ + send: mockSend, + })), + ListTablesCommand: jest.fn().mockImplementation((params) => params), +})); + +jest.mock('@aws-sdk/client-sts', () => ({ + STSClient: jest.fn().mockImplementation(() => ({ + send: jest.fn(), + })), + AssumeRoleCommand: jest.fn(), +})); + +describe('Cross-Region AWS SDK Handler - Lambda Payload Processing', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Lambda Invoke with Binary Payload Handling', () => { + test('should convert Uint8Array payload to JSON object', async () => { + // GIVEN - Lambda response with Uint8Array payload + const lambdaResponseJson = JSON.stringify({ + statusCode: 200, + body: { status: 'success', message: 'Hello from Lambda' }, + }); + const uint8ArrayPayload = new TextEncoder().encode(lambdaResponseJson); + + mockSend.mockResolvedValue({ + $metadata: { httpStatusCode: 200 }, + ExecutedVersion: '$LATEST', + Payload: uint8ArrayPayload, + StatusCode: 200, + }); + + const event = { + service: 'lambda', + action: 'invoke', + parameters: { + FunctionName: 'test-function', + Payload: JSON.stringify({ test: 'data' }), + }, + region: 'us-west-2', + endpoint: 'https://lambda.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN - Should return proper JSON instead of byte array + expect(result.Payload).toEqual({ + statusCode: 200, + body: { status: 'success', message: 'Hello from Lambda' }, + }); + expect(result.Payload).not.toHaveProperty('0'); // Should not be byte array + }); + + test('should handle Buffer payload', async () => { + // GIVEN - Lambda response with Buffer payload + const lambdaResponseJson = JSON.stringify({ result: 'buffer test' }); + const bufferPayload = Buffer.from(lambdaResponseJson, 'utf8'); + + mockSend.mockResolvedValue({ + $metadata: { httpStatusCode: 200 }, + Payload: bufferPayload, + StatusCode: 200, + }); + + const event = { + service: 'lambda', + action: 'invoke', + parameters: { FunctionName: 'test-function' }, + region: 'us-west-2', + endpoint: 'https://lambda.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN + expect(result.Payload).toEqual({ result: 'buffer test' }); + }); + + test('should handle malformed JSON payload gracefully', async () => { + // GIVEN - Malformed JSON in payload + const malformedJson = '{"incomplete": json'; + const malformedPayload = new TextEncoder().encode(malformedJson); + + mockSend.mockResolvedValue({ + $metadata: { httpStatusCode: 200 }, + Payload: malformedPayload, + StatusCode: 200, + }); + + const event = { + service: 'lambda', + action: 'invoke', + parameters: { FunctionName: 'test-function' }, + region: 'us-west-2', + endpoint: 'https://lambda.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN - Should fall back to decoded string + expect(result.Payload).toBe(malformedJson); + }); + + test('should not modify non-binary payload', async () => { + // GIVEN - Already parsed payload + mockSend.mockResolvedValue({ + $metadata: { httpStatusCode: 200 }, + Payload: { alreadyParsed: true }, + StatusCode: 200, + }); + + const event = { + service: 'lambda', + action: 'invoke', + parameters: { FunctionName: 'test-function' }, + region: 'us-west-2', + endpoint: 'https://lambda.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN + expect(result.Payload).toEqual({ alreadyParsed: true }); + }); + }); + + describe('Non-Lambda Services (Backward Compatibility)', () => { + test('should handle DynamoDB responses without Payload field', async () => { + // GIVEN - DynamoDB response + mockSend.mockResolvedValue({ + $metadata: { httpStatusCode: 200 }, + TableNames: ['table1', 'table2'], + LastEvaluatedTableName: 'table2', + }); + + const event = { + service: 'dynamodb', + action: 'listTables', + parameters: {}, + region: 'us-west-2', + endpoint: 'https://dynamodb.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN + expect(result.TableNames).toEqual(['table1', 'table2']); + expect(result.LastEvaluatedTableName).toBe('table2'); + }); + }); + + describe('Binary Payload Processing', () => { + test('should properly decode Lambda binary payloads to JSON', async () => { + // GIVEN - Lambda response with binary payload containing JSON + const originalLambdaResponse = { + statusCode: 200, + body: { status: 'success' }, + }; + + const uint8ArrayPayload = new TextEncoder().encode(JSON.stringify(originalLambdaResponse)); + + mockSend.mockResolvedValue({ + $metadata: { + httpStatusCode: 200, + requestId: '8f4f0076-f64e-42c5-a7bb-1b607a0a265f', + }, + ExecutedVersion: '$LATEST', + Payload: uint8ArrayPayload, + StatusCode: 200, + }); + + const event = { + service: 'lambda', + action: 'invoke', + parameters: { + FunctionName: 'test-function', + Payload: JSON.stringify({ input: 'test' }), + }, + region: 'us-west-2', + endpoint: 'https://lambda.us-west-2.amazonaws.com', + }; + + // WHEN + const result = await handler(event); + + // THEN - Should return proper JSON instead of byte arrays + expect(result.Payload).toEqual(originalLambdaResponse); + expect(result.Payload).not.toHaveProperty('0'); // Not byte array + expect(result.Payload).not.toHaveProperty('1'); // Not byte array + expect(result.Payload.statusCode).toBe(200); + expect(result.Payload.body.status).toBe('success'); + }); + }); +});