Skip to content

Commit 665db74

Browse files
committed
Fix DynamoDB annotation snapshot tests and add assembly reference
1 parent 7662d09 commit 665db74

12 files changed

Lines changed: 568 additions & 6 deletions

File tree

Libraries/src/Amazon.Lambda.Annotations/DynamoDB/DynamoDBEventAttribute.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ public string ResourceName
3636
return Stream.Substring(1);
3737
}
3838

39-
var arnTokens = Stream.Split(new char[] { '/' }, 2);
40-
var tableName = arnTokens.Length > 1 ? arnTokens[0].Split(':').Last() : Stream;
41-
var sanitizedName = string.Join(string.Empty, tableName.Where(char.IsLetterOrDigit));
42-
return sanitizedName;
39+
// DynamoDB stream ARN format: arn:aws:dynamodb:region:account:table/TableName/stream/timestamp
40+
var arnParts = Stream.Split('/');
41+
if (arnParts.Length >= 2)
42+
{
43+
var tableName = arnParts[1];
44+
return string.Join(string.Empty, tableName.Where(char.IsLetterOrDigit));
45+
}
46+
return string.Join(string.Empty, Stream.Where(char.IsLetterOrDigit));
4347
}
4448
set => resourceName = value;
4549
}

Libraries/src/Amazon.Lambda.RuntimeSupport/Amazon.Lambda.RuntimeSupport.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="..\..\..\buildtools\common.props" />
44

55
<PropertyGroup>
6-
<TargetFrameworks>netstandard2.0;net6.0;net8.0;net9.0;net10.0;net11.0</TargetFrameworks>
6+
<TargetFrameworks>netstandard2.0;net6.0;net8.0;net9.0</TargetFrameworks>
77
<Version>1.14.2</Version>
88
<Description>Provides a bootstrap and Lambda Runtime API Client to help you to develop custom .NET Core Lambda Runtimes.</Description>
99
<AssemblyTitle>Amazon.Lambda.RuntimeSupport</AssemblyTitle>

Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="..\..\..\buildtools\common.props" />
44

