diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml deleted file mode 100644 index 5401eedc9..000000000 --- a/.github/workflows/auto-merge.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Auto merge if dependabot PR - -on: - workflow_run: - workflows: ["Build"] - types: [completed] - -permissions: - pull-requests: write - issues: write - repository-projects: write - contents: write - -jobs: - merge-me: - name: Merge me! - runs-on: ubuntu-latest - if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' && github.actor == 'dependabot[bot]' - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - uses: ahmadnassri/action-workflow-run-wait@2aa3d9e1a12ecaaa9908e368eaf2123bb084323e # v1.4.4 - with: - timeout: 300000 - - name: 'Download artifact' - uses: actions/github-script@47f7cf65b5ced0830a325f705cad64f2f58dddf7 # v3.1.0 - with: - script: | - var artifacts = await github.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - var matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "pr" - })[0]; - var download = await github.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - var fs = require('fs'); - fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data)); - - run: unzip pr.zip - - name: Create review - uses: actions/github-script@47f7cf65b5ced0830a325f705cad64f2f58dddf7 # v3.1.0 - with: - script: | - var fs = require('fs'); - var issue_number = Number(fs.readFileSync('./NR')); - - github.pulls.createReview({ - owner: context.payload.repository.owner.login, - repo: context.payload.repository.name, - pull_number: issue_number, - event: 'APPROVE' - }) - - github.pulls.merge({ - owner: context.payload.repository.owner.login, - repo: context.payload.repository.name, - pull_number: issue_number, - merge_method: 'squash' - }) - - github-token: ${{ secrets.AUTOMERGE }} 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..05136b3e5 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.27.7 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..2dbf3c5f9 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.27.12 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..06e629fb3 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.27.7 + 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);