From 7f74a9f9a2d9bc4f1f913ab732c602613a4ee610 Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Fri, 21 Jul 2023 16:36:40 +0300
Subject: [PATCH 1/5] chore: add powertools user-agent-suffix to the AWS SDK v2
clients
---
pom.xml | 1 +
powertools-core/pom.xml | 9 ++
.../core/internal/UserAgentConfigurer.java | 90 ++++++++++++++++
.../src/main/resources/version.properties | 1 +
.../internal/UserAgentConfigurerTest.java | 102 ++++++++++++++++++
.../src/test/resources/test.properties | 1 +
.../src/test/resources/unreadable.properties | 1 +
.../persistence/DynamoDBPersistenceStore.java | 7 +-
.../parameters/AppConfigProvider.java | 9 +-
.../powertools/parameters/BaseProvider.java | 1 +
.../parameters/DynamoDbProvider.java | 6 +-
.../powertools/parameters/SSMProvider.java | 7 +-
.../parameters/SecretsProvider.java | 6 +-
.../lambda/powertools/sqs/SqsUtils.java | 30 +++---
14 files changed, 252 insertions(+), 19 deletions(-)
create mode 100644 powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
create mode 100644 powertools-core/src/main/resources/version.properties
create mode 100644 powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java
create mode 100644 powertools-core/src/test/resources/test.properties
create mode 100644 powertools-core/src/test/resources/unreadable.properties
diff --git a/pom.xml b/pom.xml
index 2e68a99ec..f092e8617 100644
--- a/pom.xml
+++ b/pom.xml
@@ -519,6 +519,7 @@
@{argLine}
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
+ --add-exports=java.xml.crypto/com.sun.org.slf4j.internal=ALL-UNNAMED
diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml
index cf9ad45d1..2bf788edc 100644
--- a/powertools-core/pom.xml
+++ b/powertools-core/pom.xml
@@ -89,4 +89,13 @@
+
+
+
+ src/main/resources
+ true
+
+
+
+
\ No newline at end of file
diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
new file mode 100644
index 000000000..2b93e9d5d
--- /dev/null
+++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
@@ -0,0 +1,90 @@
+package software.amazon.lambda.powertools.core.internal;
+
+import com.sun.org.slf4j.internal.Logger;
+import com.sun.org.slf4j.internal.LoggerFactory;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
+
+public class UserAgentConfigurer {
+
+ public static final String NA = "NA";
+ public static final String VERSION_KEY = "powertools.version";
+ public static final String PT_FEATURE_VARIABLE = "${PT_FEATURE}";
+ public static final String PT_EXEC_ENV_VARIABLE = "${PT_EXEC_ENV}";
+ public static final String VERSION_PROPERTIES_FILENAME = "version.properties";
+ public static final String AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
+ private static final Logger LOG = LoggerFactory.getLogger(UserAgentConfigurer.class);
+ private static final String NO_OP = "no-op";
+ private static String PT_VERSION = getProjectVersion();
+ private static String USER_AGENT_PATTERN = "PT/" + PT_FEATURE_VARIABLE + "/" + PT_VERSION + " PTEnv/" + PT_EXEC_ENV_VARIABLE;
+
+ /**
+ * Retrieves the project version from the version.properties file
+ *
+ * @return the project version
+ */
+ static String getProjectVersion() {
+ return getVersionFromProperties(VERSION_PROPERTIES_FILENAME, VERSION_KEY);
+ }
+
+
+ /**
+ * Retrieves the project version from a properties file.
+ * The file should be in the resources folder.
+ * The version is retrieved from the property with the given key.
+ *
+ * @param propertyFileName the name of the properties file
+ * @param versionKey the key of the property that contains the version
+ * @return the version of the project as configured in the given properties file
+ */
+ static String getVersionFromProperties(String propertyFileName, String versionKey) {
+
+ URL propertiesFileURI = Thread.currentThread().getContextClassLoader().getResource(propertyFileName);
+ if (propertiesFileURI != null) {
+ try (FileInputStream fis = new FileInputStream(propertiesFileURI.getPath())) {
+ Properties properties = new Properties();
+ properties.load(fis);
+ String version = properties.getProperty(versionKey);
+ if (version != null && !version.isEmpty()) {
+ return version;
+ }
+ } catch (IOException e) {
+ LOG.warn("Unable to read {} file. Using default version.", propertyFileName);
+ LOG.debug("Exception:", e);
+ }
+ }
+ return NA;
+ }
+
+ /**
+ * Retrieves the user agent string for the Powertools for AWS Lambda.
+ * It follows the pattern PT/{PT_FEATURE}/{PT_VERSION} PTEnv/{PT_EXEC_ENV}
+ * The version of the project is automatically retrieved.
+ * The PT_EXEC_ENV is automatically retrieved from the AWS_EXECUTION_ENV environment variable.
+ * If it AWS_EXECUTION_ENV is not set, PT_EXEC_ENV defaults to "NA"
+ *
+ * @param ptFeature a custom feature to be added to the user agent string (e.g. idempotency).
+ * If null or empty, the default PT_FEATURE is used.
+ * The default PT_FEATURE is "no-op".
+ * @return the user agent string
+ */
+ public static String getUserAgent(String ptFeature) {
+
+ String awsExecutionEnv = getenv(AWS_EXECUTION_ENV);
+ String ptExecEnv = awsExecutionEnv != null ? awsExecutionEnv : NA;
+ String userAgent = USER_AGENT_PATTERN.replace(PT_EXEC_ENV_VARIABLE, ptExecEnv);
+
+ if (ptFeature == null || ptFeature.isEmpty()) {
+ ptFeature = NO_OP;
+ }
+ return userAgent
+ .replace(PT_FEATURE_VARIABLE, ptFeature)
+ .replace(PT_EXEC_ENV_VARIABLE, ptExecEnv);
+ }
+
+}
diff --git a/powertools-core/src/main/resources/version.properties b/powertools-core/src/main/resources/version.properties
new file mode 100644
index 000000000..3063b3a71
--- /dev/null
+++ b/powertools-core/src/main/resources/version.properties
@@ -0,0 +1 @@
+powertools.version=${project.version}
\ No newline at end of file
diff --git a/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java
new file mode 100644
index 000000000..82988870c
--- /dev/null
+++ b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java
@@ -0,0 +1,102 @@
+package software.amazon.lambda.powertools.core.internal;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mockStatic;
+import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.VERSION_KEY;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.getVersionFromProperties;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.VERSION_PROPERTIES_FILENAME;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.AWS_EXECUTION_ENV;
+
+
+
+public class UserAgentConfigurerTest {
+
+ private static final String SEM_VER_PATTERN = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$";
+ private static final String VERSION = UserAgentConfigurer.getProjectVersion();
+
+
+ @Test
+ public void testGetVersion() {
+
+ assertThat(VERSION).isNotNull();
+ assertThat(VERSION).isNotEmpty();
+ assertThat(Pattern.matches(SEM_VER_PATTERN, VERSION)).isTrue();
+ }
+
+ @Test
+ public void testGetVersionFromProperties_WrongKey() {
+ String version = getVersionFromProperties(VERSION_PROPERTIES_FILENAME, "some invalid key");
+
+ assertThat(version).isNotNull();
+ assertThat(version).isEqualTo("NA");
+ }
+
+ @Test
+ public void testGetVersionFromProperties_FileNotExist() {
+ String version = getVersionFromProperties("some file", VERSION_KEY);
+
+ assertThat(version).isNotNull();
+ assertThat(version).isEqualTo("NA");
+ }
+
+ @Test
+ public void testGetVersionFromProperties_InvalidFile() {
+ File f = new File(Thread.currentThread().getContextClassLoader().getResource("unreadable.properties").getPath());
+ f.setReadable(false);
+
+ String version = getVersionFromProperties("unreadable.properties", VERSION_KEY);
+
+ assertThat(version).isEqualTo("NA");
+ }
+
+ @Test
+ public void testGetVersionFromProperties_EmptyVersion() {
+ String version = getVersionFromProperties("test.properties", VERSION_KEY);
+
+ assertThat(version).isEqualTo("NA");
+ }
+
+ @Test
+ public void testGetUserAgent() {
+ String userAgent = UserAgentConfigurer.getUserAgent("test-feature");
+
+ assertThat(userAgent).isNotNull();
+ assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/NA");
+
+ }
+
+ @Test
+ public void testGetUserAgent_NoFeature() {
+ String userAgent = UserAgentConfigurer.getUserAgent("");
+
+ assertThat(userAgent).isNotNull();
+ assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
+ }
+
+ @Test
+ public void testGetUserAgent_NullFeature() {
+ String userAgent = UserAgentConfigurer.getUserAgent(null);
+
+ assertThat(userAgent).isNotNull();
+ assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
+ }
+
+ @Test
+ public void testGetUserAgent_SetAWSExecutionEnv() {
+ try (MockedStatic mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
+ mockedSystemWrapper.when(() -> getenv(AWS_EXECUTION_ENV)).thenReturn("AWS_Lambda_java8");
+ String userAgent = UserAgentConfigurer.getUserAgent("test-feature");
+
+ assertThat(userAgent).isNotNull();
+ assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
+ }
+ }
+
+}
diff --git a/powertools-core/src/test/resources/test.properties b/powertools-core/src/test/resources/test.properties
new file mode 100644
index 000000000..65756b8dd
--- /dev/null
+++ b/powertools-core/src/test/resources/test.properties
@@ -0,0 +1 @@
+powertools.version=
\ No newline at end of file
diff --git a/powertools-core/src/test/resources/unreadable.properties b/powertools-core/src/test/resources/unreadable.properties
new file mode 100644
index 000000000..3063b3a71
--- /dev/null
+++ b/powertools-core/src/test/resources/unreadable.properties
@@ -0,0 +1 @@
+powertools.version=${project.version}
\ No newline at end of file
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 47ddf4c5c..1f1542a3f 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
@@ -16,12 +16,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;
import software.amazon.awssdk.services.dynamodb.model.*;
import software.amazon.awssdk.utils.StringUtils;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.idempotency.Constants;
import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemAlreadyExistsException;
import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemNotFoundException;
@@ -47,6 +50,7 @@
public class DynamoDBPersistenceStore extends BasePersistenceStore implements PersistenceStore {
private static final Logger LOG = LoggerFactory.getLogger(DynamoDBPersistenceStore.class);
+ public static final String IDEMPOTENCY = "idempotency";
private final String tableName;
private final String keyAttr;
@@ -90,13 +94,14 @@ private DynamoDBPersistenceStore(String tableName,
if (idempotencyDisabledEnv == null || idempotencyDisabledEnv.equalsIgnoreCase("false")) {
DynamoDbClientBuilder ddbBuilder = DynamoDbClient.builder()
.httpClient(UrlConnectionHttpClient.builder().build())
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(IDEMPOTENCY)).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)) {
+ if (initializationType != null && initializationType.equals(ON_DEMAND)) {
ddbBuilder.credentialsProvider(EnvironmentVariableCredentialsProvider.create());
}
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
index e0255125d..29302123c 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
@@ -2,6 +2,8 @@
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.core.SdkSystemSetting;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.appconfigdata.AppConfigDataClient;
@@ -10,6 +12,7 @@
import software.amazon.awssdk.services.appconfigdata.model.GetLatestConfigurationResponse;
import software.amazon.awssdk.services.appconfigdata.model.StartConfigurationSessionRequest;
import software.amazon.lambda.powertools.core.internal.LambdaConstants;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
@@ -146,13 +149,15 @@ public AppConfigProvider build() {
if (client == null) {
AppConfigDataClientBuilder appConfigDataClientBuilder = AppConfigDataClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
- .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())));
+ .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
+ .overrideConfiguration(ClientOverrideConfiguration.builder()
+ .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
// 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)) {
+ if (initializationType != null && initializationType.equals(LambdaConstants.ON_DEMAND)) {
appConfigDataClientBuilder.credentialsProvider(EnvironmentVariableCredentialsProvider.create());
}
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/BaseProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/BaseProvider.java
index fb539f850..200c0184a 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/BaseProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/BaseProvider.java
@@ -31,6 +31,7 @@
*/
@NotThreadSafe
public abstract class BaseProvider implements ParamProvider {
+ public static final String PARAMETERS = "parameters";
protected final CacheManager cacheManager;
private TransformationManager transformationManager;
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
index 1b77aed88..da4c5b18f 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
@@ -2,6 +2,8 @@
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.core.SdkSystemSetting;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
@@ -12,6 +14,7 @@
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.lambda.powertools.core.internal.LambdaConstants;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.exception.DynamoDbProviderSchemaException;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
@@ -192,7 +195,8 @@ public DynamoDbProvider.Builder withTransformationManager(TransformationManager
private static DynamoDbClient createClient() {
DynamoDbClientBuilder dynamoDbClientBuilder = DynamoDbClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
- .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())));
+ .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
// 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
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 2eb2d4199..56dd592a1 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
@@ -15,6 +15,8 @@
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.core.SdkSystemSetting;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ssm.SsmClient;
@@ -24,6 +26,7 @@
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.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
import software.amazon.lambda.powertools.parameters.transform.Transformer;
@@ -285,7 +288,9 @@ public SSMProvider.Builder withClient(SsmClient client) {
private static SsmClient createClient() {
SsmClientBuilder ssmClientBuilder = SsmClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
- .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())));
+ .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
+ ;
// 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
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 ea8b5a9d0..b6e4f475f 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
@@ -15,12 +15,15 @@
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.core.SdkSystemSetting;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
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.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
import software.amazon.lambda.powertools.parameters.transform.Transformer;
@@ -193,7 +196,8 @@ public Builder withClient(SecretsManagerClient client) {
private static SecretsManagerClient createClient() {
SecretsManagerClientBuilder secretsManagerClientBuilder = SecretsManagerClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
- .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())));
+ .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
// 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
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
index 9fff4dc6f..bf79c6602 100644
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
+++ b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
@@ -13,25 +13,26 @@
*/
package software.amazon.lambda.powertools.sqs;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.sqs.SqsClient;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.sqs.exception.SkippedMessageDueToFailedBatchException;
import software.amazon.lambda.powertools.sqs.internal.BatchContext;
-import software.amazon.payloadoffloading.PayloadS3Pointer;
import software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect;
+import software.amazon.payloadoffloading.PayloadS3Pointer;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
import static software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect.processMessages;
@@ -43,6 +44,7 @@ public final class SqsUtils {
private static final Logger LOG = LoggerFactory.getLogger(SqsUtils.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
+ public static final String SQS = "sqs";
private static SqsClient client;
private static S3Client s3Client;
@@ -491,8 +493,9 @@ public static List batchProcessor(final SQSEvent event,
final Class extends Exception>... nonRetryableExceptions) {
final List handlerReturn = new ArrayList<>();
- if(client == null) {
- client = SqsClient.create();
+ if (client == null) {
+ client = (SqsClient) SqsClient.builder()
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(SQS)).build());
}
BatchContext batchContext = new BatchContext(client);
@@ -576,8 +579,9 @@ public static ObjectMapper objectMapper() {
}
public static S3Client s3Client() {
- if(null == s3Client) {
- SqsUtils.s3Client = S3Client.create();
+ if (null == s3Client) {
+ s3Client = (S3Client) S3Client.builder().
+ overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(SQS)).build());
}
return s3Client;
From b1809ccbd7d9dea551fcbbc9226abe85a85ba585 Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Fri, 21 Jul 2023 17:31:57 +0300
Subject: [PATCH 2/5] fix wrong import for logger
---
pom.xml | 1 -
powertools-core/pom.xml | 5 +++++
.../lambda/powertools/core/internal/UserAgentConfigurer.java | 4 ++--
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index 7b84bc8b6..197e84a91 100644
--- a/pom.xml
+++ b/pom.xml
@@ -519,7 +519,6 @@
@{argLine}
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
- --add-exports=java.xml.crypto/com.sun.org.slf4j.internal=ALL-UNNAMED
diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml
index 2bf788edc..3e31e0557 100644
--- a/powertools-core/pom.xml
+++ b/powertools-core/pom.xml
@@ -50,6 +50,11 @@
org.aspectj
aspectjrt
+
+ org.apache.logging.log4j
+ log4j-slf4j2-impl
+ ${log4j.version}
+
diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
index 2b93e9d5d..87af89087 100644
--- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
+++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
@@ -1,7 +1,7 @@
package software.amazon.lambda.powertools.core.internal;
-import com.sun.org.slf4j.internal.Logger;
-import com.sun.org.slf4j.internal.LoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.IOException;
From 3bf973ca23373cda3eb02d2f9b180dbab34a5003 Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Mon, 24 Jul 2023 18:23:05 +0300
Subject: [PATCH 3/5] fix review comments: Add comments and javadoc for
readability, rename class
---
powertools-core/pom.xml | 2 +-
...igurer.java => UserAgentConfigurator.java} | 8 +++++---
.../resources-filtered/version.properties | 9 +++++++++
.../src/main/resources/version.properties | 1 -
...st.java => UserAgentConfiguratorTest.java} | 20 +++++++++----------
.../src/test/resources/unreadable.properties | 3 ++-
.../persistence/DynamoDBPersistenceStore.java | 4 ++--
.../parameters/AppConfigProvider.java | 3 ++-
.../parameters/DynamoDbProvider.java | 4 ++--
.../powertools/parameters/SSMProvider.java | 4 ++--
.../parameters/SecretsProvider.java | 4 ++--
.../lambda/powertools/sqs/SqsUtils.java | 6 +++---
12 files changed, 40 insertions(+), 28 deletions(-)
rename powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/{UserAgentConfigurer.java => UserAgentConfigurator.java} (95%)
create mode 100644 powertools-core/src/main/resources-filtered/version.properties
delete mode 100644 powertools-core/src/main/resources/version.properties
rename powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/{UserAgentConfigurerTest.java => UserAgentConfiguratorTest.java} (84%)
diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml
index 3e31e0557..da3922381 100644
--- a/powertools-core/pom.xml
+++ b/powertools-core/pom.xml
@@ -97,7 +97,7 @@
- src/main/resources
+ src/main/resources-filtered
true
diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
similarity index 95%
rename from powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
rename to powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
index 87af89087..a1c21afa4 100644
--- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurer.java
+++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
@@ -10,7 +10,10 @@
import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
-public class UserAgentConfigurer {
+/**
+ * Can be used to create a string that can server as a User-Agent suffix in requests made with the AWS SDK clients
+ */
+public class UserAgentConfigurator {
public static final String NA = "NA";
public static final String VERSION_KEY = "powertools.version";
@@ -18,7 +21,7 @@ public class UserAgentConfigurer {
public static final String PT_EXEC_ENV_VARIABLE = "${PT_EXEC_ENV}";
public static final String VERSION_PROPERTIES_FILENAME = "version.properties";
public static final String AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
- private static final Logger LOG = LoggerFactory.getLogger(UserAgentConfigurer.class);
+ private static final Logger LOG = LoggerFactory.getLogger(UserAgentConfigurator.class);
private static final String NO_OP = "no-op";
private static String PT_VERSION = getProjectVersion();
private static String USER_AGENT_PATTERN = "PT/" + PT_FEATURE_VARIABLE + "/" + PT_VERSION + " PTEnv/" + PT_EXEC_ENV_VARIABLE;
@@ -86,5 +89,4 @@ public static String getUserAgent(String ptFeature) {
.replace(PT_FEATURE_VARIABLE, ptFeature)
.replace(PT_EXEC_ENV_VARIABLE, ptExecEnv);
}
-
}
diff --git a/powertools-core/src/main/resources-filtered/version.properties b/powertools-core/src/main/resources-filtered/version.properties
new file mode 100644
index 000000000..1d835a456
--- /dev/null
+++ b/powertools-core/src/main/resources-filtered/version.properties
@@ -0,0 +1,9 @@
+# The filtered properties can have variables that are filled in y system properties or project properties.
+# See https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
+#
+# The values are replaced before copying the resources to the main output directory. Therefore, ass soon as the build phase is completed,
+# the values should have been replaced if the properties are available and if 'filtering' is set to true in the pom.xml
+#
+#
+# The ${project.version} is retrieved from the respective pom.xml property
+powertools.version=${project.version}
\ No newline at end of file
diff --git a/powertools-core/src/main/resources/version.properties b/powertools-core/src/main/resources/version.properties
deleted file mode 100644
index 3063b3a71..000000000
--- a/powertools-core/src/main/resources/version.properties
+++ /dev/null
@@ -1 +0,0 @@
-powertools.version=${project.version}
\ No newline at end of file
diff --git a/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
similarity index 84%
rename from powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java
rename to powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
index 82988870c..a0ae6ad53 100644
--- a/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurerTest.java
+++ b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
@@ -9,17 +9,17 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mockStatic;
import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.VERSION_KEY;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.getVersionFromProperties;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.VERSION_PROPERTIES_FILENAME;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurer.AWS_EXECUTION_ENV;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.VERSION_KEY;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.getVersionFromProperties;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.VERSION_PROPERTIES_FILENAME;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.AWS_EXECUTION_ENV;
-public class UserAgentConfigurerTest {
+public class UserAgentConfiguratorTest {
private static final String SEM_VER_PATTERN = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$";
- private static final String VERSION = UserAgentConfigurer.getProjectVersion();
+ private static final String VERSION = UserAgentConfigurator.getProjectVersion();
@Test
@@ -65,7 +65,7 @@ public void testGetVersionFromProperties_EmptyVersion() {
@Test
public void testGetUserAgent() {
- String userAgent = UserAgentConfigurer.getUserAgent("test-feature");
+ String userAgent = UserAgentConfigurator.getUserAgent("test-feature");
assertThat(userAgent).isNotNull();
assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/NA");
@@ -74,7 +74,7 @@ public void testGetUserAgent() {
@Test
public void testGetUserAgent_NoFeature() {
- String userAgent = UserAgentConfigurer.getUserAgent("");
+ String userAgent = UserAgentConfigurator.getUserAgent("");
assertThat(userAgent).isNotNull();
assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
@@ -82,7 +82,7 @@ public void testGetUserAgent_NoFeature() {
@Test
public void testGetUserAgent_NullFeature() {
- String userAgent = UserAgentConfigurer.getUserAgent(null);
+ String userAgent = UserAgentConfigurator.getUserAgent(null);
assertThat(userAgent).isNotNull();
assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
@@ -92,7 +92,7 @@ public void testGetUserAgent_NullFeature() {
public void testGetUserAgent_SetAWSExecutionEnv() {
try (MockedStatic mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(AWS_EXECUTION_ENV)).thenReturn("AWS_Lambda_java8");
- String userAgent = UserAgentConfigurer.getUserAgent("test-feature");
+ String userAgent = UserAgentConfigurator.getUserAgent("test-feature");
assertThat(userAgent).isNotNull();
assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
diff --git a/powertools-core/src/test/resources/unreadable.properties b/powertools-core/src/test/resources/unreadable.properties
index 3063b3a71..42ff4693f 100644
--- a/powertools-core/src/test/resources/unreadable.properties
+++ b/powertools-core/src/test/resources/unreadable.properties
@@ -1 +1,2 @@
-powertools.version=${project.version}
\ No newline at end of file
+# This is intentionally left empty
+# It used during testing and is set to un-readable to fulfil the test purposes.
\ No newline at end of file
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 787dd9645..457ad0233 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
@@ -24,7 +24,7 @@
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;
import software.amazon.awssdk.services.dynamodb.model.*;
import software.amazon.awssdk.utils.StringUtils;
-import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.idempotency.Constants;
import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemAlreadyExistsException;
import software.amazon.lambda.powertools.idempotency.exceptions.IdempotencyItemNotFoundException;
@@ -94,7 +94,7 @@ private DynamoDBPersistenceStore(String tableName,
if (idempotencyDisabledEnv == null || idempotencyDisabledEnv.equalsIgnoreCase("false")) {
DynamoDbClientBuilder ddbBuilder = DynamoDbClient.builder()
.httpClient(UrlConnectionHttpClient.builder().build())
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(IDEMPOTENCY)).build())
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(IDEMPOTENCY)).build())
.region(Region.of(System.getenv(AWS_REGION_ENV)));
// AWS_LAMBDA_INITIALIZATION_TYPE has two values on-demand and snap-start
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
index 29302123c..08270a229 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/AppConfigProvider.java
@@ -12,6 +12,7 @@
import software.amazon.awssdk.services.appconfigdata.model.GetLatestConfigurationResponse;
import software.amazon.awssdk.services.appconfigdata.model.StartConfigurationSessionRequest;
import software.amazon.lambda.powertools.core.internal.LambdaConstants;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
@@ -151,7 +152,7 @@ public AppConfigProvider build() {
.httpClientBuilder(UrlConnectionHttpClient.builder())
.region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
.overrideConfiguration(ClientOverrideConfiguration.builder()
- .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
+ .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(PARAMETERS)).build());
// 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
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
index da4c5b18f..914dd84a4 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
@@ -14,7 +14,7 @@
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.lambda.powertools.core.internal.LambdaConstants;
-import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.exception.DynamoDbProviderSchemaException;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
@@ -196,7 +196,7 @@ private static DynamoDbClient createClient() {
DynamoDbClientBuilder dynamoDbClientBuilder = DynamoDbClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
.region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(PARAMETERS)).build());
// 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
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 56dd592a1..c19534646 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
@@ -26,7 +26,7 @@
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.core.internal.UserAgentConfigurer;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
import software.amazon.lambda.powertools.parameters.transform.Transformer;
@@ -289,7 +289,7 @@ private static SsmClient createClient() {
SsmClientBuilder ssmClientBuilder = SsmClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
.region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(PARAMETERS)).build());
;
// AWS_LAMBDA_INITIALIZATION_TYPE has two values on-demand and snap-start
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 b6e4f475f..0dfbc0b0b 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
@@ -23,7 +23,7 @@
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.core.internal.UserAgentConfigurer;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.transform.TransformationManager;
import software.amazon.lambda.powertools.parameters.transform.Transformer;
@@ -197,7 +197,7 @@ private static SecretsManagerClient createClient() {
SecretsManagerClientBuilder secretsManagerClientBuilder = SecretsManagerClient.builder()
.httpClientBuilder(UrlConnectionHttpClient.builder())
.region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(PARAMETERS)).build());
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(PARAMETERS)).build());
// 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
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
index bf79c6602..b2b904bcf 100644
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
+++ b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
@@ -22,7 +22,7 @@
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.lambda.powertools.core.internal.UserAgentConfigurer;
+import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.sqs.exception.SkippedMessageDueToFailedBatchException;
import software.amazon.lambda.powertools.sqs.internal.BatchContext;
import software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect;
@@ -495,7 +495,7 @@ public static List batchProcessor(final SQSEvent event,
if (client == null) {
client = (SqsClient) SqsClient.builder()
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(SQS)).build());
+ .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(SQS)).build());
}
BatchContext batchContext = new BatchContext(client);
@@ -581,7 +581,7 @@ public static ObjectMapper objectMapper() {
public static S3Client s3Client() {
if (null == s3Client) {
s3Client = (S3Client) S3Client.builder().
- overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurer.getUserAgent(SQS)).build());
+ overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(SQS)).build());
}
return s3Client;
From 825b41cff8af3d57a2f8f348f554623b6aa80787 Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Wed, 26 Jul 2023 17:39:28 +0300
Subject: [PATCH 4/5] fix typo
---
.../src/main/resources-filtered/version.properties | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/powertools-core/src/main/resources-filtered/version.properties b/powertools-core/src/main/resources-filtered/version.properties
index 1d835a456..5e95fb588 100644
--- a/powertools-core/src/main/resources-filtered/version.properties
+++ b/powertools-core/src/main/resources-filtered/version.properties
@@ -1,7 +1,7 @@
-# The filtered properties can have variables that are filled in y system properties or project properties.
+# The filtered properties can have variables that are filled in by system properties or project properties.
# See https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
#
-# The values are replaced before copying the resources to the main output directory. Therefore, ass soon as the build phase is completed,
+# The values are replaced before copying the resources to the main output directory. Therefore, as soon as the build phase is completed,
# the values should have been replaced if the properties are available and if 'filtering' is set to true in the pom.xml
#
#
From ecaa919fc2927d438754600eed9a58f7a60d2277 Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Thu, 27 Jul 2023 16:03:51 +0300
Subject: [PATCH 5/5] fix code smells and formatting issues
---
.../core/internal/UserAgentConfigurator.java | 31 +++++--
.../internal/UserAgentConfiguratorTest.java | 88 ++++++++++++-------
.../parameters/DynamoDbProvider.java | 6 +-
.../lambda/powertools/sqs/SqsUtils.java | 21 +++--
4 files changed, 96 insertions(+), 50 deletions(-)
diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
index a1c21afa4..354305d33 100644
--- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
+++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/UserAgentConfigurator.java
@@ -1,14 +1,28 @@
+/*
+ * Copyright 2023 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;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
/**
* Can be used to create a string that can server as a User-Agent suffix in requests made with the AWS SDK clients
@@ -23,8 +37,13 @@ public class UserAgentConfigurator {
public static final String AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV";
private static final Logger LOG = LoggerFactory.getLogger(UserAgentConfigurator.class);
private static final String NO_OP = "no-op";
- private static String PT_VERSION = getProjectVersion();
- private static String USER_AGENT_PATTERN = "PT/" + PT_FEATURE_VARIABLE + "/" + PT_VERSION + " PTEnv/" + PT_EXEC_ENV_VARIABLE;
+ private static String ptVersion = getProjectVersion();
+ private static String userAgentPattern = "PT/" + PT_FEATURE_VARIABLE + "/" + ptVersion + " PTEnv/"
+ + PT_EXEC_ENV_VARIABLE;
+
+ private UserAgentConfigurator() {
+ throw new IllegalStateException("Utility class. Not meant to be instantiated");
+ }
/**
* Retrieves the project version from the version.properties file
@@ -80,7 +99,7 @@ public static String getUserAgent(String ptFeature) {
String awsExecutionEnv = getenv(AWS_EXECUTION_ENV);
String ptExecEnv = awsExecutionEnv != null ? awsExecutionEnv : NA;
- String userAgent = USER_AGENT_PATTERN.replace(PT_EXEC_ENV_VARIABLE, ptExecEnv);
+ String userAgent = userAgentPattern.replace(PT_EXEC_ENV_VARIABLE, ptExecEnv);
if (ptFeature == null || ptFeature.isEmpty()) {
ptFeature = NO_OP;
diff --git a/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
index a0ae6ad53..00110077f 100644
--- a/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
+++ b/powertools-core/src/test/java/software/amazon/lambda/powertools/core/internal/UserAgentConfiguratorTest.java
@@ -1,54 +1,70 @@
-package software.amazon.lambda.powertools.core.internal;
+/*
+ * Copyright 2023 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.
+ *
+ */
-import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
-
-import java.io.File;
-import java.util.regex.Pattern;
+package software.amazon.lambda.powertools.core.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mockStatic;
import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.AWS_EXECUTION_ENV;
import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.VERSION_KEY;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.getVersionFromProperties;
import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.VERSION_PROPERTIES_FILENAME;
-import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.AWS_EXECUTION_ENV;
-
+import static software.amazon.lambda.powertools.core.internal.UserAgentConfigurator.getVersionFromProperties;
+import java.io.File;
+import java.util.Objects;
+import java.util.regex.Pattern;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
-public class UserAgentConfiguratorTest {
+class UserAgentConfiguratorTest {
private static final String SEM_VER_PATTERN = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$";
private static final String VERSION = UserAgentConfigurator.getProjectVersion();
@Test
- public void testGetVersion() {
+ void testGetVersion() {
- assertThat(VERSION).isNotNull();
- assertThat(VERSION).isNotEmpty();
+ assertThat(VERSION)
+ .isNotNull()
+ .isNotEmpty();
assertThat(Pattern.matches(SEM_VER_PATTERN, VERSION)).isTrue();
}
@Test
- public void testGetVersionFromProperties_WrongKey() {
+ void testGetVersionFromProperties_WrongKey() {
String version = getVersionFromProperties(VERSION_PROPERTIES_FILENAME, "some invalid key");
- assertThat(version).isNotNull();
- assertThat(version).isEqualTo("NA");
+ assertThat(version)
+ .isNotNull()
+ .isEqualTo("NA");
}
@Test
- public void testGetVersionFromProperties_FileNotExist() {
+ void testGetVersionFromProperties_FileNotExist() {
String version = getVersionFromProperties("some file", VERSION_KEY);
- assertThat(version).isNotNull();
- assertThat(version).isEqualTo("NA");
+ assertThat(version)
+ .isNotNull()
+ .isEqualTo("NA");
}
@Test
- public void testGetVersionFromProperties_InvalidFile() {
- File f = new File(Thread.currentThread().getContextClassLoader().getResource("unreadable.properties").getPath());
+ void testGetVersionFromProperties_InvalidFile() {
+ File f = new File(Objects.requireNonNull(Thread.currentThread().getContextClassLoader()
+ .getResource("unreadable.properties")).getPath());
f.setReadable(false);
String version = getVersionFromProperties("unreadable.properties", VERSION_KEY);
@@ -57,45 +73,49 @@ public void testGetVersionFromProperties_InvalidFile() {
}
@Test
- public void testGetVersionFromProperties_EmptyVersion() {
+ void testGetVersionFromProperties_EmptyVersion() {
String version = getVersionFromProperties("test.properties", VERSION_KEY);
assertThat(version).isEqualTo("NA");
}
@Test
- public void testGetUserAgent() {
+ void testGetUserAgent() {
String userAgent = UserAgentConfigurator.getUserAgent("test-feature");
- assertThat(userAgent).isNotNull();
- assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/NA");
+ assertThat(userAgent)
+ .isNotNull()
+ .isEqualTo("PT/test-feature/" + VERSION + " PTEnv/NA");
}
@Test
- public void testGetUserAgent_NoFeature() {
+ void testGetUserAgent_NoFeature() {
String userAgent = UserAgentConfigurator.getUserAgent("");
- assertThat(userAgent).isNotNull();
- assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
+ assertThat(userAgent)
+ .isNotNull()
+ .isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
}
@Test
- public void testGetUserAgent_NullFeature() {
+ void testGetUserAgent_NullFeature() {
String userAgent = UserAgentConfigurator.getUserAgent(null);
- assertThat(userAgent).isNotNull();
- assertThat(userAgent).isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
+ assertThat(userAgent)
+ .isNotNull()
+ .isEqualTo("PT/no-op/" + VERSION + " PTEnv/NA");
}
@Test
- public void testGetUserAgent_SetAWSExecutionEnv() {
+ void testGetUserAgent_SetAWSExecutionEnv() {
try (MockedStatic mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(AWS_EXECUTION_ENV)).thenReturn("AWS_Lambda_java8");
String userAgent = UserAgentConfigurator.getUserAgent("test-feature");
- assertThat(userAgent).isNotNull();
- assertThat(userAgent).isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
+ assertThat(userAgent)
+ .isNotNull()
+ .isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
}
}
diff --git a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
index 654cbfd33..499241927 100644
--- a/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
+++ b/powertools-parameters/src/main/java/software/amazon/lambda/powertools/parameters/DynamoDbProvider.java
@@ -23,7 +23,11 @@
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
-import software.amazon.awssdk.services.dynamodb.model.*;
+import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
+import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
+import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
+import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
+import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
import software.amazon.lambda.powertools.parameters.cache.CacheManager;
import software.amazon.lambda.powertools.parameters.exception.DynamoDbProviderSchemaException;
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
index c8d83bd68..29050d6c8 100644
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
+++ b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
@@ -41,17 +41,14 @@
* A class of helper functions to add additional functionality to {@link SQSEvent} processing.
*/
public final class SqsUtils {
- private static final Logger LOG = LoggerFactory.getLogger(SqsUtils.class);
-
- private static final ObjectMapper objectMapper = new ObjectMapper();
public static final String SQS = "sqs";
+ private static final Logger LOG = LoggerFactory.getLogger(SqsUtils.class);
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+ private static final String MESSAGE_GROUP_ID = "MessageGroupId";
private static SqsClient client;
private static S3Client s3Client;
- // The attribute on an SQS-FIFO message used to record the message group ID
- private static final String MESSAGE_GROUP_ID = "MessageGroupId";
-
private SqsUtils() {
}
@@ -500,7 +497,10 @@ public static List batchProcessor(final SQSEvent event,
if (client == null) {
client = (SqsClient) SqsClient.builder()
- .overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(SQS)).build());
+ .overrideConfiguration(ClientOverrideConfiguration.builder()
+ .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX,
+ UserAgentConfigurator.getUserAgent(SQS))
+ .build());
}
BatchContext batchContext = new BatchContext(client);
@@ -589,8 +589,11 @@ public static ObjectMapper objectMapper() {
public static S3Client s3Client() {
if (null == s3Client) {
- s3Client = (S3Client) S3Client.builder().
- overrideConfiguration(ClientOverrideConfiguration.builder().putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX, UserAgentConfigurator.getUserAgent(SQS)).build());
+ s3Client = (S3Client) S3Client.builder()
+ .overrideConfiguration(ClientOverrideConfiguration.builder()
+ .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX,
+ UserAgentConfigurator.getUserAgent(SQS))
+ .build());
SqsUtils.s3Client = S3Client.create();
}