55
<PropertyGroup>
6-
<TargetFrameworks>net8.0;net9.0;net10.0;net11.0</TargetFrameworks>
6+
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
77
<Version>1.0.1</Version>
88
<Description>Provides a Restore Hooks library to help you register before snapshot and after restore hooks.</Description>
99
<AssemblyTitle>SnapshotRestore.Registry</AssemblyTitle>

Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208
<ProjectReference Include="..\..\src\Amazon.Lambda.Annotations\Amazon.Lambda.Annotations.csproj" />
209209
<ProjectReference Include="..\..\src\Amazon.Lambda.APIGatewayEvents\Amazon.Lambda.APIGatewayEvents.csproj" />
210210
<ProjectReference Include="..\..\src\Amazon.Lambda.SQSEvents\Amazon.Lambda.SQSEvents.csproj" />
211+
<ProjectReference Include="..\..\src\Amazon.Lambda.DynamoDBEvents\Amazon.Lambda.DynamoDBEvents.csproj" />
211212
<!--
212213
We need to force using the .NET Standard 2.0 version because the source generator test framework will complain
213214
about using newer versions of System.Runtime then it can handle. This is not an issue in a end user scenario.

Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Amazon.Lambda.Core;
44
using Amazon.Lambda.RuntimeSupport;
55
using Amazon.Lambda.Serialization.SystemTextJson;
6+
using Amazon.Lambda.DynamoDBEvents;
67
using Amazon.Lambda.SQSEvents;
78
using Microsoft.CodeAnalysis;
89
using Microsoft.CodeAnalysis.CSharp;
@@ -58,6 +59,7 @@ public Test(ReferencesMode referencesMode = ReferencesMode.All, TargetFramework
5859
return solution.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(ILambdaContext).Assembly.Location))
5960
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(APIGatewayProxyRequest).Assembly.Location))
6061
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(SQSEvent).Assembly.Location))
62+
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(DynamoDBEvent).Assembly.Location))
6163
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(IServiceCollection).Assembly.Location))
6264
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(ServiceProvider).Assembly.Location))
6365
.AddMetadataReference(projectId, MetadataReference.CreateFromFile(typeof(RestApiAttribute).Assembly.Location))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// <auto-generated/>
2+
3+
using System;
4+
using System.Linq;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using System.IO;
9+
using Amazon.Lambda.Core;
10+
11+
namespace TestServerlessApp.DynamoDBEventExamples
12+
{
13+
public class ValidDynamoDBEvents_ProcessMessagesAsync_Generated
14+
{
15+
private readonly ValidDynamoDBEvents validDynamoDBEvents;
16+
private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer;
17+
18+
/// <summary>
19+
/// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment
20+
/// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the
21+
/// region the Lambda function is executed in.
22+
/// </summary>
23+
public ValidDynamoDBEvents_ProcessMessagesAsync_Generated()
24+
{
25+
SetExecutionEnvironment();
26+
validDynamoDBEvents = new ValidDynamoDBEvents();
27+
serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer();
28+
}
29+
30+
/// <summary>
31+
/// The generated Lambda function handler for <see cref="ProcessMessagesAsync(Amazon.Lambda.DynamoDBEvents.DynamoDBEvent)"/>
32+
/// </summary>
33+
/// <param name="__evnt__">The request object that will be processed by the Lambda function handler.</param>
34+
/// <returns>Result of the Lambda function execution</returns>
35+
public async System.Threading.Tasks.Task ProcessMessagesAsync(Amazon.Lambda.DynamoDBEvents.DynamoDBEvent __evnt__)
36+
{
37+
await validDynamoDBEvents.ProcessMessagesAsync(__evnt__);
38+
}
39+
40+
private static void SetExecutionEnvironment()
41+
{
42+
const string envName = "AWS_EXECUTION_ENV";
43+
44+
var envValue = new StringBuilder();
45+
46+
// If there is an existing execution environment variable add the annotations package as a suffix.
47+
if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)))
48+
{
49+
envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_");
50+
}
51+
52+
envValue.Append("lib/amazon-lambda-annotations#{ANNOTATIONS_ASSEMBLY_VERSION}");
53+
54+
Environment.SetEnvironmentVariable(envName, envValue.ToString());
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// <auto-generated/>
2+
3+
using System;
4+
using System.Linq;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using System.IO;
9+
using Amazon.Lambda.Core;
10+
11+
namespace TestServerlessApp.DynamoDBEventExamples
12+
{
13+
public class ValidDynamoDBEvents_ProcessMessages_Generated
14+
{
15+
private readonly ValidDynamoDBEvents validDynamoDBEvents;
16+
private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer;
17+
18+
/// <summary>
19+
/// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment
20+
/// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the
21+
/// region the Lambda function is executed in.
22+
/// </summary>
23+
public ValidDynamoDBEvents_ProcessMessages_Generated()
24+
{
25+
SetExecutionEnvironment();
26+
validDynamoDBEvents = new ValidDynamoDBEvents();
27+
serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer();
28+
}
29+
30+
/// <summary>
31+
/// The generated Lambda function handler for <see cref="ProcessMessages(Amazon.Lambda.DynamoDBEvents.DynamoDBEvent)"/>
32+
/// </summary>
33+
/// <param name="__evnt__">The request object that will be processed by the Lambda function handler.</param>
34+
/// <returns>Result of the Lambda function execution</returns>
35+
public void ProcessMessages(Amazon.Lambda.DynamoDBEvents.DynamoDBEvent __evnt__)
36+
{
37+
validDynamoDBEvents.ProcessMessages(__evnt__);
38+
}
39+
40+
private static void SetExecutionEnvironment()
41+
{
42+
const string envName = "AWS_EXECUTION_ENV";
43+
44+
var envValue = new StringBuilder();
45+
46+
// If there is an existing execution environment variable add the annotations package as a suffix.
47+
if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)))
48+
{
49+
envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_");
50+
}
51+
52+
envValue.Append("lib/amazon-lambda-annotations#{ANNOTATIONS_ASSEMBLY_VERSION}");
53+
54+
Environment.SetEnvironmentVariable(envName, envValue.ToString());
55+
}
56+
}
57+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
{
2+
"AWSTemplateFormatVersion": "2010-09-09",
3+
"Transform": "AWS::Serverless-2016-10-31",
4+
"Description": "This template is partially managed by Amazon.Lambda.Annotations (v{ANNOTATIONS_ASSEMBLY_VERSION}).",
5+
"Resources": {
6+
"TestServerlessAppDynamoDBEventExamplesValidDynamoDBEventsProcessMessagesGenerated": {
7+
"Type": "AWS::Serverless::Function",
8+
"Metadata": {
9+
"Tool": "Amazon.Lambda.Annotations",
10+
"SyncedEvents": [
11+
"MyTable",
12+
"MyTable2",
13+
"testTableEvent"
14+
],
15+
"SyncedEventProperties": {
16+
"MyTable": [
17+
"Stream",
18+
"StartingPosition",
19+
"BatchSize",
20+
"MaximumBatchingWindowInSeconds",
21+
"FilterCriteria.Filters"
22+
],
23+
"MyTable2": [
24+
"Stream",
25+
"StartingPosition",
26+
"Enabled"
27+
],
28+
"testTableEvent": [
29+
"Stream.Fn::GetAtt",
30+
"StartingPosition"
31+
]
32+
}
33+
},
34+
"Properties": {
35+
"MemorySize": 512,
36+
"Timeout": 30,
37+
"Policies": [
38+
"AWSLambdaBasicExecutionRole"
39+
],
40+
"PackageType": "Image",
41+
"ImageUri": ".",
42+
"ImageConfig": {
43+
"Command": [
44+
"TestProject::TestServerlessApp.DynamoDBEventExamples.ValidDynamoDBEvents_ProcessMessages_Generated::ProcessMessages"
45+
]
46+
},
47+
"Events": {
48+
"MyTable": {
49+
"Type": "DynamoDB",
50+
"Properties": {
51+
"Stream": "arn:aws:dynamodb:us-east-2:444455556666:table/MyTable/stream/2024-01-01T00:00:00",
52+
"StartingPosition": "LATEST",
53+
"BatchSize": 50,
54+
"MaximumBatchingWindowInSeconds": 2,
55+
"FilterCriteria": {
56+
"Filters": [
57+
{
58+
"Pattern": "My-Filter-1"
59+
},
60+
{
61+
"Pattern": "My-Filter-2"
62+
}
63+
]
64+
}
65+
}
66+
},
67+
"MyTable2": {
68+
"Type": "DynamoDB",
69+
"Properties": {
70+
"Stream": "arn:aws:dynamodb:us-east-2:444455556666:table/MyTable2/stream/2024-01-01T00:00:00",
71+
"StartingPosition": "TRIM_HORIZON",
72+
"Enabled": false
73+
}
74+
},
75+
"testTableEvent": {
76+
"Type": "DynamoDB",
77+
"Properties": {
78+
"Stream": {
79+
"Fn::GetAtt": [
80+
"testTable",
81+
"StreamArn"
82+
]
83+
},
84+
"StartingPosition": "LATEST"
85+
}
86+
}
87+
}
88+
}
89+
},
90+
"TestServerlessAppDynamoDBEventExamplesValidDynamoDBEventsProcessMessagesAsyncGenerated": {
91+
"Type": "AWS::Serverless::Function",
92+
"Metadata": {
93+
"Tool": "Amazon.Lambda.Annotations",
94+
"SyncedEvents": [
95+
"MyTable"
96+
],
97+
"SyncedEventProperties": {
98+
"MyTable": [
99+
"Stream",
100+
"StartingPosition"
101+
]
102+
}
103+
},
104+
"Properties": {
105+
"MemorySize": 512,
106+
"Timeout": 30,
107+
"Policies": [
108+
"AWSLambdaBasicExecutionRole"
109+
],
110+
"PackageType": "Image",
111+
"ImageUri": ".",
112+
"ImageConfig": {
113+
"Command": [
114+
"TestProject::TestServerlessApp.DynamoDBEventExamples.ValidDynamoDBEvents_ProcessMessagesAsync_Generated::ProcessMessagesAsync"
115+
]
116+
},
117+
"Events": {
118+
"MyTable": {
119+
"Type": "DynamoDB",
120+
"Properties": {
121+
"Stream": "arn:aws:dynamodb:us-east-2:444455556666:table/MyTable/stream/2024-01-01T00:00:00",
122+
"StartingPosition": "LATEST"
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}

Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,53 @@ public async Task VerifyValidSQSEvents()
13391339
}.RunAsync();
13401340
}
13411341

1342+
[Fact]
1343+
public async Task VerifyValidDynamoDBEvents()
1344+
{
1345+
var expectedTemplateContent = await ReadSnapshotContent(Path.Combine("Snapshots", "ServerlessTemplates", "dynamoDBEvents.template"));
1346+
var validDynamoDBEventsProcessMessagesGeneratedContent = await ReadSnapshotContent(Path.Combine("Snapshots", "DynamoDB", "ValidDynamoDBEvents_ProcessMessages_Generated.g.cs"));
1347+
var validDynamoDBEventsProcessMessagesAsyncGeneratedContent = await ReadSnapshotContent(Path.Combine("Snapshots", "DynamoDB", "ValidDynamoDBEvents_ProcessMessagesAsync_Generated.g.cs"));
1348+
1349+
await new VerifyCS.Test
1350+
{
1351+
TestState =
1352+
{
1353+
Sources =
1354+
{
1355+
(Path.Combine("TestServerlessApp", "PlaceholderClass.cs"), await File.ReadAllTextAsync(Path.Combine("TestServerlessApp", "PlaceholderClass.cs"))),
1356+
(Path.Combine("TestServerlessApp", "DynamoDBEventExamples", "ValidDynamoDBEvents.cs"), await File.ReadAllTextAsync(Path.Combine("TestServerlessApp", "DynamoDBEventExamples", "ValidDynamoDBEvents.cs.txt"))),
1357+
(Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"), await File.ReadAllTextAsync(Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"))),
1358+
(Path.Combine("Amazon.Lambda.Annotations", "DynamoDB", "DynamoDBEventAttribute.cs"), await File.ReadAllTextAsync(Path.Combine("Amazon.Lambda.Annotations", "DynamoDB", "DynamoDBEventAttribute.cs"))),
1359+
(Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"), await File.ReadAllTextAsync(Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"))),
1360+
},
1361+
GeneratedSources =
1362+
{
1363+
(
1364+
typeof(SourceGenerator.Generator),
1365+
"ValidDynamoDBEvents_ProcessMessages_Generated.g.cs",
1366+
SourceText.From(validDynamoDBEventsProcessMessagesGeneratedContent, Encoding.UTF8, SourceHashAlgorithm.Sha256)
1367+
),
1368+
(
1369+
typeof(SourceGenerator.Generator),
1370+
"ValidDynamoDBEvents_ProcessMessagesAsync_Generated.g.cs",
1371+
SourceText.From(validDynamoDBEventsProcessMessagesAsyncGeneratedContent, Encoding.UTF8, SourceHashAlgorithm.Sha256)
1372+
)
1373+
},
1374+
ExpectedDiagnostics =
1375+
{
1376+
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info)
1377+
.WithArguments("ValidDynamoDBEvents_ProcessMessages_Generated.g.cs", validDynamoDBEventsProcessMessagesGeneratedContent),
1378+
1379+
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info)
1380+
.WithArguments("ValidDynamoDBEvents_ProcessMessagesAsync_Generated.g.cs", validDynamoDBEventsProcessMessagesAsyncGeneratedContent),
1381+
1382+
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info)
1383+
.WithArguments($"TestServerlessApp{Path.DirectorySeparatorChar}serverless.template", expectedTemplateContent)
1384+
}
1385+
}
1386+
}.RunAsync();
1387+
}
1388+
13421389
[Fact]
13431390
public async Task ExceededMaximumHandlerLength()
13441391
{

0 commit comments

Comments
 (0)