Skip to content

Commit 17af703

Browse files
committed
end-to-end tests
1 parent 93441a9 commit 17af703

File tree

6 files changed

+397
-3
lines changed

6 files changed

+397
-3
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>software.amazon.lambda</groupId>
7+
<artifactId>e2e-test-handlers-parent</artifactId>
8+
<version>1.0.0</version>
9+
</parent>
10+
11+
<artifactId>e2e-test-handler-large-msg-idempotent</artifactId>
12+
<packaging>jar</packaging>
13+
<name>A Lambda function using Powertools for AWS Lambda (Java) idempotency with large messages</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>software.amazon.lambda</groupId>
18+
<artifactId>powertools-idempotency</artifactId>
19+
</dependency>
20+
<dependency>
21+
<groupId>software.amazon.lambda</groupId>
22+
<artifactId>powertools-large-messages</artifactId>
23+
</dependency>
24+
<dependency>
25+
<groupId>software.amazon.lambda</groupId>
26+
<artifactId>powertools-logging</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>com.amazonaws</groupId>
30+
<artifactId>aws-lambda-java-events</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.apache.logging.log4j</groupId>
34+
<artifactId>log4j-slf4j2-impl</artifactId>
35+
</dependency>
36+
37+
</dependencies>
38+
39+
<build>
40+
<plugins>
41+
<plugin>
42+
<groupId>dev.aspectj</groupId>
43+
<artifactId>aspectj-maven-plugin</artifactId>
44+
<configuration>
45+
<source>${maven.compiler.source}</source>
46+
<target>${maven.compiler.target}</target>
47+
<complianceLevel>${maven.compiler.target}</complianceLevel>
48+
<aspectLibraries>
49+
<aspectLibrary>
50+
<groupId>software.amazon.lambda</groupId>
51+
<artifactId>powertools-idempotency</artifactId>
52+
</aspectLibrary>
53+
<aspectLibrary>
54+
<groupId>software.amazon.lambda</groupId>
55+
<artifactId>powertools-large-messages</artifactId>
56+
</aspectLibrary>
57+
<aspectLibrary>
58+
<groupId>software.amazon.lambda</groupId>
59+
<artifactId>powertools-logging</artifactId>
60+
</aspectLibrary>
61+
</aspectLibraries>
62+
</configuration>
63+
<executions>
64+
<execution>
65+
<goals>
66+
<goal>compile</goal>
67+
</goals>
68+
</execution>
69+
</executions>
70+
</plugin>
71+
<plugin>
72+
<groupId>org.apache.maven.plugins</groupId>
73+
<artifactId>maven-shade-plugin</artifactId>
74+
</plugin>
75+
</plugins>
76+
</build>
77+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
15+
package software.amazon.lambda.powertools.e2e;
16+
17+
import com.amazonaws.services.lambda.runtime.Context;
18+
import com.amazonaws.services.lambda.runtime.RequestHandler;
19+
import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
20+
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
21+
import java.nio.charset.StandardCharsets;
22+
import java.time.Duration;
23+
import java.time.Instant;
24+
import java.time.format.DateTimeFormatter;
25+
import java.time.temporal.ChronoUnit;
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import java.util.TimeZone;
29+
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
30+
import software.amazon.awssdk.regions.Region;
31+
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
32+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
33+
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
34+
import software.amazon.awssdk.utils.BinaryUtils;
35+
import software.amazon.awssdk.utils.Md5Utils;
36+
import software.amazon.lambda.powertools.idempotency.Idempotency;
37+
import software.amazon.lambda.powertools.idempotency.IdempotencyConfig;
38+
import software.amazon.lambda.powertools.idempotency.IdempotencyKey;
39+
import software.amazon.lambda.powertools.idempotency.Idempotent;
40+
import software.amazon.lambda.powertools.idempotency.persistence.DynamoDBPersistenceStore;
41+
import software.amazon.lambda.powertools.largemessages.LargeMessage;
42+
import software.amazon.lambda.powertools.logging.Logging;
43+
44+
public class Function implements RequestHandler<SQSEvent, SQSBatchResponse> {
45+
46+
private static final String TABLE_FOR_ASYNC_TESTS = System.getenv("TABLE_FOR_ASYNC_TESTS");
47+
private final DynamoDbClient client;
48+
49+
public Function() {
50+
this(DynamoDbClient
51+
.builder()
52+
.httpClient(UrlConnectionHttpClient.builder().build())
53+
.region(Region.of(System.getenv("AWS_REGION")))
54+
.build());
55+
}
56+
57+
public Function(DynamoDbClient client) {
58+
this.client = client;
59+
Idempotency.config().withConfig(
60+
IdempotencyConfig.builder()
61+
.withExpiration(Duration.of(22, ChronoUnit.SECONDS))
62+
.withEventKeyJMESPath("body") // get the body of the message
63+
.build())
64+
.withPersistenceStore(
65+
DynamoDBPersistenceStore.builder()
66+
.withDynamoDbClient(client)
67+
.withTableName(System.getenv("IDEMPOTENCY_TABLE"))
68+
.build()
69+
).configure();
70+
}
71+
72+
@Logging(logEvent = true)
73+
public SQSBatchResponse handleRequest(SQSEvent event, Context context) {
74+
for (SQSEvent.SQSMessage message: event.getRecords()) {
75+
processRawMessage(message, context);
76+
}
77+
return SQSBatchResponse.builder().build();
78+
}
79+
80+
@Idempotent
81+
@LargeMessage(deleteS3Object = false)
82+
private String processRawMessage(@IdempotencyKey SQSEvent.SQSMessage sqsMessage, Context context) {
83+
String bodyMD5 = md5(sqsMessage.getBody());
84+
if (!sqsMessage.getMd5OfBody().equals(bodyMD5)) {
85+
throw new SecurityException(String.format("message digest does not match, expected %s, got %s", sqsMessage.getMd5OfBody(), bodyMD5));
86+
}
87+
88+
Instant now = Instant.now();
89+
Map<String, AttributeValue> item = new HashMap<>();
90+
item.put("functionName", AttributeValue.builder().s(context.getFunctionName()).build());
91+
item.put("id", AttributeValue.builder().s(sqsMessage.getMessageId()).build());
92+
item.put("bodyMD5", AttributeValue.builder().s(bodyMD5).build());
93+
item.put("now", AttributeValue.builder().n(String.valueOf(now.getEpochSecond())).build());
94+
item.put("bodySize", AttributeValue.builder().n(String.valueOf(sqsMessage.getBody().getBytes(StandardCharsets.UTF_8).length)).build());
95+
96+
client.putItem(PutItemRequest.builder().tableName(TABLE_FOR_ASYNC_TESTS).item(item).build());
97+
98+
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME.withZone(TimeZone.getTimeZone("UTC").toZoneId());
99+
return dtf.format(now);
100+
}
101+
102+
private String md5(String message) {
103+
return BinaryUtils.toHex(Md5Utils.computeMD5Hash(message.getBytes(StandardCharsets.UTF_8)));
104+
}
105+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Configuration>
3+
<Appenders>
4+
<Console name="JsonAppender" target="SYSTEM_OUT">
5+
<JsonTemplateLayout eventTemplateUri="classpath:LambdaJsonLayout.json" />
6+
</Console>
7+
</Appenders>
8+
<Loggers>
9+
<Root level="INFO">
10+
<AppenderRef ref="JsonAppender"/>
11+
</Root>
12+
<Logger name="JsonLogger" level="INFO" additivity="false">
13+
<AppenderRef ref="JsonAppender"/>
14+
</Logger>
15+
</Loggers>
16+
</Configuration>

powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/IdempotencyE2ET.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import static software.amazon.lambda.powertools.testutils.lambda.LambdaInvoker.invokeFunction;
1919

2020
import java.time.Year;
21-
import java.util.Collections;
2221
import java.util.Map;
2322
import java.util.UUID;
2423
import java.util.concurrent.TimeUnit;
@@ -42,7 +41,6 @@ public static void setup() {
4241
.testName(IdempotencyE2ET.class.getSimpleName())
4342
.pathToFunction("idempotency")
4443
.idempotencyTable("idempo" + random)
45-
.environmentVariables(Collections.singletonMap("IDEMPOTENCY_TABLE", "idempo" + random))
4644
.build();
4745
Map<String, String> outputs = infrastructure.deploy();
4846
functionName = outputs.get(FUNCTION_NAME_OUTPUT);

0 commit comments

Comments
 (0)