diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java new file mode 100644 index 000000000..fe30b4928 --- /dev/null +++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java @@ -0,0 +1,21 @@ +/* + * Copyright 2022 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package software.amazon.lambda.powertools.core.internal; + +public class LambdaConstants { + public static final String LAMBDA_FUNCTION_NAME_ENV = "AWS_LAMBDA_FUNCTION_NAME"; + public static final String AWS_REGION_ENV = "AWS_REGION"; + public static final String AWS_LAMBDA_INITIALIZATION_TYPE = "AWS_LAMBDA_INITIALIZATION_TYPE"; + public static final String ON_DEMAND = "on-demand"; +} diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Constants.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Constants.java index d8f7a9a13..28c6f58aa 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Constants.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/Constants.java @@ -14,7 +14,5 @@ package software.amazon.lambda.powertools.idempotency; public class Constants { - public static final String LAMBDA_FUNCTION_NAME_ENV = "AWS_LAMBDA_FUNCTION_NAME"; - public static final String AWS_REGION_ENV = "AWS_REGION"; public static final String IDEMPOTENCY_DISABLED_ENV = "POWERTOOLS_IDEMPOTENCY_DISABLED"; } diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java index 79db29f05..727405257 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java @@ -20,7 +20,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.utils.StringUtils; -import software.amazon.lambda.powertools.idempotency.Constants; import software.amazon.lambda.powertools.idempotency.IdempotencyConfig; import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemAlreadyExistsException; import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemNotFoundException; @@ -43,6 +42,8 @@ import java.util.Spliterator; import java.util.stream.StreamSupport; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.LAMBDA_FUNCTION_NAME_ENV; + /** * Persistence layer that will store the idempotency result. * Base implementation. See {@link DynamoDBPersistenceStore} for an implementation (default one) @@ -71,7 +72,7 @@ public abstract class BasePersistenceStore implements PersistenceStore { * @param functionName The name of the function being decorated */ public void configure(IdempotencyConfig config, String functionName) { - String funcEnv = System.getenv(Constants.LAMBDA_FUNCTION_NAME_ENV); + String funcEnv = System.getenv(LAMBDA_FUNCTION_NAME_ENV); this.functionName = funcEnv != null ? funcEnv : "testFunction"; if (!StringUtils.isEmpty(functionName)) { this.functionName += "." + functionName; diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/DynamoDBPersistenceStore.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/DynamoDBPersistenceStore.java index e48cb78e2..47ddf4c5c 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/DynamoDBPersistenceStore.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/DynamoDBPersistenceStore.java @@ -34,7 +34,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static software.amazon.lambda.powertools.idempotency.Constants.AWS_REGION_ENV; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.AWS_LAMBDA_INITIALIZATION_TYPE; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.AWS_REGION_ENV; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.LAMBDA_FUNCTION_NAME_ENV; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.ON_DEMAND; import static software.amazon.lambda.powertools.idempotency.persistence.DataRecord.Status.INPROGRESS; /** @@ -86,9 +89,17 @@ private DynamoDBPersistenceStore(String tableName, String idempotencyDisabledEnv = System.getenv().get(Constants.IDEMPOTENCY_DISABLED_ENV); if (idempotencyDisabledEnv == null || idempotencyDisabledEnv.equalsIgnoreCase("false")) { DynamoDbClientBuilder ddbBuilder = DynamoDbClient.builder() - .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .httpClient(UrlConnectionHttpClient.builder().build()) .region(Region.of(System.getenv(AWS_REGION_ENV))); + + // AWS_LAMBDA_INITIALIZATION_TYPE has two values on-demand and snap-start + // when using snap-start mode, the env var creds provider isn't used and causes a fatal error if set + // fall back to the default provider chain if the mode is anything other than on-demand. + String initializationType = System.getenv().get(AWS_LAMBDA_INITIALIZATION_TYPE); + if (initializationType != null && initializationType.equals(ON_DEMAND)) { + ddbBuilder.credentialsProvider(EnvironmentVariableCredentialsProvider.create()); + } + this.dynamoDbClient = ddbBuilder.build(); } else { // we do not want to create a DynamoDbClient if idempotency is disabled @@ -249,7 +260,7 @@ public static Builder builder() { * You can also set a custom {@link DynamoDbClient} for further tuning. */ public static class Builder { - private static final String funcEnv = System.getenv(Constants.LAMBDA_FUNCTION_NAME_ENV); + private static final String funcEnv = System.getenv(LAMBDA_FUNCTION_NAME_ENV); private String tableName; private String keyAttr = "id"; diff --git a/powertools-parameters/pom.xml b/powertools-parameters/pom.xml index 3232d01cf..a579325c0 100644 --- a/powertools-parameters/pom.xml +++ b/powertools-parameters/pom.xml @@ -41,6 +41,10 @@ + + software.amazon.lambda + powertools-core + software.amazon.awssdk ssm diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SSMProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SSMProvider.java index a74e1c095..bf36aa717 100644 --- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SSMProvider.java +++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SSMProvider.java @@ -22,14 +22,18 @@ import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; import software.amazon.awssdk.services.ssm.model.GetParameterRequest; import software.amazon.awssdk.services.ssm.model.GetParametersByPathRequest; import software.amazon.awssdk.services.ssm.model.GetParametersByPathResponse; import software.amazon.awssdk.utils.StringUtils; +import software.amazon.lambda.powertools.core.internal.LambdaConstants; import software.amazon.lambda.powertools.parameters.cache.CacheManager; import software.amazon.lambda.powertools.parameters.transform.TransformationManager; import software.amazon.lambda.powertools.parameters.transform.Transformer; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.AWS_LAMBDA_INITIALIZATION_TYPE; + /** * AWS System Manager Parameter Store Provider

* @@ -75,20 +79,6 @@ public class SSMProvider extends BaseProvider { private boolean decrypt = false; private boolean recursive = false; - /** - * Default constructor with default {@link SsmClient}.
- * Use when you don't need to customize region or any other attribute of the client.

- *

- * Use the {@link SSMProvider.Builder} to create an instance of it. - */ - SSMProvider(CacheManager cacheManager) { - this(cacheManager, SsmClient.builder() - .httpClientBuilder(UrlConnectionHttpClient.builder()) - .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) - .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) - .build()); - } - /** * Constructor with custom {@link SsmClient}.
* Use when you need to customize region or any other attribute of the client.

@@ -253,11 +243,24 @@ public SSMProvider build() { throw new IllegalStateException("No CacheManager provided, please provide one"); } SSMProvider provider; - if (client != null) { - provider = new SSMProvider(cacheManager, client); - } else { - provider = new SSMProvider(cacheManager); + if (client == null) { + SsmClientBuilder ssmClientBuilder = SsmClient.builder() + .httpClientBuilder(UrlConnectionHttpClient.builder()) + .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))); + + // AWS_LAMBDA_INITIALIZATION_TYPE has two values on-demand and snap-start + // when using snap-start mode, the env var creds provider isn't used and causes a fatal error if set + // fall back to the default provider chain if the mode is anything other than on-demand. + String initializationType = System.getenv().get(AWS_LAMBDA_INITIALIZATION_TYPE); + if (initializationType != null && initializationType.equals(LambdaConstants.ON_DEMAND)) { + ssmClientBuilder.credentialsProvider(EnvironmentVariableCredentialsProvider.create()); + } + + client = ssmClientBuilder.build(); } + + provider = new SSMProvider(cacheManager, client); + if (transformationManager != null) { provider.setTransformationManager(transformationManager); } diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SecretsProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SecretsProvider.java index a0a8fe51e..9764564a9 100644 --- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SecretsProvider.java +++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/SecretsProvider.java @@ -22,12 +22,15 @@ import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; +import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; +import software.amazon.lambda.powertools.core.internal.LambdaConstants; import software.amazon.lambda.powertools.parameters.cache.CacheManager; import software.amazon.lambda.powertools.parameters.transform.TransformationManager; import software.amazon.lambda.powertools.parameters.transform.Transformer; import static java.nio.charset.StandardCharsets.UTF_8; +import static software.amazon.lambda.powertools.core.internal.LambdaConstants.AWS_LAMBDA_INITIALIZATION_TYPE; /** * AWS Secrets Manager Parameter Provider

@@ -57,20 +60,6 @@ public class SecretsProvider extends BaseProvider { private final SecretsManagerClient client; - /** - * Default constructor with default {@link SecretsManagerClient}.
- * Use when you don't need to customize region or any other attribute of the client.

- * - * Use the {@link Builder} to create an instance of it. - */ - SecretsProvider(CacheManager cacheManager) { - this(cacheManager, SecretsManagerClient.builder() - .httpClientBuilder(UrlConnectionHttpClient.builder()) - .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) - .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) - .build()); - } - /** * Constructor with custom {@link SecretsManagerClient}.
* Use when you need to customize region or any other attribute of the client.

@@ -162,11 +151,24 @@ public SecretsProvider build() { throw new IllegalStateException("No CacheManager provided, please provide one"); } SecretsProvider provider; - if (client != null) { - provider = new SecretsProvider(cacheManager, client); - } else { - provider = new SecretsProvider(cacheManager); + if (client == null) { + SecretsManagerClientBuilder secretsManagerClientBuilder = SecretsManagerClient.builder() + .httpClientBuilder(UrlConnectionHttpClient.builder()) + .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))); + + // AWS_LAMBDA_INITIALIZATION_TYPE has two values on-demand and snap-start + // when using snap-start mode, the env var creds provider isn't used and causes a fatal error if set + // fall back to the default provider chain if the mode is anything other than on-demand. + String initializationType = System.getenv().get(AWS_LAMBDA_INITIALIZATION_TYPE); + if (initializationType != null && initializationType.equals(LambdaConstants.ON_DEMAND)) { + secretsManagerClientBuilder.credentialsProvider(EnvironmentVariableCredentialsProvider.create()); + } + + client = secretsManagerClientBuilder.build(); } + + provider = new SecretsProvider(cacheManager, client); + if (transformationManager != null) { provider.setTransformationManager(transformationManager); }