From a751eaa6ead5e817ac4e3c25a5de3611223e8059 Mon Sep 17 00:00:00 2001 From: Jerome Van Der Linden Date: Thu, 27 Oct 2022 17:15:31 +0200 Subject: [PATCH 1/7] fix idempotency when function timeouts --- powertools-idempotency/pom.xml | 1 + .../powertools/idempotency/Idempotency.java | 10 ++ .../idempotency/IdempotencyConfig.java | 15 ++- ...IdempotencyInconsistentStateException.java | 2 +- .../internal/IdempotencyHandler.java | 28 +++++- .../internal/IdempotentAspect.java | 19 +++- .../persistence/BasePersistenceStore.java | 17 ++-- .../idempotency/persistence/DataRecord.java | 22 ++++- .../persistence/DynamoDBPersistenceStore.java | 48 +++++++-- .../handlers/IdempotencyInternalFunction.java | 10 ++ .../internal/IdempotencyAspectTest.java | 87 ++++++++++++++-- .../persistence/BasePersistenceStoreTest.java | 47 +++++++-- .../DynamoDBPersistenceStoreTest.java | 99 ++++++++++++++++++- spotbugs-exclude.xml | 8 ++ 14 files changed, 371 insertions(+), 42 deletions(-) diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index 7ddc1e793..536ef0e9d 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -122,6 +122,7 @@ com.amazonaws aws-lambda-java-tests + test com.amazonaws diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Idempotency.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Idempotency.java index 1ff2ed47f..ce652791b 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Idempotency.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Idempotency.java @@ -65,6 +65,16 @@ public static Idempotency getInstance() { return Holder.instance; } + /** + * Can be used in a method which is not the handler to capture the Lambda context, + * to calculate the remaining time before the invocation times out. + * + * @param lambdaContext + */ + public static void registerLambdaContext(Context lambdaContext) { + getInstance().getConfig().setLambdaContext(lambdaContext); + } + /** * Acts like a builder that can be used to configure {@link Idempotency} * diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/IdempotencyConfig.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/IdempotencyConfig.java index 4089d3ed8..aeadfe033 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/IdempotencyConfig.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/IdempotencyConfig.java @@ -13,8 +13,10 @@ */ package software.amazon.lambda.powertools.idempotency; +import com.amazonaws.services.lambda.runtime.Context; import software.amazon.lambda.powertools.idempotency.internal.cache.LRUCache; +import java.security.MessageDigest; import java.time.Duration; /** @@ -28,6 +30,7 @@ public class IdempotencyConfig { private final String payloadValidationJMESPath; private final boolean throwOnNoIdempotencyKey; private final String hashFunction; + private Context lambdaContext; private IdempotencyConfig(String eventKeyJMESPath, String payloadValidationJMESPath, boolean throwOnNoIdempotencyKey, boolean useLocalCache, int localCacheMaxItems, long expirationInSeconds, String hashFunction) { this.localCacheMaxItems = localCacheMaxItems; @@ -71,12 +74,20 @@ public String getHashFunction() { /** * Create a builder that can be used to configure and create a {@link IdempotencyConfig}. * - * @return a new instance of {@link IdempotencyConfig.Builder} + * @return a new instance of {@link Builder} */ public static Builder builder() { return new Builder(); } + public void setLambdaContext(Context lambdaContext) { + this.lambdaContext = lambdaContext; + } + + public Context getLambdaContext() { + return lambdaContext; + } + public static class Builder { private int localCacheMaxItems = 256; @@ -203,7 +214,7 @@ public Builder withThrowOnNoIdempotencyKey() { /** * Function to use for calculating hashes, by default MD5. * - * @param hashFunction Can be any algorithm supported by {@link java.security.MessageDigest}, most commons are