diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 634a4ee0f..60eea144e 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -2,90 +2,10 @@ name: Build on: pull_request: - branches: - - main - paths: - - 'powertools-batch/**' - - 'powertools-cloudformation/**' - - 'powertools-core/**' - - 'powertools-e2e-tests/**' - - 'powertools-idempotency/**' - - 'powertools-large-messages/**' - - 'powertools-logging/**' - - 'powertools-metrics/**' - - 'powertools-parameters/**' - - 'powertools-serialization/**' - - 'powertools-sqs/**' - - 'powertools-test-suite/**' - - 'powertools-tracing/**' - - 'powertools-validation/**' - - 'examples/**' - - 'pom.xml' - - 'examples/pom.xml' - - '.github/workflows/**' - push: - branches: - - main - paths: - - 'powertools-batch/**' - - 'powertools-cloudformation/**' - - 'powertools-core/**' - - 'powertools-e2e-tests/**' - - 'powertools-idempotency/**' - - 'powertools-large-messages/**' - - 'powertools-logging/**' - - 'powertools-metrics/**' - - 'powertools-parameters/**' - - 'powertools-serialization/**' - - 'powertools-sqs/**' - - 'powertools-test-suite/**' - - 'powertools-tracing/**' - - 'powertools-validation/**' - - 'examples/**' - - 'pom.xml' - - 'examples/pom.xml' - - '.github/workflows/**' jobs: - build-corretto: - runs-on: ubuntu-latest - strategy: - max-parallel: 5 - matrix: - java: [8, 11, 17, 21] - name: Java ${{ matrix.java }} - env: - JAVA: ${{ matrix.java }} - AWS_REGION: eu-west-1 - permissions: - id-token: write # needed to interact with GitHub's OIDC Token endpoint. - contents: read - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - name: Setup java - uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 - with: - distribution: 'corretto' - java-version: ${{ matrix.java }} - cache: 'maven' - - name: Build with Maven - run: mvn -B install --file pom.xml - - name: Build Gradle Example - Java - if: ${{ matrix.java == '8' }} # Gradle example can only be built on Java 8 - working-directory: examples/powertools-examples-core/gradle - run: ./gradlew build - - name: Build Gradle Example - Kotlin - if: ${{ matrix.java == '8' }} # Gradle example can only be built on Java 8 - working-directory: examples/powertools-examples-core/kotlin - run: ./gradlew build - - name: Upload coverage to Codecov - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 - if: ${{ matrix.java == '11' }} # publish results once - with: - files: ./powertools-cloudformation/target/site/jacoco/jacoco.xml,./powertools-core/target/site/jacoco/jacoco.xml,./powertools-idempotency/target/site/jacoco/jacoco.xml,./powertools-logging/target/site/jacoco/jacoco.xml,./powertools-metrics/target/site/jacoco/jacoco.xml,./powertools-parameters/target/site/jacoco/jacoco.xml,./powertools-serialization/target/site/jacoco/jacoco.xml,./powertools-sqs/target/site/jacoco/jacoco.xml,./powertools-tracing/target/site/jacoco/jacoco.xml,./powertools-validation/target/site/jacoco/jacoco.xml,./powertools-large-messages/target/site/jacoco/jacoco.xml,./powertools-batch/target/site/jacoco/jacoco.xml savepr: runs-on: ubuntu-latest name: Save PR number if running on PR by dependabot - if: github.actor == 'dependabot[bot]' steps: - name: Create Directory and save issue run: | diff --git a/README.md b/README.md index dbe8eb2fe..acc816193 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ Knowing which companies are using this library is important to help prioritize t The following companies, among others, use Powertools: * [Capital One](https://www.capitalone.com/) +* [Caylent](https://caylent.com/) * [CPQi (Exadel Financial Services)](https://cpqi.com/) * [Europace AG](https://europace.de/) * [Vertex Pharmaceuticals](https://www.vrtx.com/) diff --git a/docs/core/logging.md b/docs/core/logging.md index 70781b1b2..30ae20a76 100644 --- a/docs/core/logging.md +++ b/docs/core/logging.md @@ -187,7 +187,7 @@ You can also override log level by setting **`POWERTOOLS_LOG_LEVEL`** env var. H Type: AWS::Serverless::Function Properties: ... - Runtime: java8 + Runtime: java11 Environment: Variables: POWERTOOLS_LOG_LEVEL: DEBUG @@ -590,7 +590,7 @@ via `samplingRate` attribute on annotation. Type: AWS::Serverless::Function Properties: ... - Runtime: java8 + Runtime: java11 Environment: Variables: POWERTOOLS_LOGGER_SAMPLE_RATE: 0.5 diff --git a/docs/core/metrics.md b/docs/core/metrics.md index e06ab6d10..5d43e53c0 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -179,7 +179,7 @@ Setting | Description | Environment variable | Constructor parameter Type: AWS::Serverless::Function Properties: ... - Runtime: java8 + Runtime: java11 Environment: Variables: POWERTOOLS_SERVICE_NAME: payment diff --git a/docs/core/tracing.md b/docs/core/tracing.md index 17e81b867..8e3abe89a 100644 --- a/docs/core/tracing.md +++ b/docs/core/tracing.md @@ -164,7 +164,7 @@ Before your use this utility, your AWS Lambda function [must have permissions](h Type: AWS::Serverless::Function Properties: ... - Runtime: java8 + Runtime: java11 Tracing: Active Environment: @@ -250,7 +250,7 @@ different supported `captureMode` to record response, exception or both. Type: AWS::Serverless::Function Properties: ... - Runtime: java8 + Runtime: java11 Tracing: Active Environment: @@ -376,8 +376,24 @@ under a subsegment, or you are doing multithreaded programming. Refer examples b ## Instrumenting SDK clients and HTTP calls -User should make sure to instrument the SDK clients explicitly based on the function dependency. Refer details on -[how to instrument SDK client with Xray](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-awssdkclients.html) and [outgoing http calls](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-httpclients.html). +Powertools for Lambda (Java) cannot intercept SDK clients instantiation to add X-Ray instrumentation. You should make sure to instrument the SDK clients explicitly. Refer details on +[how to instrument SDK client with Xray](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html#xray-sdk-java-awssdkclients) +and [outgoing http calls](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html#xray-sdk-java-httpclients). For example: + +=== "LambdaHandler.java" + + ```java hl_lines="1 2 7" + import com.amazonaws.xray.AWSXRay; + import com.amazonaws.xray.handlers.TracingHandler; + + public class LambdaHandler { + private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() + .withRegion(Regions.fromName(System.getenv("AWS_REGION"))) + .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder())) + .build(); + // ... + } + ``` ## Testing your code diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index d3539d919..ac6d1e557 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -14,7 +14,7 @@ 2.20.0 1.8 1.8 - 2.21.1 + 2.27.12 diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 5e3403f4e..7c9feabb4 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -15,7 +15,7 @@ 1.8 1.2.3 3.11.4 - 2.25.6 + 2.28.15 diff --git a/examples/powertools-examples-core/gradle/template.yaml b/examples/powertools-examples-core/gradle/template.yaml index a717c2998..122c05fcc 100644 --- a/examples/powertools-examples-core/gradle/template.yaml +++ b/examples/powertools-examples-core/gradle/template.yaml @@ -26,7 +26,7 @@ Resources: Properties: CodeUri: . Handler: helloworld.App::handleRequest - Runtime: java8 + Runtime: java8.al2 MemorySize: 512 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: @@ -43,7 +43,7 @@ Resources: Properties: CodeUri: . Handler: helloworld.AppStream::handleRequest - Runtime: java8 + Runtime: java8.al2 MemorySize: 512 Tracing: Active Environment: diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 01bbfd8d2..554ae9a71 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -27,7 +27,7 @@ software.amazon.awssdk url-connection-client - 2.25.6 + 2.28.15 com.amazonaws @@ -52,7 +52,7 @@ com.fasterxml.jackson.datatype jackson-datatype-joda - 2.15.2 + 2.17.0 diff --git a/mkdocs.yml b/mkdocs.yml index a271c1260..92430a18a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,6 +5,7 @@ site_url: https://docs.powertools.aws.dev/lambda-java/ nav: - Homepage: index.md - Changelog: changelog.md + - Workshop 🆕: https://s12d.com/powertools-for-aws-lambda-workshop" target="_blank - FAQs: FAQs.md - Core utilities: - core/logging.md @@ -85,6 +86,7 @@ extra_css: extra_javascript: - javascript/aws-amplify.min.js - javascript/extra.js + - https://docs.powertools.aws.dev/shared/mermaid.min.js extra: powertools: diff --git a/pom.xml b/pom.xml index e3f5dad3b..979dd9756 100644 --- a/pom.xml +++ b/pom.xml @@ -74,10 +74,10 @@ 1.8 1.8 2.22.1 - 2.15.3 - 2.25.6 - 2.15.1 - 2.1.3 + 2.17.2 + 2.28.15 + 2.18.1 + 2.2.0 UTF-8 1.2.3 3.11.4 @@ -89,8 +89,8 @@ 0.8.11 1.6.13 3.6.0 - 3.3.0 - 3.1.0 + 3.3.1 + 3.2.1 5.10.0 1.0.6 0.6.0 @@ -260,7 +260,7 @@ org.apache.commons commons-lang3 - 3.13.0 + 3.14.0 test @@ -272,7 +272,7 @@ org.assertj assertj-core - 3.24.2 + 3.26.0 test @@ -499,7 +499,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.7.3.6 + 4.8.5.0 test @@ -606,7 +606,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.3.0 + 3.4.0 checkstyle.xml UTF-8 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 450d1f5c1..5c8db8d80 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -103,7 +103,7 @@ commons-io commons-io - 2.15.1 + 2.16.1 @@ -209,7 +209,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.1.2 + 3.3.0 diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java index 28a0f2bb4..b7d3354e1 100644 --- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java +++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/Infrastructure.java @@ -513,7 +513,7 @@ private Builder() { private JavaRuntime mapRuntimeVersion(String environmentVariableName) { String javaVersion = System.getenv(environmentVariableName); // must be set in GitHub actions - JavaRuntime ret = null; + JavaRuntime ret; if (javaVersion == null) { throw new IllegalArgumentException(environmentVariableName + " is not set"); } diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/JavaRuntime.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/JavaRuntime.java index c75682949..9f04831c0 100644 --- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/JavaRuntime.java +++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/testutils/JavaRuntime.java @@ -17,7 +17,6 @@ import software.amazon.awscdk.services.lambda.Runtime; public enum JavaRuntime { - JAVA8("java8", Runtime.JAVA_8, "1.8"), JAVA8AL2("java8.al2", Runtime.JAVA_8_CORRETTO, "1.8"), JAVA11("java11", Runtime.JAVA_11, "11"), JAVA17("java17", Runtime.JAVA_17, "17"), diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index 94aceebfc..0bf3f3600 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -174,7 +174,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 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 f2e4faebb..b075b169d 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 @@ -14,8 +14,6 @@ package software.amazon.lambda.powertools.parameters; -import java.util.HashMap; -import java.util.Map; import software.amazon.awssdk.core.SdkSystemSetting; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption; @@ -25,10 +23,14 @@ import software.amazon.awssdk.services.appconfigdata.model.GetLatestConfigurationRequest; import software.amazon.awssdk.services.appconfigdata.model.GetLatestConfigurationResponse; import software.amazon.awssdk.services.appconfigdata.model.StartConfigurationSessionRequest; +import software.amazon.awssdk.utils.StringUtils; 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 java.util.HashMap; +import java.util.Map; + /** * Implements a {@link ParamProvider} on top of the AppConfig service. AppConfig provides * a mechanism to retrieve and update configuration of applications over time. @@ -98,7 +100,7 @@ protected String getValue(String key) { // Get the value of the key. Note that AppConfig will return null if the value // has not changed since we last asked for it in this session - in this case // we return the value we stashed at last request. - String value = response.configuration() != null ? + String value = !(response.configuration() == null || StringUtils.isEmpty(response.configuration().asUtf8String())) ? response.configuration().asUtf8String() : // if we have a new value, use it establishedSession != null ? establishedSession.lastConfigurationValue : diff --git a/powertools-parameters/src/test/java/software/amazon/lambda/powertools/parameters/AppConfigProviderTest.java b/powertools-parameters/src/test/java/software/amazon/lambda/powertools/parameters/AppConfigProviderTest.java index f467dca72..7614d4f0b 100644 --- a/powertools-parameters/src/test/java/software/amazon/lambda/powertools/parameters/AppConfigProviderTest.java +++ b/powertools-parameters/src/test/java/software/amazon/lambda/powertools/parameters/AppConfigProviderTest.java @@ -14,11 +14,6 @@ package software.amazon.lambda.powertools.parameters; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.assertj.core.api.Assertions.assertThatRuntimeException; -import static org.mockito.MockitoAnnotations.openMocks; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -34,6 +29,11 @@ import software.amazon.lambda.powertools.parameters.cache.CacheManager; import software.amazon.lambda.powertools.parameters.transform.TransformationManager; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatRuntimeException; +import static org.mockito.MockitoAnnotations.openMocks; + public class AppConfigProviderTest { private final String environmentName = "test"; @@ -90,21 +90,29 @@ public void getValueRetrievesValue() { GetLatestConfigurationResponse thirdResponse = GetLatestConfigurationResponse.builder() .nextPollConfigurationToken("token4") .build(); + // Forth response returns empty, which means the provider should yield the previous value again + GetLatestConfigurationResponse forthResponse = GetLatestConfigurationResponse.builder() + .nextPollConfigurationToken("token5") + .configuration(SdkBytes.fromUtf8String("")) + .build(); Mockito.when(client.startConfigurationSession(startSessionRequestCaptor.capture())) .thenReturn(firstSession); Mockito.when(client.getLatestConfiguration(getLatestConfigurationRequestCaptor.capture())) - .thenReturn(firstResponse, secondResponse, thirdResponse); + .thenReturn(firstResponse, secondResponse, thirdResponse, forthResponse); // Act String returnedValue1 = provider.getValue(defaultTestKey); String returnedValue2 = provider.getValue(defaultTestKey); String returnedValue3 = provider.getValue(defaultTestKey); + String returnedValue4 = provider.getValue(defaultTestKey); // Assert assertThat(returnedValue1).isEqualTo(firstResponse.configuration().asUtf8String()); assertThat(returnedValue2).isEqualTo(secondResponse.configuration().asUtf8String()); assertThat(returnedValue3).isEqualTo(secondResponse.configuration() .asUtf8String()); // Third response is mocked to return null and should re-use previous value + assertThat(returnedValue4).isEqualTo(secondResponse.configuration() + .asUtf8String()); // Forth response is mocked to return empty and should re-use previous value assertThat(startSessionRequestCaptor.getValue().applicationIdentifier()).isEqualTo(applicationName); assertThat(startSessionRequestCaptor.getValue().environmentIdentifier()).isEqualTo(environmentName); assertThat(startSessionRequestCaptor.getValue().configurationProfileIdentifier()).isEqualTo(defaultTestKey);