From ecd737405f27a06a17400a1f6164c14a869a2f2d Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 24 Apr 2023 15:17:42 +0200 Subject: [PATCH] feat(lambda-event-sources): Add eventsourceMappingArn to IEventSourceMapping (#24991) Currently the eventsourceMappingArn (for example for SQS Lambda Trigger) needs to be constructed manually: `arn:aws:lambda:eu-west-1:ACCOUNT_ID:event-source-mapping:EVENTSOURCEMAPPINGID` With this change its no longer needed to construct it manually. The solution now exposes the `eventSourceMappingArn` on the `IEventSourceMapping`. The ARN is constructed by the individual components (`service, resource, resourceName/eventSourceMappingId` and `format`). I considered adding a static method `fromEventSourceMappingArn` to the `EventSourceMapping` class. Wasnt sure if it provides any value, but let me know if you think its a good Idea to add it. ~Sidenote: I had a bit of a struggle to build the project (during development I had a lot of heap memory issues). Additionally I wasnt able to execute the integration tests, I tried to follow https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md#running-integration-tests but either I make something wrong or the guide seems out of date? Would be great if I get some pointers in the right direction.~ Closes #24801 . ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/integ.dynamodb.js.snapshot/cdk.out | 2 +- .../integ.dynamodb.js.snapshot/integ.json | 2 +- .../lambda-event-source-dynamodb.assets.json | 6 +- ...lambda-event-source-dynamodb.template.json | 27 +++++++ .../integ.dynamodb.js.snapshot/manifest.json | 22 ++++-- .../test/integ.dynamodb.js.snapshot/tree.json | 78 +++++++++++++------ .../test/integ.dynamodb.ts | 9 ++- .../lambda-event-source-kinesis.assets.json | 4 +- .../lambda-event-source-kinesis.template.json | 27 +++++++ .../integ.kinesis.js.snapshot/manifest.json | 8 +- .../test/integ.kinesis.js.snapshot/tree.json | 8 ++ .../test/integ.kinesis.ts | 9 ++- .../test/integ.sqs.js.snapshot/cdk.out | 2 +- .../test/integ.sqs.js.snapshot/integ.json | 2 +- .../lambda-event-source-sqs.assets.json | 6 +- .../lambda-event-source-sqs.template.json | 27 +++++++ .../test/integ.sqs.js.snapshot/manifest.json | 22 ++++-- .../test/integ.sqs.js.snapshot/tree.json | 74 +++++++++++++----- .../test/integ.sqs.ts | 9 ++- .../aws-lambda-event-sources/README.md | 5 ++ .../aws-lambda-event-sources/lib/dynamodb.ts | 14 +++- .../aws-lambda-event-sources/lib/kafka.ts | 16 +++- .../aws-lambda-event-sources/lib/kinesis.ts | 14 +++- .../aws-lambda-event-sources/lib/sqs.ts | 12 +++ .../test/dynamo.test.ts | 44 ++++++++++- .../test/kafka.test.ts | 4 +- .../test/kinesis.test.ts | 32 +++++++- .../aws-lambda-event-sources/test/sqs.test.ts | 28 ++++++- .../aws-lambda/lib/event-source-mapping.ts | 24 +++++- .../test/event-source-mapping.test.ts | 1 + 30 files changed, 446 insertions(+), 92 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/cdk.out index 588d7b269d34f..7925065efbcc4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"31.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/integ.json index 6cc795f8e21db..2b1f95f95f250 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "31.0.0", "testCases": { "integ.dynamodb": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.assets.json index 8e91ae180357b..1cd776a531194 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "31.0.0", "files": { - "e143da2a8687914f63b1adc3553d6af9014851503b71a4e1d068416fd906061e": { + "3bd69e1fd092b2d77dfe5884db2c3213c0c79d892c1fef9c3e4d29fb7f33547e": { "source": { "path": "lambda-event-source-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "e143da2a8687914f63b1adc3553d6af9014851503b71a4e1d068416fd906061e.json", + "objectKey": "3bd69e1fd092b2d77dfe5884db2c3213c0c79d892c1fef9c3e4d29fb7f33547e.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.template.json index 62ea88a222ae6..d45a5feb3ca69 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/lambda-event-source-dynamodb.template.json @@ -130,6 +130,33 @@ "DeletionPolicy": "Delete" } }, + "Outputs": { + "OutputEventSourceMappingArn": { + "Value": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":event-source-mapping:", + { + "Ref": "FDynamoDBEventSourcelambdaeventsourcedynamodbT7967476AE652DA48" + } + ] + ] + } + } + }, "Parameters": { "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/manifest.json index d24ef1a826b9e..cc8a191ef2445 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "31.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "lambda-event-source-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e143da2a8687914f63b1adc3553d6af9014851503b71a4e1d068416fd906061e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/3bd69e1fd092b2d77dfe5884db2c3213c0c79d892c1fef9c3e4d29fb7f33547e.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -69,6 +63,12 @@ "data": "TD925BC7E" } ], + "/lambda-event-source-dynamodb/OutputEventSourceMappingArn": [ + { + "type": "aws:cdk:logicalId", + "data": "OutputEventSourceMappingArn" + } + ], "/lambda-event-source-dynamodb/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -83,6 +83,12 @@ ] }, "displayName": "lambda-event-source-dynamodb" + }, + "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-lambda-event-sources/test/integ.dynamodb.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/tree.json index 5041aaf168db3..2ecdb3cc12b4f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "lambda-event-source-dynamodb": { "id": "lambda-event-source-dynamodb", "path": "lambda-event-source-dynamodb", @@ -24,6 +16,14 @@ "id": "ServiceRole", "path": "lambda-event-source-dynamodb/F/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "lambda-event-source-dynamodb/F/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "lambda-event-source-dynamodb/F/ServiceRole/Resource", @@ -59,7 +59,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -106,19 +106,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -142,7 +142,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", "version": "0.0.0" } }, @@ -171,19 +171,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnEventSourceMapping", + "fqn": "aws-cdk-lib.aws_lambda.CfnEventSourceMapping", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.EventSourceMapping", + "fqn": "aws-cdk-lib.aws_lambda.EventSourceMapping", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.Function", + "fqn": "aws-cdk-lib.aws_lambda.Function", "version": "0.0.0" } }, @@ -219,7 +219,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-dynamodb.CfnTable", + "fqn": "aws-cdk-lib.aws_dynamodb.CfnTable", "version": "0.0.0" } }, @@ -227,26 +227,58 @@ "id": "ScalingRole", "path": "lambda-event-source-dynamodb/T/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-dynamodb.Table", + "fqn": "aws-cdk-lib.aws_dynamodb.Table", + "version": "0.0.0" + } + }, + "OutputEventSourceMappingArn": { + "id": "OutputEventSourceMappingArn", + "path": "lambda-event-source-dynamodb/OutputEventSourceMappingArn", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "lambda-event-source-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "lambda-event-source-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.270" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "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-lambda-event-sources/test/integ.dynamodb.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.ts index 12597ac4da723..87c10245dec94 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.dynamodb.ts @@ -17,12 +17,15 @@ class DynamoEventSourceTest extends cdk.Stack { stream: dynamodb.StreamViewType.NEW_IMAGE, removalPolicy: cdk.RemovalPolicy.DESTROY, }); - - fn.addEventSource(new DynamoEventSource(queue, { + const eventSource = new DynamoEventSource(queue, { batchSize: 5, startingPosition: lambda.StartingPosition.TRIM_HORIZON, tumblingWindow: cdk.Duration.seconds(60), - })); + }); + + fn.addEventSource(eventSource); + + new cdk.CfnOutput(this, 'OutputEventSourceMappingArn', { value: eventSource.eventSourceMappingArn }); } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.assets.json index 0da5246313c0f..16490c5fbf0fa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.assets.json @@ -1,7 +1,7 @@ { "version": "31.0.0", "files": { - "95e2148d1ebc26fd910572145857d4425136c06c8c3eccf43e585af4a0e73db7": { + "a93b796326a3eeeb540403c10cdf6cf3b003fe7da5e559e2182f0036ff06e342": { "source": { "path": "lambda-event-source-kinesis.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "95e2148d1ebc26fd910572145857d4425136c06c8c3eccf43e585af4a0e73db7.json", + "objectKey": "a93b796326a3eeeb540403c10cdf6cf3b003fe7da5e559e2182f0036ff06e342.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.template.json index 65bab762e2aca..3b1618b7d56c5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/lambda-event-source-kinesis.template.json @@ -145,6 +145,33 @@ ] } }, + "Outputs": { + "OutputEventSourceMappingArn": { + "Value": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":event-source-mapping:", + { + "Ref": "FKinesisEventSourcelambdaeventsourcekinesisQ645CE7DB2D6BCCF5" + } + ] + ] + } + } + }, "Parameters": { "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/manifest.json index ffa307d8ac971..780e31ab832b6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/manifest.json @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/95e2148d1ebc26fd910572145857d4425136c06c8c3eccf43e585af4a0e73db7.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a93b796326a3eeeb540403c10cdf6cf3b003fe7da5e559e2182f0036ff06e342.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -69,6 +69,12 @@ "data": "AwsCdkKinesisEncryptedStreamsUnsupportedRegions" } ], + "/lambda-event-source-kinesis/OutputEventSourceMappingArn": [ + { + "type": "aws:cdk:logicalId", + "data": "OutputEventSourceMappingArn" + } + ], "/lambda-event-source-kinesis/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/tree.json index b0ee4b1a0344b..162b1bdf53a4b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.js.snapshot/tree.json @@ -232,6 +232,14 @@ "version": "0.0.0" } }, + "OutputEventSourceMappingArn": { + "id": "OutputEventSourceMappingArn", + "path": "lambda-event-source-kinesis/OutputEventSourceMappingArn", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "lambda-event-source-kinesis/BootstrapVersion", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.ts index ca53f286111f4..3a0226e5f9022 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.kinesis.ts @@ -10,11 +10,14 @@ class KinesisEventSourceTest extends cdk.Stack { const fn = new TestFunction(this, 'F'); const stream = new kinesis.Stream(this, 'Q'); - - fn.addEventSource(new KinesisEventSource(stream, { + const eventSource = new KinesisEventSource(stream, { startingPosition: lambda.StartingPosition.TRIM_HORIZON, tumblingWindow: cdk.Duration.seconds(60), - })); + }); + + fn.addEventSource(eventSource); + + new cdk.CfnOutput(this, 'OutputEventSourceMappingArn', { value: eventSource.eventSourceMappingArn }); } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/cdk.out index 588d7b269d34f..7925065efbcc4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"31.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/integ.json index c25c010a831f1..b4c4e4c12a8ed 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "31.0.0", "testCases": { "integ.sqs": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.assets.json index 1204ef645747a..7084c00f081f0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "31.0.0", "files": { - "9c4572e84df4c12b2ef0b057a88c0514dff86c6f71cdc8b81467b9c4feb06737": { + "595d99c2b432adb98648c72d1b52415a1b1238ea1e7a309ad60e31ca0ec2cfba": { "source": { "path": "lambda-event-source-sqs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "9c4572e84df4c12b2ef0b057a88c0514dff86c6f71cdc8b81467b9c4feb06737.json", + "objectKey": "595d99c2b432adb98648c72d1b52415a1b1238ea1e7a309ad60e31ca0ec2cfba.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.template.json index 58a3cf1ba69a1..72db746a21d02 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/lambda-event-source-sqs.template.json @@ -104,6 +104,33 @@ "DeletionPolicy": "Delete" } }, + "Outputs": { + "OutputEventSourceMappingArn": { + "Value": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":event-source-mapping:", + { + "Ref": "FSqsEventSourcelambdaeventsourcesqsQ67DE9201754EC819" + } + ] + ] + } + } + }, "Parameters": { "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/manifest.json index 3fd5b27b52495..dc6435d2e303b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "31.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "lambda-event-source-sqs.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9c4572e84df4c12b2ef0b057a88c0514dff86c6f71cdc8b81467b9c4feb06737.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/595d99c2b432adb98648c72d1b52415a1b1238ea1e7a309ad60e31ca0ec2cfba.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -69,6 +63,12 @@ "data": "Q63C6E3AB" } ], + "/lambda-event-source-sqs/OutputEventSourceMappingArn": [ + { + "type": "aws:cdk:logicalId", + "data": "OutputEventSourceMappingArn" + } + ], "/lambda-event-source-sqs/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -83,6 +83,12 @@ ] }, "displayName": "lambda-event-source-sqs" + }, + "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-lambda-event-sources/test/integ.sqs.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/tree.json index c4a78fba69b2b..d581d82868357 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "lambda-event-source-sqs": { "id": "lambda-event-source-sqs", "path": "lambda-event-source-sqs", @@ -24,6 +16,14 @@ "id": "ServiceRole", "path": "lambda-event-source-sqs/F/ServiceRole", "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "lambda-event-source-sqs/F/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "lambda-event-source-sqs/F/ServiceRole/Resource", @@ -59,7 +59,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", + "fqn": "aws-cdk-lib.aws_iam.CfnRole", "version": "0.0.0" } }, @@ -103,19 +103,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Policy", + "fqn": "aws-cdk-lib.aws_iam.Policy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", + "fqn": "aws-cdk-lib.aws_iam.Role", "version": "0.0.0" } }, @@ -139,7 +139,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", "version": "0.0.0" } }, @@ -166,19 +166,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnEventSourceMapping", + "fqn": "aws-cdk-lib.aws_lambda.CfnEventSourceMapping", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.EventSourceMapping", + "fqn": "aws-cdk-lib.aws_lambda.EventSourceMapping", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.Function", + "fqn": "aws-cdk-lib.aws_lambda.Function", "version": "0.0.0" } }, @@ -194,26 +194,58 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-sqs.CfnQueue", + "fqn": "aws-cdk-lib.aws_sqs.CfnQueue", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-sqs.Queue", + "fqn": "aws-cdk-lib.aws_sqs.Queue", + "version": "0.0.0" + } + }, + "OutputEventSourceMappingArn": { + "id": "OutputEventSourceMappingArn", + "path": "lambda-event-source-sqs/OutputEventSourceMappingArn", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "lambda-event-source-sqs/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "lambda-event-source-sqs/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.270" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "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-lambda-event-sources/test/integ.sqs.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.ts index 7c74e50006cf0..ec47ad01df561 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-event-sources/test/integ.sqs.ts @@ -9,10 +9,13 @@ class SqsEventSourceTest extends cdk.Stack { const fn = new TestFunction(this, 'F'); const queue = new sqs.Queue(this, 'Q'); - - fn.addEventSource(new SqsEventSource(queue, { + const eventSource = new SqsEventSource(queue, { batchSize: 5, - })); + }); + + fn.addEventSource(eventSource); + + new cdk.CfnOutput(this, 'OutputEventSourceMappingArn', { value: eventSource.eventSourceMappingArn }); } } diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/README.md b/packages/aws-cdk-lib/aws-lambda-event-sources/README.md index 31faee0fe35cd..6cf23bbb519e5 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/README.md +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/README.md @@ -24,12 +24,17 @@ const eventSource = new SqsEventSource(queue); fn.addEventSource(eventSource); const eventSourceId = eventSource.eventSourceMappingId; +const eventSourceMappingArn = eventSource.eventSourceMappingArn; ``` The `eventSourceId` property contains the event source id. This will be a [token](https://docs.aws.amazon.com/cdk/latest/guide/tokens.html) that will resolve to the final value at the time of deployment. +The `eventSourceMappingArn` property contains the event source mapping ARN. This will be a +[token](https://docs.aws.amazon.com/cdk/latest/guide/tokens.html) that will resolve to the final value at the time of +deployment. + ## SQS Amazon Simple Queue Service (Amazon SQS) allows you to build asynchronous diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/dynamodb.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/dynamodb.ts index 50c4c008aa745..ec349f0ed0fa6 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/dynamodb.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/dynamodb.ts @@ -1,7 +1,7 @@ +import { StreamEventSource, StreamEventSourceProps } from './stream'; import * as dynamodb from '../../aws-dynamodb'; import * as lambda from '../../aws-lambda'; import { Names, Token } from '../../core'; -import { StreamEventSource, StreamEventSourceProps } from './stream'; export interface DynamoEventSourceProps extends StreamEventSourceProps { } @@ -11,6 +11,7 @@ export interface DynamoEventSourceProps extends StreamEventSourceProps { */ export class DynamoEventSource extends StreamEventSource { private _eventSourceMappingId?: string = undefined; + private _eventSourceMappingArn?: string = undefined; constructor(private readonly table: dynamodb.ITable, props: DynamoEventSourceProps) { super(props); @@ -31,6 +32,7 @@ export class DynamoEventSource extends StreamEventSource { this.enrichMappingOptions({ eventSourceArn: this.table.tableStreamArn }), ); this._eventSourceMappingId = eventSourceMapping.eventSourceMappingId; + this._eventSourceMappingArn = eventSourceMapping.eventSourceMappingArn; this.table.grantStreamRead(target); } @@ -44,4 +46,14 @@ export class DynamoEventSource extends StreamEventSource { } return this._eventSourceMappingId; } + + /** + * The ARN for this EventSourceMapping + */ + public get eventSourceMappingArn(): string { + if (!this._eventSourceMappingArn) { + throw new Error('DynamoEventSource is not yet bound to an event source mapping'); + } + return this._eventSourceMappingArn; + } } diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kafka.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kafka.ts index 815824bed4cf8..3fea49565b186 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kafka.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kafka.ts @@ -1,11 +1,11 @@ +import { Construct } from 'constructs'; +import { StreamEventSource, BaseStreamEventSourceProps } from './stream'; import { ISecurityGroup, IVpc, SubnetSelection } from '../../aws-ec2'; import * as iam from '../../aws-iam'; import * as lambda from '../../aws-lambda'; import * as secretsmanager from '../../aws-secretsmanager'; import { Stack, Names } from '../../core'; import { md5hash } from '../../core/lib/helpers-internal'; -import { Construct } from 'constructs'; -import { StreamEventSource, BaseStreamEventSourceProps } from './stream'; /** * Properties for a Kafka event source @@ -118,6 +118,7 @@ export class ManagedKafkaEventSource extends StreamEventSource { // This is to work around JSII inheritance problems private innerProps: ManagedKafkaEventSourceProps; private _eventSourceMappingId?: string = undefined; + private _eventSourceMappingArn?: string = undefined; constructor(props: ManagedKafkaEventSourceProps) { super(props); @@ -137,6 +138,7 @@ export class ManagedKafkaEventSource extends StreamEventSource { ); this._eventSourceMappingId = eventSourceMapping.eventSourceMappingId; + this._eventSourceMappingArn = eventSourceMapping.eventSourceMappingArn; if (this.innerProps.secret !== undefined) { this.innerProps.secret.grantRead(target); @@ -176,6 +178,16 @@ export class ManagedKafkaEventSource extends StreamEventSource { } return this._eventSourceMappingId; } + + /** + * The ARN for this EventSourceMapping + */ + public get eventSourceMappingArn(): string { + if (!this._eventSourceMappingArn) { + throw new Error('KafkaEventSource is not yet bound to an event source mapping'); + } + return this._eventSourceMappingArn; + } } /** diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kinesis.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kinesis.ts index 79888c1c7753f..aa0fccd26de66 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kinesis.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/kinesis.ts @@ -1,7 +1,7 @@ +import { StreamEventSource, StreamEventSourceProps } from './stream'; import * as kinesis from '../../aws-kinesis'; import * as lambda from '../../aws-lambda'; import * as cdk from '../../core'; -import { StreamEventSource, StreamEventSourceProps } from './stream'; export interface KinesisEventSourceProps extends StreamEventSourceProps { /** @@ -17,6 +17,7 @@ export interface KinesisEventSourceProps extends StreamEventSourceProps { */ export class KinesisEventSource extends StreamEventSource { private _eventSourceMappingId?: string = undefined; + private _eventSourceMappingArn?: string = undefined; private startingPositionTimestamp?: number; constructor(readonly stream: kinesis.IStream, props: KinesisEventSourceProps) { @@ -38,6 +39,7 @@ export class KinesisEventSource extends StreamEventSource { }), ); this._eventSourceMappingId = eventSourceMapping.eventSourceMappingId; + this._eventSourceMappingArn = eventSourceMapping.eventSourceMappingArn; this.stream.grantRead(target); @@ -58,4 +60,14 @@ export class KinesisEventSource extends StreamEventSource { } return this._eventSourceMappingId; } + + /** + * The ARN for this EventSourceMapping + */ + public get eventSourceMappingArn(): string { + if (!this._eventSourceMappingArn) { + throw new Error('KinesisEventSource is not yet bound to an event source mapping'); + } + return this._eventSourceMappingArn; + } } diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/sqs.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/sqs.ts index 2500bea2adbf6..ff23e77b6357f 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/lib/sqs.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/lib/sqs.ts @@ -64,6 +64,7 @@ export interface SqsEventSourceProps { */ export class SqsEventSource implements lambda.IEventSource { private _eventSourceMappingId?: string = undefined; + private _eventSourceMappingArn?: string = undefined; constructor(readonly queue: sqs.IQueue, private readonly props: SqsEventSourceProps = { }) { if (this.props.maxBatchingWindow !== undefined) { @@ -95,6 +96,7 @@ export class SqsEventSource implements lambda.IEventSource { filters: this.props.filters, }); this._eventSourceMappingId = eventSourceMapping.eventSourceMappingId; + this._eventSourceMappingArn = eventSourceMapping.eventSourceMappingArn; // only grant access if the lambda function has an IAM role // otherwise the IAM module will throw an error @@ -115,4 +117,14 @@ export class SqsEventSource implements lambda.IEventSource { } return this._eventSourceMappingId; } + + /** + * The ARN for this EventSourceMapping + */ + public get eventSourceMappingArn(): string { + if (!this._eventSourceMappingArn) { + throw new Error('SqsEventSource is not yet bound to an event source mapping'); + } + return this._eventSourceMappingArn; + } } diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/test/dynamo.test.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/test/dynamo.test.ts index 816fc923f8a1a..d022717094425 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/test/dynamo.test.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/test/dynamo.test.ts @@ -1,9 +1,9 @@ +import { TestFunction } from './test-function'; import { Template } from '../../assertions'; import * as dynamodb from '../../aws-dynamodb'; import * as lambda from '../../aws-lambda'; import * as sqs from '../../aws-sqs'; import * as cdk from '../../core'; -import { TestFunction } from './test-function'; import * as sources from '../lib'; /* eslint-disable quote-props */ @@ -375,6 +375,29 @@ describe('DynamoEventSource', () => { }); + test('contains eventSourceMappingArn after lambda binding', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new TestFunction(stack, 'Fn'); + const table = new dynamodb.Table(stack, 'T', { + partitionKey: { + name: 'id', + type: dynamodb.AttributeType.STRING, + }, + stream: dynamodb.StreamViewType.NEW_IMAGE, + }); + const eventSource = new sources.DynamoEventSource(table, { + startingPosition: lambda.StartingPosition.TRIM_HORIZON, + }); + + // WHEN + fn.addEventSource(eventSource); + + // THEN + expect(eventSource.eventSourceMappingArn).toBeDefined(); + + }); + test('eventSourceMappingId throws error before binding to lambda', () => { // GIVEN const stack = new cdk.Stack(); @@ -394,6 +417,25 @@ describe('DynamoEventSource', () => { }); + test('eventSourceMappingArn throws error before binding to lambda', () => { + // GIVEN + const stack = new cdk.Stack(); + const table = new dynamodb.Table(stack, 'T', { + partitionKey: { + name: 'id', + type: dynamodb.AttributeType.STRING, + }, + stream: dynamodb.StreamViewType.NEW_IMAGE, + }); + const eventSource = new sources.DynamoEventSource(table, { + startingPosition: lambda.StartingPosition.TRIM_HORIZON, + }); + + // WHEN/THEN + expect(() => eventSource.eventSourceMappingArn).toThrow(/DynamoEventSource is not yet bound to an event source mapping/); + + }); + test('specific retryAttempts', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/test/kafka.test.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/test/kafka.test.ts index 39e6731dfb3a9..12f896c00c3fb 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/test/kafka.test.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/test/kafka.test.ts @@ -1,9 +1,9 @@ +import { TestFunction } from './test-function'; import { Template, Match } from '../../assertions'; import { SecurityGroup, SubnetType, Vpc } from '../../aws-ec2'; import * as lambda from '../../aws-lambda'; import { Secret } from '../../aws-secretsmanager'; import * as cdk from '../../core'; -import { TestFunction } from './test-function'; import * as sources from '../lib'; describe('KafkaEventSource', () => { @@ -682,6 +682,7 @@ describe('KafkaEventSource', () => { // WHEN fn.addEventSource(mskEventMapping); expect(mskEventMapping.eventSourceMappingId).toBeDefined(); + expect(mskEventMapping.eventSourceMappingArn).toBeDefined(); const template = Template.fromStack(stack); template.hasResourceProperties('AWS::Lambda::EventSourceMapping', { @@ -707,6 +708,7 @@ describe('KafkaEventSource', () => { // WHEN fn.addEventSource(mskEventMapping); expect(mskEventMapping.eventSourceMappingId).toBeDefined(); + expect(mskEventMapping.eventSourceMappingArn).toBeDefined(); }); }); }); diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/test/kinesis.test.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/test/kinesis.test.ts index 03c065ebf9565..71b8c8da70e59 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/test/kinesis.test.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/test/kinesis.test.ts @@ -1,8 +1,8 @@ +import { TestFunction } from './test-function'; import { Template } from '../../assertions'; import * as kinesis from '../../aws-kinesis'; import * as lambda from '../../aws-lambda'; import * as cdk from '../../core'; -import { TestFunction } from './test-function'; import * as sources from '../lib'; /* eslint-disable quote-props */ @@ -232,6 +232,23 @@ describe('KinesisEventSource', () => { }); + test('contains eventSourceMappingArn after lambda binding', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new TestFunction(stack, 'Fn'); + const stream = new kinesis.Stream(stack, 'S'); + const eventSource = new sources.KinesisEventSource(stream, { + startingPosition: lambda.StartingPosition.TRIM_HORIZON, + }); + + // WHEN + fn.addEventSource(eventSource); + + // THEN + expect(eventSource.eventSourceMappingArn).toBeDefined(); + + }); + test('eventSourceMappingId throws error before binding to lambda', () => { // GIVEN const stack = new cdk.Stack(); @@ -245,6 +262,19 @@ describe('KinesisEventSource', () => { }); + test('eventSourceMappingArn throws error before binding to lambda', () => { + // GIVEN + const stack = new cdk.Stack(); + const stream = new kinesis.Stream(stack, 'S'); + const eventSource = new sources.KinesisEventSource(stream, { + startingPosition: lambda.StartingPosition.TRIM_HORIZON, + }); + + // WHEN/THEN + expect(() => eventSource.eventSourceMappingArn).toThrow(/KinesisEventSource is not yet bound to an event source mapping/); + + }); + test('event source disabled', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/test/sqs.test.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/test/sqs.test.ts index 63e102b534c2c..f03445287bf4a 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/test/sqs.test.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/test/sqs.test.ts @@ -1,10 +1,10 @@ +import { TestFunction } from './test-function'; import { Template } from '../../assertions'; import * as iam from '../../aws-iam'; import * as lambda from '../../aws-lambda'; import * as sqs from '../../aws-sqs'; import * as cdk from '../../core'; import { App } from '../../core'; -import { TestFunction } from './test-function'; import * as sources from '../lib'; /* eslint-disable quote-props */ @@ -239,6 +239,21 @@ describe('SQSEventSource', () => { }); + test('contains eventSourceMappingArn after lambda binding', () => { + // GIVEN + const stack = new cdk.Stack(); + const fn = new TestFunction(stack, 'Fn'); + const q = new sqs.Queue(stack, 'Q'); + const eventSource = new sources.SqsEventSource(q); + + // WHEN + fn.addEventSource(eventSource); + + // THEN + expect(eventSource.eventSourceMappingArn).toBeDefined(); + + }); + test('eventSourceMappingId throws error before binding to lambda', () => { // GIVEN const stack = new cdk.Stack(); @@ -250,6 +265,17 @@ describe('SQSEventSource', () => { }); + test('eventSourceMappingArn throws error before binding to lambda', () => { + // GIVEN + const stack = new cdk.Stack(); + const q = new sqs.Queue(stack, 'Q'); + const eventSource = new sources.SqsEventSource(q); + + // WHEN/THEN + expect(() => eventSource.eventSourceMappingArn).toThrow(/SqsEventSource is not yet bound to an event source mapping/); + + }); + test('event source disabled', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/aws-cdk-lib/aws-lambda/lib/event-source-mapping.ts b/packages/aws-cdk-lib/aws-lambda/lib/event-source-mapping.ts index 7781032b1ee55..e0c0d7c63c889 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/event-source-mapping.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/event-source-mapping.ts @@ -1,8 +1,8 @@ -import * as cdk from '../../core'; import { Construct } from 'constructs'; import { IEventSourceDlq } from './dlq'; import { IFunction } from './function-base'; import { CfnEventSourceMapping } from './lambda.generated'; +import * as cdk from '../../core'; /** * The type of authentication protocol or the VPC components for your event source's SourceAccessConfiguration @@ -273,6 +273,11 @@ export interface IEventSourceMapping extends cdk.IResource { * @attribute */ readonly eventSourceMappingId: string; + + /** + * The ARN of the event source mapping (i.e. arn:aws:lambda:region:account-id:event-source-mapping/event-source-mapping-id) + */ + readonly eventSourceMappingArn: string; } /** @@ -293,13 +298,27 @@ export class EventSourceMapping extends cdk.Resource implements IEventSourceMapp * Import an event source into this stack from its event source id. */ public static fromEventSourceMappingId(scope: Construct, id: string, eventSourceMappingId: string): IEventSourceMapping { + const eventSourceMappingArn = EventSourceMapping.formatArn(scope, + eventSourceMappingId, + ); class Import extends cdk.Resource implements IEventSourceMapping { public readonly eventSourceMappingId = eventSourceMappingId; + public readonly eventSourceMappingArn = eventSourceMappingArn; } return new Import(scope, id); } + private static formatArn(scope: Construct, eventSourceMappingId: string): string { + return cdk.Stack.of(scope).formatArn({ + service: 'lambda', + resource: 'event-source-mapping', + resourceName: eventSourceMappingId, + arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, + }); + } + public readonly eventSourceMappingId: string; + public readonly eventSourceMappingArn: string; constructor(scope: Construct, id: string, props: EventSourceMappingProps) { super(scope, id); @@ -395,6 +414,7 @@ export class EventSourceMapping extends cdk.Resource implements IEventSourceMapp amazonManagedKafkaEventSourceConfig: props.eventSourceArn ? consumerGroupConfig : undefined, }); this.eventSourceMappingId = cfnEventSourceMapping.ref; + this.eventSourceMappingArn = EventSourceMapping.formatArn(this, this.eventSourceMappingId); } private validateKafkaConsumerGroupIdOrThrow(kafkaConsumerGroupId: string) { @@ -402,7 +422,7 @@ export class EventSourceMapping extends cdk.Resource implements IEventSourceMapp return; } - if (kafkaConsumerGroupId.length > 200 ||kafkaConsumerGroupId.length < 1) { + if (kafkaConsumerGroupId.length > 200 || kafkaConsumerGroupId.length < 1) { throw new Error('kafkaConsumerGroupId must be a valid string between 1 and 200 characters'); } diff --git a/packages/aws-cdk-lib/aws-lambda/test/event-source-mapping.test.ts b/packages/aws-cdk-lib/aws-lambda/test/event-source-mapping.test.ts index 14e945d1c4949..386967e1c3302 100644 --- a/packages/aws-cdk-lib/aws-lambda/test/event-source-mapping.test.ts +++ b/packages/aws-cdk-lib/aws-lambda/test/event-source-mapping.test.ts @@ -141,6 +141,7 @@ describe('event source mapping', () => { expect(imported.eventSourceMappingId).toEqual('14e0db71-5d35-4eb5-b481-8945cf9d10c2'); expect(imported.stack.stackName).toEqual('test-stack'); + expect(imported.eventSourceMappingArn.endsWith(':event-source-mapping:14e0db71-5d35-4eb5-b481-8945cf9d10c2')).toBeTruthy(); }); test('accepts if kafkaTopic is a parameter', () => {