Skip to content

Commit 99b90ff

Browse files
committed
Idempotency module example
1 parent 141cf68 commit 99b90ff

File tree

4 files changed

+131
-2
lines changed

4 files changed

+131
-2
lines changed

example/HelloWorldFunction/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ plugins{
44
}
55

66
repositories {
7+
mavenLocal()
78
mavenCentral()
89
}
910

@@ -15,8 +16,11 @@ dependencies {
1516
aspect 'software.amazon.lambda:powertools-parameters:1.10.2'
1617
aspect 'software.amazon.lambda:powertools-validation:1.10.2'
1718

19+
implementation 'software.amazon.lambda:powertools-idempotency:1.10.2'
20+
aspectpath 'software.amazon.lambda:powertools-idempotency:1.10.2'
21+
1822
implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
19-
implementation 'com.amazonaws:aws-lambda-java-events:3.1.0'
23+
implementation 'com.amazonaws:aws-lambda-java-events:3.11.0'
2024

2125
implementation 'org.apache.logging.log4j:log4j-api:2.16.0'
2226
implementation 'org.apache.logging.log4j:log4j-core:2.16.0'

example/HelloWorldFunction/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
<artifactId>powertools-sqs</artifactId>
4444
<version>1.10.2</version>
4545
</dependency>
46+
<dependency>
47+
<groupId>software.amazon.lambda</groupId>
48+
<artifactId>powertools-idempotency</artifactId>
49+
<version>1.10.2</version>
50+
</dependency>
4651
<dependency>
4752
<groupId>com.amazonaws</groupId>
4853
<artifactId>aws-lambda-java-core</artifactId>
@@ -51,7 +56,7 @@
5156
<dependency>
5257
<groupId>com.amazonaws</groupId>
5358
<artifactId>aws-lambda-java-events</artifactId>
54-
<version>3.1.0</version>
59+
<version>3.11.0</version>
5560
</dependency>
5661
<dependency>
5762
<groupId>org.apache.logging.log4j</groupId>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package helloworld;
2+
3+
import com.amazonaws.services.lambda.runtime.Context;
4+
import com.amazonaws.services.lambda.runtime.RequestHandler;
5+
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
6+
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
7+
import org.apache.logging.log4j.LogManager;
8+
import org.apache.logging.log4j.Logger;
9+
import software.amazon.lambda.powertools.idempotency.Idempotency;
10+
import software.amazon.lambda.powertools.idempotency.IdempotencyConfig;
11+
import software.amazon.lambda.powertools.idempotency.Idempotent;
12+
import software.amazon.lambda.powertools.idempotency.persistence.DynamoDBPersistenceStore;
13+
import software.amazon.lambda.powertools.utilities.JsonConfig;
14+
15+
import java.io.BufferedReader;
16+
import java.io.IOException;
17+
import java.io.InputStreamReader;
18+
import java.net.URL;
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import java.util.stream.Collectors;
22+
23+
public class AppIdempotency implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
24+
private final static Logger LOG = LogManager.getLogger();
25+
26+
public AppIdempotency() {
27+
// we need to initialize idempotency configuration before the handleRequest method is called
28+
Idempotency.config().withConfig(
29+
IdempotencyConfig.builder()
30+
.withEventKeyJMESPath("powertools_json(body).address")
31+
.withUseLocalCache()
32+
.build())
33+
.withPersistenceStore(
34+
DynamoDBPersistenceStore.builder()
35+
.withTableName("idempotency_table")
36+
.build()
37+
).configure();
38+
}
39+
40+
41+
/**
42+
* Try with:
43+
* <pre>
44+
* curl -X POST https://[REST-API-ID].execute-api.[REGION].amazonaws.com/Prod/helloidem/ -H "Content-Type: application/json" -d '{"address": "https://checkip.amazonaws.com"}'
45+
* </pre>
46+
* @param input
47+
* @param context
48+
* @return
49+
*/
50+
@Idempotent
51+
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
52+
Map<String, String> headers = new HashMap<>();
53+
54+
headers.put("Content-Type", "application/json");
55+
headers.put("Access-Control-Allow-Origin", "*");
56+
headers.put("Access-Control-Allow-Methods", "GET, OPTIONS");
57+
headers.put("Access-Control-Allow-Headers", "*");
58+
59+
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
60+
.withHeaders(headers);
61+
try {
62+
String address = JsonConfig.get().getObjectMapper().readTree(input.getBody()).get("address").asText();
63+
final String pageContents = this.getPageContents(address);
64+
String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);
65+
66+
LOG.debug("ip is {}", pageContents);
67+
return response
68+
.withStatusCode(200)
69+
.withBody(output);
70+
71+
} catch (IOException e) {
72+
return response
73+
.withBody("{}")
74+
.withStatusCode(500);
75+
}
76+
}
77+
78+
// we could actually also put the @Idempotent annotation here
79+
private String getPageContents(String address) throws IOException {
80+
URL url = new URL(address);
81+
try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) {
82+
return br.lines().collect(Collectors.joining(System.lineSeparator()));
83+
}
84+
}
85+
}

example/template.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ Resources:
8888
Path: /helloparams
8989
Method: get
9090

91+
IdempotencyTable:
92+
Type: AWS::Serverless::SimpleTable
93+
Properties:
94+
TableName: idempotency_table
95+
PrimaryKey:
96+
Name: id
97+
Type: String
98+
99+
HelloWorldIdempotentFunction:
100+
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
101+
Properties:
102+
CodeUri: HelloWorldFunction
103+
Handler: helloworld.AppIdempotency::handleRequest
104+
MemorySize: 512
105+
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
106+
Variables:
107+
POWERTOOLS_LOG_LEVEL: INFO
108+
AWS_ENDPOINT_DISCOVERY_ENABLED: false
109+
Tracing: Active
110+
Policies:
111+
- DynamoDBCrudPolicy:
112+
TableName: !Ref IdempotencyTable
113+
Events:
114+
HelloWorld:
115+
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
116+
Properties:
117+
Path: /helloidem
118+
Method: post
119+
91120
UserPwd:
92121
Type: AWS::SecretsManager::Secret
93122
Properties:
@@ -212,3 +241,9 @@ Outputs:
212241
Description: "Hello World Params Lambda Function ARN"
213242
Value: !GetAtt HelloWorldParamsFunction.Arn
214243

244+
HelloWorldIdempotencyApi:
245+
Description: "API Gateway endpoint URL for Prod stage for Hello World idempotency function"
246+
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/helloidem/"
247+
HelloWorldIdempotencyFunction:
248+
Description: "Hello World Idempotency Lambda Function ARN"
249+
Value: !GetAtt HelloWorldIdempotentFunction.Arn

0 commit comments

Comments
 (0)