From 1c847957911a2c3a6bd9cdac9c00a1e2552e8915 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 14:04:08 +0200 Subject: [PATCH 01/74] build(deps): bump aws.sdk.version from 2.20.129 to 2.20.130 (#1386) Bumps `aws.sdk.version` from 2.20.129 to 2.20.130. Updates `software.amazon.awssdk:bom` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:http-client-spi` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:url-connection-client` from 2.20.128 to 2.20.130 Updates `software.amazon.awssdk:sqs` from 2.20.128 to 2.20.130 Updates `software.amazon.awssdk:s3` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:dynamodb` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:lambda` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:kinesis` from 2.20.128 to 2.20.130 Updates `software.amazon.awssdk:cloudwatch` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:xray` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:cloudformation` from 2.20.129 to 2.20.130 Updates `software.amazon.awssdk:sts` from 2.20.129 to 2.20.130 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 8a4834cdf..86bd29f93 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -16,7 +16,7 @@ true 1.2.3 3.11.2 - 2.20.129 + 2.20.130 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 277c282a4..f676e1a73 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -28,7 +28,7 @@ software.amazon.awssdk url-connection-client - 2.20.129 + 2.20.130 com.amazonaws diff --git a/pom.xml b/pom.xml index 3b05583a6..2bd2f9ad2 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.129 + 2.20.130 2.14.0 2.1.3 UTF-8 From 99982d6cd54cf44b9603f31a0548e292a60a5630 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Mon, 21 Aug 2023 13:39:10 +0100 Subject: [PATCH 02/74] Fix batch pom (#1385) --- powertools-batch/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/powertools-batch/pom.xml b/powertools-batch/pom.xml index 2243c3097..82d1d57b2 100644 --- a/powertools-batch/pom.xml +++ b/powertools-batch/pom.xml @@ -9,6 +9,9 @@ 1.17.0 + A suite of utilities that makes batch message processing using AWS Lambda easier. + Powertools for AWS Lambda (Java) batch messages + From b01e3dfa4f23f5a58bc154208fa473f224e8999e Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Mon, 21 Aug 2023 13:55:37 +0100 Subject: [PATCH 03/74] Update to snapshot (#1384) --- examples/pom.xml | 2 +- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-core/cdk/infra/pom.xml | 2 +- examples/powertools-examples-core/sam/pom.xml | 2 +- examples/powertools-examples-idempotency/pom.xml | 2 +- examples/powertools-examples-parameters/pom.xml | 2 +- examples/powertools-examples-serialization/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- examples/powertools-examples-validation/pom.xml | 2 +- pom.xml | 2 +- powertools-batch/pom.xml | 2 +- powertools-cloudformation/pom.xml | 2 +- powertools-core/pom.xml | 2 +- powertools-e2e-tests/handlers/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- powertools-idempotency/pom.xml | 2 +- powertools-large-messages/pom.xml | 2 +- powertools-logging/pom.xml | 2 +- powertools-metrics/pom.xml | 2 +- powertools-parameters/pom.xml | 2 +- powertools-serialization/pom.xml | 2 +- powertools-sqs/pom.xml | 2 +- powertools-test-suite/pom.xml | 2 +- powertools-tracing/pom.xml | 2 +- powertools-validation/pom.xml | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 652a845a5..948005546 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -20,7 +20,7 @@ software.amazon.lambda powertools-examples - 1.17.0 + 1.18.0-SNAPSHOT pom Powertools for AWS Lambda (Java) library Examples diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index aea59e873..dd75b597b 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -5,7 +5,7 @@ 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-batch jar Powertools for AWS Lambda (Java) library Examples - Batch diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 86bd29f93..93cf4acc1 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-cloudformation jar diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 9a7850b93..d81118cde 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -4,7 +4,7 @@ 4.0.0 software.amazon.lambda.examples cdk - 1.17.0 + 1.18.0-SNAPSHOT UTF-8 2.91.0 diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index a21d64910..7350542cd 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-core-sam jar diff --git a/examples/powertools-examples-idempotency/pom.xml b/examples/powertools-examples-idempotency/pom.xml index 1f194eeb2..e9337aafc 100644 --- a/examples/powertools-examples-idempotency/pom.xml +++ b/examples/powertools-examples-idempotency/pom.xml @@ -17,7 +17,7 @@ 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-idempotency jar Powertools for AWS Lambda (Java) library Examples - Idempotency diff --git a/examples/powertools-examples-parameters/pom.xml b/examples/powertools-examples-parameters/pom.xml index 11d5de24a..301247136 100644 --- a/examples/powertools-examples-parameters/pom.xml +++ b/examples/powertools-examples-parameters/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-parameters jar Powertools for AWS Lambda (Java) library Examples - Parameters diff --git a/examples/powertools-examples-serialization/pom.xml b/examples/powertools-examples-serialization/pom.xml index 3674c8b10..18318ff76 100644 --- a/examples/powertools-examples-serialization/pom.xml +++ b/examples/powertools-examples-serialization/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-serialization jar Powertools for AWS Lambda (Java) library Examples - Serialization diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index f676e1a73..5eee08b22 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-sqs jar Powertools for AWS Lambda (Java) library Examples - SQS diff --git a/examples/powertools-examples-validation/pom.xml b/examples/powertools-examples-validation/pom.xml index 3fdb55412..3aa8dad2b 100644 --- a/examples/powertools-examples-validation/pom.xml +++ b/examples/powertools-examples-validation/pom.xml @@ -16,7 +16,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.17.0 + 1.18.0-SNAPSHOT powertools-examples-validation jar Powertools for AWS Lambda (Java) library Examples - Validation diff --git a/pom.xml b/pom.xml index 2bd2f9ad2..d806dcb43 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ software.amazon.lambda powertools-parent - 1.17.0 + 1.18.0-SNAPSHOT pom Powertools for AWS Lambda (Java) library Parent diff --git a/powertools-batch/pom.xml b/powertools-batch/pom.xml index 82d1d57b2..27bb33a42 100644 --- a/powertools-batch/pom.xml +++ b/powertools-batch/pom.xml @@ -6,7 +6,7 @@ software.amazon.lambda powertools-parent - 1.17.0 + 1.18.0-SNAPSHOT A suite of utilities that makes batch message processing using AWS Lambda easier. diff --git a/powertools-cloudformation/pom.xml b/powertools-cloudformation/pom.xml index 99b4a6fdc..1347d95a3 100644 --- a/powertools-cloudformation/pom.xml +++ b/powertools-cloudformation/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java)library Cloudformation diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml index 830405376..a5460031d 100644 --- a/powertools-core/pom.xml +++ b/powertools-core/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library Core diff --git a/powertools-e2e-tests/handlers/pom.xml b/powertools-e2e-tests/handlers/pom.xml index 9b3636dbd..6507e3104 100644 --- a/powertools-e2e-tests/handlers/pom.xml +++ b/powertools-e2e-tests/handlers/pom.xml @@ -10,7 +10,7 @@ Fake handlers that use Powertools for AWS Lambda (Java). - 1.17.0 + 1.18.0-SNAPSHOT UTF-8 1.8 1.8 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 848f7768a..e13cb65fc 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -20,7 +20,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT powertools-e2e-tests diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index 3f205b321..e89df47f7 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -21,7 +21,7 @@ software.amazon.lambda powertools-parent - 1.17.0 + 1.18.0-SNAPSHOT powertools-idempotency diff --git a/powertools-large-messages/pom.xml b/powertools-large-messages/pom.xml index 88ace5b4e..aed8cc2e4 100644 --- a/powertools-large-messages/pom.xml +++ b/powertools-large-messages/pom.xml @@ -23,7 +23,7 @@ software.amazon.lambda powertools-parent - 1.17.0 + 1.18.0-SNAPSHOT powertools-large-messages diff --git a/powertools-logging/pom.xml b/powertools-logging/pom.xml index 5e1ee339c..26ad8c243 100644 --- a/powertools-logging/pom.xml +++ b/powertools-logging/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library Logging diff --git a/powertools-metrics/pom.xml b/powertools-metrics/pom.xml index 253b2596f..cb3acf110 100644 --- a/powertools-metrics/pom.xml +++ b/powertools-metrics/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library Metrics diff --git a/powertools-parameters/pom.xml b/powertools-parameters/pom.xml index 74055614a..f99a3d3cd 100644 --- a/powertools-parameters/pom.xml +++ b/powertools-parameters/pom.xml @@ -21,7 +21,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT powertools-parameters diff --git a/powertools-serialization/pom.xml b/powertools-serialization/pom.xml index 3dd59ba32..b1f228df7 100644 --- a/powertools-serialization/pom.xml +++ b/powertools-serialization/pom.xml @@ -21,7 +21,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT powertools-serialization diff --git a/powertools-sqs/pom.xml b/powertools-sqs/pom.xml index 1e274011d..f824f409d 100644 --- a/powertools-sqs/pom.xml +++ b/powertools-sqs/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library SQS diff --git a/powertools-test-suite/pom.xml b/powertools-test-suite/pom.xml index 4969f171a..80b8635f5 100644 --- a/powertools-test-suite/pom.xml +++ b/powertools-test-suite/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library Test Suite diff --git a/powertools-tracing/pom.xml b/powertools-tracing/pom.xml index afe4cb570..d2f14c3e0 100644 --- a/powertools-tracing/pom.xml +++ b/powertools-tracing/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) library Tracing diff --git a/powertools-validation/pom.xml b/powertools-validation/pom.xml index ad8e192fd..23841777e 100644 --- a/powertools-validation/pom.xml +++ b/powertools-validation/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.17.0 + 1.18.0-SNAPSHOT Powertools for AWS Lambda (Java) validation library From 07c31d3e337d2585a08e9d569654440df8149a92 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Mon, 21 Aug 2023 16:39:44 +0100 Subject: [PATCH 04/74] Fix batch logging (#1387) --- .../main/java/org/demo/batch/kinesis/KinesisBatchHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-batch/src/main/java/org/demo/batch/kinesis/KinesisBatchHandler.java b/examples/powertools-examples-batch/src/main/java/org/demo/batch/kinesis/KinesisBatchHandler.java index d9339549b..b188df501 100644 --- a/examples/powertools-examples-batch/src/main/java/org/demo/batch/kinesis/KinesisBatchHandler.java +++ b/examples/powertools-examples-batch/src/main/java/org/demo/batch/kinesis/KinesisBatchHandler.java @@ -12,7 +12,7 @@ public class KinesisBatchHandler implements RequestHandler { - private final static Logger LOGGER = LogManager.getLogger(org.demo.batch.sqs.SqsBatchHandler.class); + private final static Logger LOGGER = LogManager.getLogger(KinesisBatchHandler.class); private final BatchMessageHandler handler; public KinesisBatchHandler() { From 869192a5756f9a0e54d4c840fd2e79a2bda4a0be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:31:35 +0200 Subject: [PATCH 05/74] build(deps): bump aws.sdk.version from 2.20.130 to 2.20.131 (#1389) Bumps `aws.sdk.version` from 2.20.130 to 2.20.131. Updates `software.amazon.awssdk:bom` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:http-client-spi` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:url-connection-client` from 2.20.128 to 2.20.131 Updates `software.amazon.awssdk:sqs` from 2.20.128 to 2.20.131 Updates `software.amazon.awssdk:s3` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:dynamodb` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:lambda` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:kinesis` from 2.20.128 to 2.20.131 Updates `software.amazon.awssdk:cloudwatch` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:xray` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:cloudformation` from 2.20.130 to 2.20.131 Updates `software.amazon.awssdk:sts` from 2.20.130 to 2.20.131 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 93cf4acc1..4c4a53039 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -16,7 +16,7 @@ true 1.2.3 3.11.2 - 2.20.130 + 2.20.131 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 5eee08b22..8969662a8 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -28,7 +28,7 @@ software.amazon.awssdk url-connection-client - 2.20.130 + 2.20.131 com.amazonaws diff --git a/pom.xml b/pom.xml index d806dcb43..76cdee1f8 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.130 + 2.20.131 2.14.0 2.1.3 UTF-8 From 52a1f48ec7baddb6fc2a756b4e0c74d8cb2913ab Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Tue, 22 Aug 2023 16:24:31 +0100 Subject: [PATCH 06/74] docs: Change link to absolute versioned path for examples (#1374) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change link to absolute versioned path for examples * Update README.md --------- Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e120bfb00..e351b5c0e 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ Next, configure the aspectj-maven-plugin to compile-time weave (CTW) the aws-lam ## Examples -See the **[examples](examples)** directory for example projects showcasing usage of different utilities. +See the latest release of the **[examples](https://github.com/aws-powertools/powertools-lambda-java/tree/v1.17.0/examples)** for example projects showcasing usage of different utilities. Have a demo project to contribute which showcase usage of different utilities from powertools? We are happy to accept it [here](CONTRIBUTING.md#security-issue-notifications). From 7c3e45b81e607c98d64034bc36492795d4eb446e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:52:22 +0200 Subject: [PATCH 07/74] build(deps): bump aws.sdk.version from 2.20.131 to 2.20.132 (#1390) Bumps `aws.sdk.version` from 2.20.131 to 2.20.132. Updates `software.amazon.awssdk:bom` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:http-client-spi` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:url-connection-client` from 2.20.128 to 2.20.132 Updates `software.amazon.awssdk:sqs` from 2.20.128 to 2.20.132 Updates `software.amazon.awssdk:s3` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:dynamodb` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:lambda` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:kinesis` from 2.20.128 to 2.20.132 Updates `software.amazon.awssdk:cloudwatch` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:xray` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:cloudformation` from 2.20.131 to 2.20.132 Updates `software.amazon.awssdk:sts` from 2.20.131 to 2.20.132 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 4c4a53039..bfa183290 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -16,7 +16,7 @@ true 1.2.3 3.11.2 - 2.20.131 + 2.20.132 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 8969662a8..60387f2d3 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -28,7 +28,7 @@ software.amazon.awssdk url-connection-client - 2.20.131 + 2.20.132 com.amazonaws diff --git a/pom.xml b/pom.xml index 76cdee1f8..dd12c2ae7 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.131 + 2.20.132 2.14.0 2.1.3 UTF-8 From 9f67d215865821a288ee8e4c2a9327c5fa3691f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 13:50:29 +0200 Subject: [PATCH 08/74] build(deps): bump aws.sdk.version from 2.20.132 to 2.20.133 (#1392) Bumps `aws.sdk.version` from 2.20.132 to 2.20.133. Updates `software.amazon.awssdk:bom` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:http-client-spi` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:url-connection-client` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:sqs` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:s3` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:dynamodb` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:lambda` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:kinesis` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:cloudwatch` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:xray` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:cloudformation` from 2.20.132 to 2.20.133 Updates `software.amazon.awssdk:sts` from 2.20.132 to 2.20.133 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index bfa183290..20aa5aeaf 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -16,7 +16,7 @@ true 1.2.3 3.11.2 - 2.20.132 + 2.20.133 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 60387f2d3..b030d22fd 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -28,7 +28,7 @@ software.amazon.awssdk url-connection-client - 2.20.132 + 2.20.133 com.amazonaws diff --git a/pom.xml b/pom.xml index dd12c2ae7..8226fa878 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.132 + 2.20.133 2.14.0 2.1.3 UTF-8 From 46124b4fb9d2a53efdff784345ac07d29678a5a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 13:55:56 +0200 Subject: [PATCH 09/74] build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib (#1373) --- examples/powertools-examples-core/cdk/infra/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index d81118cde..5131e22af 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -7,7 +7,7 @@ 1.18.0-SNAPSHOT UTF-8 - 2.91.0 + 2.92.0 [10.0.0,11.0.0) 5.10.0 true diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index e13cb65fc..8fd96030b 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -31,7 +31,7 @@ 1.8 1.8 10.2.69 - 2.91.0 + 2.92.0 true From 1fb444abcd6f51142377dc6f8831151a4f288dd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:06:23 +0200 Subject: [PATCH 10/74] build(deps): bump aws.sdk.version from 2.20.128 to 2.20.133 (#1393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps `aws.sdk.version` from 2.20.128 to 2.20.133. Updates `software.amazon.awssdk:url-connection-client` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:sqs` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:sdk-core` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:kinesis` from 2.20.128 to 2.20.133 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.128 to 2.20.133 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index dd75b597b..9faa4dc24 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -15,7 +15,7 @@ 1.8 1.8 true - 2.20.128 + 2.20.133 From 787aa9d0a811dbf79bef400e718e7171694fb35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:19:52 +0200 Subject: [PATCH 11/74] chore: secure github actions using hash instead of versions (#1232) * secure github actions using hash instead of versions * delete docs.yaml * fix hash for dcos --------- Co-authored-by: Scott Gerring --- .github/workflows/auto-merge.yml | 8 +++--- .github/workflows/build-docs.yml | 4 +-- .github/workflows/build.yml | 8 +++--- .github/workflows/dispatch_analytics.yml | 2 +- .github/workflows/docs.yml | 4 +-- .github/workflows/publish.yml | 9 ++++--- .github/workflows/release-drafter.yml | 2 +- .github/workflows/release-prep.yml | 16 ++++++------ .github/workflows/run-e2e-tests.yml | 6 ++--- .github/workflows/secure_workflows.yml | 32 ++++++++++++++++++++++++ .github/workflows/spotbugs.yml | 6 ++--- 11 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/secure_workflows.yml diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 21b5e20e5..5401eedc9 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -17,12 +17,12 @@ jobs: 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@v3 - - uses: ahmadnassri/action-workflow-run-wait@v1 + - 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@v3.1.0 + uses: actions/github-script@47f7cf65b5ced0830a325f705cad64f2f58dddf7 # v3.1.0 with: script: | var artifacts = await github.actions.listWorkflowRunArtifacts({ @@ -43,7 +43,7 @@ jobs: fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data)); - run: unzip pr.zip - name: Create review - uses: actions/github-script@v3 + uses: actions/github-script@47f7cf65b5ced0830a325f705cad64f2f58dddf7 # v3.1.0 with: script: | var fs = require('fs'); diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index f4a9c4d3f..a4ab6e7de 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -22,9 +22,9 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # v4.6.1 with: python-version: "3.8" - name: Capture branch and tag diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ed871a6c..f9a985fb9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,9 +54,9 @@ jobs: JAVA: ${{ matrix.java }} AWS_REGION: eu-west-1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup java - uses: actions/setup-java@v3 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: distribution: 'corretto' java-version: ${{ matrix.java }} @@ -64,7 +64,7 @@ jobs: - name: Build with Maven run: mvn -B install --file pom.xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # 3.1.1 + 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 @@ -78,7 +78,7 @@ jobs: mkdir -p ./pr echo ${{ github.event.number }} echo ${{ github.event.number }} > ./pr/NR - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 name: Upload artifact with: name: pr diff --git a/.github/workflows/dispatch_analytics.yml b/.github/workflows/dispatch_analytics.yml index 49a276f6f..c93cb5b36 100644 --- a/.github/workflows/dispatch_analytics.yml +++ b/.github/workflows/dispatch_analytics.yml @@ -29,7 +29,7 @@ jobs: environment: analytics steps: - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: aws-region: eu-central-1 role-to-assume: ${{ secrets.AWS_ANALYTICS_ROLE_ARN }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9c09e294d..5e37c5f45 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,9 +16,9 @@ jobs: runs-on: ubuntu-latest environment: Docs steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # v4.6.1 with: python-version: "3.8" - name: Capture branch and tag diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2068c09c5..03f04e0f4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,15 +8,16 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Set up Maven Central Repository - uses: actions/setup-java@v2 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: - distribution: 'zulu' + distribution: 'corretto' java-version: 8 server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD + # TODO: use environments https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase - name: Set release notes tag @@ -30,7 +31,7 @@ jobs: MAVEN_PASSWORD: ${{ secrets.OSSRH_JIRA_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Close issues related to this release - uses: actions/github-script@v5 + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 with: script: | const post_release = require('.github/workflows/post_release.js') diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 5b27fd671..72bd5c24f 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -10,6 +10,6 @@ jobs: update_release_draft: runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@569eb7ee3a85817ab916c8f8ff03a5bd96c9c83e # v5.23.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-prep.yml b/.github/workflows/release-prep.yml index 345bd2a10..f7a3c74c0 100644 --- a/.github/workflows/release-prep.yml +++ b/.github/workflows/release-prep.yml @@ -10,7 +10,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Get current date id: date run: echo "::set-output name=date::$(date +'%Y-%m-%d')" @@ -18,42 +18,42 @@ jobs: run: | echo "CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV - name: Find and Replace ${{ env.CURRENT_VERSION }} with ${{ github.event.inputs.targetRelease }} in mkdocs.yml - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: 'version: ${{ env.CURRENT_VERSION }}' replace: 'version: ${{ github.event.inputs.targetRelease }}' regex: false include: "mkdocs.yml" - name: Find and Replace ${{ env.CURRENT_VERSION }} with ${{ github.event.inputs.targetRelease }} in main pom.xml - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: ${{ env.CURRENT_VERSION }} replace: ${{ github.event.inputs.targetRelease }} regex: false include: "pom.xml" - name: Find and Replace ${{ env.CURRENT_VERSION }} with ${{ github.event.inputs.targetRelease }} in modules pom.xml - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: ${{ env.CURRENT_VERSION }} replace: ${{ github.event.inputs.targetRelease }} regex: false include: "**/*pom.xml" - name: Find and Replace ${{ env.CURRENT_VERSION }} with ${{ github.event.inputs.targetRelease }} in build.gradle - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: ${{ env.CURRENT_VERSION }} replace: ${{ github.event.inputs.targetRelease }} regex: false include: "**/*build.gradle" - name: Find and Replace ${{ env.CURRENT_VERSION }} with ${{ github.event.inputs.targetRelease }} in README.md - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: ${{ env.CURRENT_VERSION }} replace: ${{ github.event.inputs.targetRelease }} regex: false include: "README.md" - name: Create changelog placeholder for ${{ github.event.inputs.targetRelease }} - uses: jacobtomlinson/gha-find-replace@v2 + uses: jacobtomlinson/gha-find-replace@f485fdc3f67a6d87ae6e3d11e41f648c26d7aee3 # v2.0.0 with: find: '## [Unreleased]' replace: | @@ -66,7 +66,7 @@ jobs: regex: false include: CHANGELOG.md - name: Create Release Pull Request - uses: peter-evans/create-pull-request@v3 + uses: peter-evans/create-pull-request@18f7dc018cc2cd597073088f7c7591b9d1c02672 # v3.14.0 with: commit-message: chore:prep release ${{ github.event.inputs.targetRelease }} token: ${{ secrets.RELEASE }} diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 36c9dd97a..c4a8c6fb2 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -41,15 +41,15 @@ jobs: id-token: write # needed to interact with GitHub's OIDC Token endpoint. contents: read steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup java - uses: actions/setup-java@v3 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: distribution: 'corretto' java-version: ${{ matrix.java }} cache: maven - name: Setup AWS credentials - uses: aws-actions/configure-aws-credentials@v1.6.1 + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} aws-region: ${{ env.AWS_DEFAULT_REGION }} diff --git a/.github/workflows/secure_workflows.yml b/.github/workflows/secure_workflows.yml new file mode 100644 index 000000000..1430e91d6 --- /dev/null +++ b/.github/workflows/secure_workflows.yml @@ -0,0 +1,32 @@ +name: Lockdown untrusted workflows + +# PROCESS +# +# 1. Scans for any external GitHub Action being used without version pinning (@ vs @v3) +# 2. Scans for insecure practices for inline bash scripts (shellcheck) +# 3. Fail CI and prevent PRs to be merged if any malpractice is found + +# USAGE +# +# Always triggered on new PR, PR changes and PR merge. + + +on: + push: + paths: + - ".github/workflows/**" + pull_request: + paths: + - ".github/workflows/**" + +jobs: + enforce_pinned_workflows: + name: Harden Security + runs-on: ubuntu-latest + permissions: + contents: read # checkout code and subsequently GitHub action workflows + steps: + - name: Checkout code + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Ensure 3rd party workflows have SHA pinned + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@555a30da2656b4a7cf47b107800bef097723363e # v2.1.3 diff --git a/.github/workflows/spotbugs.yml b/.github/workflows/spotbugs.yml index 0b07bcd81..d314107fa 100644 --- a/.github/workflows/spotbugs.yml +++ b/.github/workflows/spotbugs.yml @@ -23,11 +23,11 @@ jobs: codecheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup java JDK 1.8 - uses: actions/setup-java@v2 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: - distribution: 'zulu' + distribution: 'corretto' java-version: 8 # https://github.com/jwgmeligmeyling/spotbugs-github-action/issues/6 # https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/ From 8d032490a3da5cd891fc80b163a5f9f010c10734 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Thu, 24 Aug 2023 15:09:18 +0100 Subject: [PATCH 12/74] docs: Update gradle configuration readme (#1359) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update gradle configuration readme * Move into configuration * Starting gradle example * Remove * Start again * Update documentation for gradle * Clarify gradle versions a bit better * Starting gradle example * Cleanup gradle example * Build gradle example * Fix build hopefully * Add gradle wrapper * Formatting * Update docs/index.md Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> * Updated README with sam instructions --------- Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- .github/workflows/build.yml | 5 + .gitignore | 2 + README.md | 16 +- docs/index.md | 17 +- examples/powertools-examples-core/README.md | 5 + .../powertools-examples-core/gradle/README.md | 38 +++ .../gradle/build.gradle | 35 +++ .../gradle/events/event.json | 62 +++++ .../gradle/gradle/wrapper/.gitignore | 2 + .../gradle/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63375 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + .../powertools-examples-core/gradle/gradlew | 248 ++++++++++++++++++ .../gradle/gradlew.bat | 92 +++++++ .../gradle/src/main/java/helloworld/App.java | 107 ++++++++ .../src/main/java/helloworld/AppStream.java | 38 +++ .../src/test/java/helloworld/AppTest.java | 24 ++ .../gradle/template.yaml | 71 +++++ 17 files changed, 767 insertions(+), 2 deletions(-) create mode 100644 examples/powertools-examples-core/gradle/README.md create mode 100644 examples/powertools-examples-core/gradle/build.gradle create mode 100644 examples/powertools-examples-core/gradle/events/event.json create mode 100644 examples/powertools-examples-core/gradle/gradle/wrapper/.gitignore create mode 100644 examples/powertools-examples-core/gradle/gradle/wrapper/gradle-wrapper.jar create mode 100644 examples/powertools-examples-core/gradle/gradle/wrapper/gradle-wrapper.properties create mode 100755 examples/powertools-examples-core/gradle/gradlew create mode 100644 examples/powertools-examples-core/gradle/gradlew.bat create mode 100644 examples/powertools-examples-core/gradle/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/gradle/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java create mode 100644 examples/powertools-examples-core/gradle/template.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9a985fb9..73ae67553 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,6 +63,11 @@ jobs: cache: 'maven' - name: Build with Maven run: mvn -B install --file pom.xml + - name: Build Gradle Example + if: ${{ matrix.java == '8' }} # Gradle example can only be built on Java 8 + run: | + cd examples/powertools-examples-core/gradle + ./gradlew build - name: Upload coverage to Codecov uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 if: ${{ matrix.java == '11' }} # publish results once diff --git a/.gitignore b/.gitignore index 04e85211d..b404d2cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,5 @@ example/HelloWorldFunction/.gradle example/HelloWorldFunction/build /example/.gradle/ /example/.java-version +.gradle +build/ \ No newline at end of file diff --git a/README.md b/README.md index e351b5c0e..2afb40e5d 100644 --- a/README.md +++ b/README.md @@ -130,11 +130,18 @@ Next, configure the aspectj-maven-plugin to compile-time weave (CTW) the aws-lam Gradle - Java 11+ ```groovy + plugins { id 'java' - id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0' + id 'io.freefair.aspectj.post-compile-weaving' version '8.2.2' } + // the freefair aspect plugins targets gradle 8.2.1 + // https://docs.freefair.io/gradle-plugins/8.2.2/reference/ + wrapper { + gradleVersion = "8.2.1" + } + repositories { mavenCentral() } @@ -143,6 +150,7 @@ Next, configure the aspectj-maven-plugin to compile-time weave (CTW) the aws-lam aspect 'software.amazon.lambda:powertools-logging:{{ powertools.version }}' aspect 'software.amazon.lambda:powertools-tracing:{{ powertools.version }}' aspect 'software.amazon.lambda:powertools-metrics:{{ powertools.version }}' + implementation "org.aspectj:aspectjrt:1.9.8.RC3" } sourceCompatibility = 11 @@ -159,6 +167,12 @@ Next, configure the aspectj-maven-plugin to compile-time weave (CTW) the aws-lam id 'io.freefair.aspectj.post-compile-weaving' version '6.6.3' } + // the freefair aspect plugins targets gradle 7.6.1 + // https://docs.freefair.io/gradle-plugins/6.6.3/reference/ + wrapper { + gradleVersion = "7.6.1" + } + repositories { mavenCentral() } diff --git a/docs/index.md b/docs/index.md index d3e487174..6af4c5e8d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -211,10 +211,17 @@ Depending on your version of Java (either Java 1.8 or 11+), the configuration sl === "Gradle Java 11+" ```groovy + plugins { id 'java' - id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0' + id 'io.freefair.aspectj.post-compile-weaving' version '8.2.2' } + + // the freefair aspect plugins targets gradle 8.2.1 + // https://docs.freefair.io/gradle-plugins/8.2.2/reference/ + wrapper { + gradleVersion = "8.2.1" + } repositories { mavenCentral() @@ -233,10 +240,18 @@ Depending on your version of Java (either Java 1.8 or 11+), the configuration sl === "Gradle Java 1.8" ```groovy + plugins { id 'java' id 'io.freefair.aspectj.post-compile-weaving' version '6.6.3' } + + // the freefair aspect plugins targets gradle 7.6.1 + // https://docs.freefair.io/gradle-plugins/6.6.3/reference/ + wrapper { + gradleVersion = "7.6.1" + } + repositories { mavenCentral() diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index f11982477..d690b01c5 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -6,9 +6,14 @@ This project demonstrates the Lambda for Powertools Java module - including [metrics](https://docs.powertools.aws.dev/lambda/java/core/metrics/). We provide examples for the following infrastructure-as-code tools: + * [AWS SAM](sam/) * [AWS CDK](cdk/) +We also provide an example showing the integration of SAM, Powertools, and Gradle: + +* [AWS SAM with a Gradle build](gradle/) + For each of the tools, the example application is the same, and consists of the following files: - [App.java](sam/src/main/java/helloworld/App.java) - Code for the application's Lambda function. diff --git a/examples/powertools-examples-core/gradle/README.md b/examples/powertools-examples-core/gradle/README.md new file mode 100644 index 000000000..c7c798d5d --- /dev/null +++ b/examples/powertools-examples-core/gradle/README.md @@ -0,0 +1,38 @@ +# Powertools for AWS Lambda (Java) - Core Utilities Example with Gradle + +This project demonstrates the Lambda for Powertools Java module deployed using [Serverless Application Model](https://aws.amazon.com/serverless/sam/) with +[Gradle](https://gradle.org/) running the build. This example is configured for Java 1.8 only; in order to use a newer version, check out the Gradle +configuration guide [in the main project README](../../../README.md). + +You can also use `sam init` to create a new Gradle-powered Powertools application - choose to use the **AWS Quick Start Templates**, +and then **Hello World Example with Powertools for AWS Lambda**, **Java 17** runtime, and finally **gradle**. + + +For general information on the deployed example itself, you can refer to the parent [README](../README.md) + +## Configuration +SAM uses [template.yaml](template.yaml) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +The build of the project is managed by Gradle, and configured in [build.gradle](build.gradle). + +## Deploy the sample application +To get started, you can use the Gradle wrapper to bootstrap Gradle and run the build: + +```bash +./gradlew build +``` + +Once this is done to deploy the example, check out the instructions for getting started with SAM in +[the examples directory](../../README.md) + +## Additional notes + +You can watch the trace information or log information using the SAM CLI: +```bash +# Tail the logs +sam logs --tail $MY_STACK + +# Tail the traces +sam traces --tail +``` \ No newline at end of file diff --git a/examples/powertools-examples-core/gradle/build.gradle b/examples/powertools-examples-core/gradle/build.gradle new file mode 100644 index 000000000..e7367c246 --- /dev/null +++ b/examples/powertools-examples-core/gradle/build.gradle @@ -0,0 +1,35 @@ + +plugins { + id 'java' + id "io.freefair.aspectj.post-compile-weaving" version "6.6.3" +} + +wrapper { + gradleVersion = "7.6.1" +} + +compileJava { + sourceCompatibility = "1.8" + targetCompatibility = "1.8" + + ajc { + enabled = true + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.2' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2.2' + implementation 'com.amazonaws:aws-lambda-java-events:3.11.0' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2' + aspect 'software.amazon.lambda:powertools-tracing:1.17.0' + aspect 'software.amazon.lambda:powertools-logging:1.17.0' + aspect 'software.amazon.lambda:powertools-metrics:1.17.0' + testImplementation 'junit:junit:4.13.2' +} + diff --git a/examples/powertools-examples-core/gradle/events/event.json b/examples/powertools-examples-core/gradle/events/event.json new file mode 100644 index 000000000..070ad8e01 --- /dev/null +++ b/examples/powertools-examples-core/gradle/events/event.json @@ -0,0 +1,62 @@ +{ + "body": "{\"message\": \"hello world\"}", + "resource": "/{proxy+}", + "path": "/path/to/resource", + "httpMethod": "POST", + "isBase64Encoded": false, + "queryStringParameters": { + "foo": "bar" + }, + "pathParameters": { + "proxy": "/path/to/resource" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "apiId": "1234567890", + "protocol": "HTTP/1.1" + } +} diff --git a/examples/powertools-examples-core/gradle/gradle/wrapper/.gitignore b/examples/powertools-examples-core/gradle/gradle/wrapper/.gitignore new file mode 100644 index 000000000..59c09e205 --- /dev/null +++ b/examples/powertools-examples-core/gradle/gradle/wrapper/.gitignore @@ -0,0 +1,2 @@ +!gradle-wrapper.jar + diff --git a/examples/powertools-examples-core/gradle/gradle/wrapper/gradle-wrapper.jar b/examples/powertools-examples-core/gradle/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..033e24c4cdf41af1ab109bc7f253b2b887023340 GIT binary patch literal 63375 zcmb5VV{~QRw)Y#`wrv{~+qP{x72B%VwzFc}c2cp;N~)5ZbDrJayPv(!dGEd-##*zr z)#n-$y^sH|_dchh3@8{H5D*j;5D<{i*8l5IFJ|DjL!e)upfGNX(kojugZ3I`oH1PvW`wFW_ske0j@lB9bX zO;2)`y+|!@X(fZ1<2n!Qx*)_^Ai@Cv-dF&(vnudG?0CsddG_&Wtae(n|K59ew)6St z#dj7_(Cfwzh$H$5M!$UDd8=4>IQsD3xV=lXUq($;(h*$0^yd+b{qq63f0r_de#!o_ zXDngc>zy`uor)4A^2M#U*DC~i+dc<)Tb1Tv&~Ev@oM)5iJ4Sn#8iRw16XXuV50BS7 zdBL5Mefch(&^{luE{*5qtCZk$oFr3RH=H!c3wGR=HJ(yKc_re_X9pD` zJ;uxPzUfVpgU>DSq?J;I@a+10l0ONXPcDkiYcihREt5~T5Gb}sT0+6Q;AWHl`S5dV>lv%-p9l#xNNy7ZCr%cyqHY%TZ8Q4 zbp&#ov1*$#grNG#1vgfFOLJCaNG@K|2!W&HSh@3@Y%T?3YI75bJp!VP*$*!< z;(ffNS_;@RJ`=c7yX04!u3JP*<8jeqLHVJu#WV&v6wA!OYJS4h<_}^QI&97-;=ojW zQ-1t)7wnxG*5I%U4)9$wlv5Fr;cIizft@&N+32O%B{R1POm$oap@&f| zh+5J{>U6ftv|vAeKGc|zC=kO(+l7_cLpV}-D#oUltScw})N>~JOZLU_0{Ka2e1evz z{^a*ZrLr+JUj;)K&u2CoCAXLC2=fVScI(m_p~0FmF>>&3DHziouln?;sxW`NB}cSX z8?IsJB)Z=aYRz!X=yJn$kyOWK%rCYf-YarNqKzmWu$ZvkP12b4qH zhS9Q>j<}(*frr?z<%9hl*i^#@*O2q(Z^CN)c2c z>1B~D;@YpG?G!Yk+*yn4vM4sO-_!&m6+`k|3zd;8DJnxsBYtI;W3We+FN@|tQ5EW= z!VU>jtim0Mw#iaT8t_<+qKIEB-WwE04lBd%Letbml9N!?SLrEG$nmn7&W(W`VB@5S zaY=sEw2}i@F_1P4OtEw?xj4@D6>_e=m=797#hg}f*l^`AB|Y0# z9=)o|%TZFCY$SzgSjS|8AI-%J4x}J)!IMxY3_KYze`_I=c1nmrk@E8c9?MVRu)7+Ue79|)rBX7tVB7U|w4*h(;Gi3D9le49B38`wuv zp7{4X^p+K4*$@gU(Tq3K1a#3SmYhvI42)GzG4f|u zwQFT1n_=n|jpi=70-yE9LA+d*T8u z`=VmmXJ_f6WmZveZPct$Cgu^~gFiyL>Lnpj*6ee>*0pz=t$IJ}+rE zsf@>jlcG%Wx;Cp5x)YSVvB1$yyY1l&o zvwX=D7k)Dn;ciX?Z)Pn8$flC8#m`nB&(8?RSdBvr?>T9?E$U3uIX7T?$v4dWCa46 z+&`ot8ZTEgp7G+c52oHJ8nw5}a^dwb_l%MOh(ebVj9>_koQP^$2B~eUfSbw9RY$_< z&DDWf2LW;b0ZDOaZ&2^i^g+5uTd;GwO(-bbo|P^;CNL-%?9mRmxEw~5&z=X^Rvbo^WJW=n_%*7974RY}JhFv46> zd}`2|qkd;89l}R;i~9T)V-Q%K)O=yfVKNM4Gbacc7AOd>#^&W&)Xx!Uy5!BHnp9kh z`a(7MO6+Ren#>R^D0K)1sE{Bv>}s6Rb9MT14u!(NpZOe-?4V=>qZ>}uS)!y~;jEUK z&!U7Fj&{WdgU#L0%bM}SYXRtM5z!6M+kgaMKt%3FkjWYh=#QUpt$XX1!*XkpSq-pl zhMe{muh#knk{9_V3%qdDcWDv}v)m4t9 zQhv{;} zc{}#V^N3H>9mFM8`i`0p+fN@GqX+kl|M94$BK3J-X`Hyj8r!#x6Vt(PXjn?N)qedP z=o1T^#?1^a{;bZ&x`U{f?}TMo8ToN zkHj5v|}r}wDEi7I@)Gj+S1aE-GdnLN+$hw!=DzglMaj#{qjXi_dwpr|HL(gcCXwGLEmi|{4&4#OZ4ChceA zKVd4K!D>_N=_X;{poT~4Q+!Le+ZV>=H7v1*l%w`|`Dx8{)McN@NDlQyln&N3@bFpV z_1w~O4EH3fF@IzJ9kDk@7@QctFq8FbkbaH7K$iX=bV~o#gfh?2JD6lZf(XP>~DACF)fGFt)X%-h1yY~MJU{nA5 ze2zxWMs{YdX3q5XU*9hOH0!_S24DOBA5usB+Ws$6{|AMe*joJ?RxfV}*7AKN9V*~J zK+OMcE@bTD>TG1*yc?*qGqjBN8mgg@h1cJLDv)0!WRPIkC` zZrWXrceVw;fB%3`6kq=a!pq|hFIsQ%ZSlo~)D z|64!aCnw-?>}AG|*iOl44KVf8@|joXi&|)1rB;EQWgm+iHfVbgllP$f!$Wf42%NO5b(j9Bw6L z;0dpUUK$5GX4QbMlTmLM_jJt!ur`_0~$b#BB7FL*%XFf<b__1o)Ao3rlobbN8-(T!1d-bR8D3S0@d zLI!*GMb5s~Q<&sjd}lBb8Nr0>PqE6_!3!2d(KAWFxa{hm`@u|a(%#i(#f8{BP2wbs zt+N_slWF4IF_O|{w`c~)Xvh&R{Au~CFmW#0+}MBd2~X}t9lz6*E7uAD`@EBDe$>7W zzPUkJx<`f$0VA$=>R57^(K^h86>09?>_@M(R4q($!Ck6GG@pnu-x*exAx1jOv|>KH zjNfG5pwm`E-=ydcb+3BJwuU;V&OS=6yM^4Jq{%AVqnTTLwV`AorIDD}T&jWr8pB&j28fVtk_y*JRP^t@l*($UZ z6(B^-PBNZ+z!p?+e8@$&jCv^EWLb$WO=}Scr$6SM*&~B95El~;W_0(Bvoha|uQ1T< zO$%_oLAwf1bW*rKWmlD+@CP&$ObiDy=nh1b2ejz%LO9937N{LDe7gle4i!{}I$;&Y zkexJ9Ybr+lrCmKWg&}p=`2&Gf10orS?4$VrzWidT=*6{KzOGMo?KI0>GL0{iFWc;C z+LPq%VH5g}6V@-tg2m{C!-$fapJ9y}c$U}aUmS{9#0CM*8pC|sfer!)nG7Ji>mfRh z+~6CxNb>6eWKMHBz-w2{mLLwdA7dA-qfTu^A2yG1+9s5k zcF=le_UPYG&q!t5Zd_*E_P3Cf5T6821bO`daa`;DODm8Ih8k89=RN;-asHIigj`n=ux>*f!OC5#;X5i;Q z+V!GUy0|&Y_*8k_QRUA8$lHP;GJ3UUD08P|ALknng|YY13)}!!HW@0z$q+kCH%xet zlWf@BXQ=b=4}QO5eNnN~CzWBbHGUivG=`&eWK}beuV*;?zt=P#pM*eTuy3 zP}c#}AXJ0OIaqXji78l;YrP4sQe#^pOqwZUiiN6^0RCd#D271XCbEKpk`HI0IsN^s zES7YtU#7=8gTn#lkrc~6)R9u&SX6*Jk4GFX7){E)WE?pT8a-%6P+zS6o&A#ml{$WX zABFz#i7`DDlo{34)oo?bOa4Z_lNH>n;f0nbt$JfAl~;4QY@}NH!X|A$KgMmEsd^&Y zt;pi=>AID7ROQfr;MsMtClr5b0)xo|fwhc=qk33wQ|}$@?{}qXcmECh>#kUQ-If0$ zseb{Wf4VFGLNc*Rax#P8ko*=`MwaR-DQ8L8V8r=2N{Gaips2_^cS|oC$+yScRo*uF zUO|5=?Q?{p$inDpx*t#Xyo6=s?bbN}y>NNVxj9NZCdtwRI70jxvm3!5R7yiWjREEd zDUjrsZhS|P&|Ng5r+f^kA6BNN#|Se}_GF>P6sy^e8kBrgMv3#vk%m}9PCwUWJg-AD zFnZ=}lbi*mN-AOm zCs)r=*YQAA!`e#1N>aHF=bb*z*hXH#Wl$z^o}x##ZrUc=kh%OHWhp=7;?8%Xj||@V?1c ziWoaC$^&04;A|T)!Zd9sUzE&$ODyJaBpvqsw19Uiuq{i#VK1!htkdRWBnb z`{rat=nHArT%^R>u#CjjCkw-7%g53|&7z-;X+ewb?OLWiV|#nuc8mp*LuGSi3IP<<*Wyo9GKV7l0Noa4Jr0g3p_$ z*R9{qn=?IXC#WU>48-k5V2Oc_>P;4_)J@bo1|pf=%Rcbgk=5m)CJZ`caHBTm3%!Z9 z_?7LHr_BXbKKr=JD!%?KhwdYSdu8XxPoA{n8^%_lh5cjRHuCY9Zlpz8g+$f@bw@0V z+6DRMT9c|>1^3D|$Vzc(C?M~iZurGH2pXPT%F!JSaAMdO%!5o0uc&iqHx?ImcX6fI zCApkzc~OOnfzAd_+-DcMp&AOQxE_EsMqKM{%dRMI5`5CT&%mQO?-@F6tE*xL?aEGZ z8^wH@wRl`Izx4sDmU>}Ym{ybUm@F83qqZPD6nFm?t?(7>h*?`fw)L3t*l%*iw0Qu#?$5eq!Qc zpQvqgSxrd83NsdO@lL6#{%lsYXWen~d3p4fGBb7&5xqNYJ)yn84!e1PmPo7ChVd%4 zHUsV0Mh?VpzZD=A6%)Qrd~i7 z96*RPbid;BN{Wh?adeD_p8YU``kOrGkNox3D9~!K?w>#kFz!4lzOWR}puS(DmfjJD z`x0z|qB33*^0mZdM&6$|+T>fq>M%yoy(BEjuh9L0>{P&XJ3enGpoQRx`v6$txXt#c z0#N?b5%srj(4xmPvJxrlF3H%OMB!jvfy z;wx8RzU~lb?h_}@V=bh6p8PSb-dG|-T#A?`c&H2`_!u+uenIZe`6f~A7r)`9m8atC zt(b|6Eg#!Q*DfRU=Ix`#B_dK)nnJ_+>Q<1d7W)eynaVn`FNuN~%B;uO2}vXr5^zi2 z!ifIF5@Zlo0^h~8+ixFBGqtweFc`C~JkSq}&*a3C}L?b5Mh-bW=e)({F_g4O3 zb@SFTK3VD9QuFgFnK4Ve_pXc3{S$=+Z;;4+;*{H}Rc;845rP?DLK6G5Y-xdUKkA6E3Dz&5f{F^FjJQ(NSpZ8q-_!L3LL@H* zxbDF{gd^U3uD;)a)sJwAVi}7@%pRM&?5IaUH%+m{E)DlA_$IA1=&jr{KrhD5q&lTC zAa3c)A(K!{#nOvenH6XrR-y>*4M#DpTTOGQEO5Jr6kni9pDW`rvY*fs|ItV;CVITh z=`rxcH2nEJpkQ^(;1c^hfb8vGN;{{oR=qNyKtR1;J>CByul*+=`NydWnSWJR#I2lN zTvgnR|MBx*XFsfdA&;tr^dYaqRZp*2NwkAZE6kV@1f{76e56eUmGrZ>MDId)oqSWw z7d&r3qfazg+W2?bT}F)4jD6sWaw`_fXZGY&wnGm$FRPFL$HzVTH^MYBHWGCOk-89y zA+n+Q6EVSSCpgC~%uHfvyg@ufE^#u?JH?<73A}jj5iILz4Qqk5$+^U(SX(-qv5agK znUkfpke(KDn~dU0>gdKqjTkVk`0`9^0n_wzXO7R!0Thd@S;U`y)VVP&mOd-2 z(hT(|$=>4FY;CBY9#_lB$;|Wd$aOMT5O_3}DYXEHn&Jrc3`2JiB`b6X@EUOD zVl0S{ijm65@n^19T3l%>*;F(?3r3s?zY{thc4%AD30CeL_4{8x6&cN}zN3fE+x<9; zt2j1RRVy5j22-8U8a6$pyT+<`f+x2l$fd_{qEp_bfxfzu>ORJsXaJn4>U6oNJ#|~p z`*ZC&NPXl&=vq2{Ne79AkQncuxvbOG+28*2wU$R=GOmns3W@HE%^r)Fu%Utj=r9t` zd;SVOnA(=MXgnOzI2@3SGKHz8HN~Vpx&!Ea+Df~`*n@8O=0!b4m?7cE^K*~@fqv9q zF*uk#1@6Re_<^9eElgJD!nTA@K9C732tV~;B`hzZ321Ph=^BH?zXddiu{Du5*IPg} zqDM=QxjT!Rp|#Bkp$(mL)aar)f(dOAXUiw81pX0DC|Y4;>Vz>>DMshoips^8Frdv} zlTD=cKa48M>dR<>(YlLPOW%rokJZNF2gp8fwc8b2sN+i6&-pHr?$rj|uFgktK@jg~ zIFS(%=r|QJ=$kvm_~@n=ai1lA{7Z}i+zj&yzY+!t$iGUy|9jH#&oTNJ;JW-3n>DF+ z3aCOzqn|$X-Olu_p7brzn`uk1F*N4@=b=m;S_C?#hy{&NE#3HkATrg?enaVGT^$qIjvgc61y!T$9<1B@?_ibtDZ{G zeXInVr5?OD_nS_O|CK3|RzzMmu+8!#Zb8Ik;rkIAR%6?$pN@d<0dKD2c@k2quB%s( zQL^<_EM6ow8F6^wJN1QcPOm|ehA+dP(!>IX=Euz5qqIq}Y3;ibQtJnkDmZ8c8=Cf3 zu`mJ!Q6wI7EblC5RvP*@)j?}W=WxwCvF3*5Up_`3*a~z$`wHwCy)2risye=1mSp%p zu+tD6NAK3o@)4VBsM!@);qgsjgB$kkCZhaimHg&+k69~drbvRTacWKH;YCK(!rC?8 zP#cK5JPHSw;V;{Yji=55X~S+)%(8fuz}O>*F3)hR;STU`z6T1aM#Wd+FP(M5*@T1P z^06O;I20Sk!bxW<-O;E081KRdHZrtsGJflFRRFS zdi5w9OVDGSL3 zNrC7GVsGN=b;YH9jp8Z2$^!K@h=r-xV(aEH@#JicPy;A0k1>g1g^XeR`YV2HfmqXY zYbRwaxHvf}OlCAwHoVI&QBLr5R|THf?nAevV-=~V8;gCsX>jndvNOcFA+DI+zbh~# zZ7`qNk&w+_+Yp!}j;OYxIfx_{f0-ONc?mHCiCUak=>j>~>YR4#w# zuKz~UhT!L~GfW^CPqG8Lg)&Rc6y^{%3H7iLa%^l}cw_8UuG;8nn9)kbPGXS}p3!L_ zd#9~5CrH8xtUd?{d2y^PJg+z(xIfRU;`}^=OlehGN2=?}9yH$4Rag}*+AWotyxfCJ zHx=r7ZH>j2kV?%7WTtp+-HMa0)_*DBBmC{sd$)np&GEJ__kEd`xB5a2A z*J+yx>4o#ZxwA{;NjhU*1KT~=ZK~GAA;KZHDyBNTaWQ1+;tOFFthnD)DrCn`DjBZ% zk$N5B4^$`n^jNSOr=t(zi8TN4fpaccsb`zOPD~iY=UEK$0Y70bG{idLx@IL)7^(pL z{??Bnu=lDeguDrd%qW1)H)H`9otsOL-f4bSu};o9OXybo6J!Lek`a4ff>*O)BDT_g z<6@SrI|C9klY(>_PfA^qai7A_)VNE4c^ZjFcE$Isp>`e5fLc)rg@8Q_d^Uk24$2bn z9#}6kZ2ZxS9sI(RqT7?El2@B+($>eBQrNi_k#CDJ8D9}8$mmm z4oSKO^F$i+NG)-HE$O6s1--6EzJa?C{x=QgK&c=)b(Q9OVoAXYEEH20G|q$}Hue%~ zO3B^bF=t7t48sN zWh_zA`w~|){-!^g?6Mqf6ieV zFx~aPUOJGR=4{KsW7I?<=J2|lY`NTU=lt=%JE9H1vBpkcn=uq(q~=?iBt_-r(PLBM zP-0dxljJO>4Wq-;stY)CLB4q`-r*T$!K2o}?E-w_i>3_aEbA^MB7P5piwt1dI-6o!qWCy0 ztYy!x9arGTS?kabkkyv*yxvsPQ7Vx)twkS6z2T@kZ|kb8yjm+^$|sEBmvACeqbz)RmxkkDQX-A*K!YFziuhwb|ym>C$}U|J)4y z$(z#)GH%uV6{ec%Zy~AhK|+GtG8u@c884Nq%w`O^wv2#A(&xH@c5M`Vjk*SR_tJnq z0trB#aY)!EKW_}{#L3lph5ow=@|D5LzJYUFD6 z7XnUeo_V0DVSIKMFD_T0AqAO|#VFDc7c?c-Q%#u00F%!_TW1@JVnsfvm@_9HKWflBOUD~)RL``-!P;(bCON_4eVdduMO>?IrQ__*zE@7(OX zUtfH@AX*53&xJW*Pu9zcqxGiM>xol0I~QL5B%Toog3Jlenc^WbVgeBvV8C8AX^Vj& z^I}H})B=VboO%q1;aU5ACMh{yK4J;xlMc`jCnZR^!~LDs_MP&8;dd@4LDWw~*>#OT zeZHwdQWS!tt5MJQI~cw|Ka^b4c|qyd_ly(+Ql2m&AAw^ zQeSXDOOH!!mAgzAp0z)DD>6Xo``b6QwzUV@w%h}Yo>)a|xRi$jGuHQhJVA%>)PUvK zBQ!l0hq<3VZ*RnrDODP)>&iS^wf64C;MGqDvx>|p;35%6(u+IHoNbK z;Gb;TneFo*`zUKS6kwF*&b!U8e5m4YAo03a_e^!5BP42+r)LFhEy?_7U1IR<; z^0v|DhCYMSj<-;MtY%R@Fg;9Kky^pz_t2nJfKWfh5Eu@_l{^ph%1z{jkg5jQrkvD< z#vdK!nku*RrH~TdN~`wDs;d>XY1PH?O<4^U4lmA|wUW{Crrv#r%N>7k#{Gc44Fr|t z@UZP}Y-TrAmnEZ39A*@6;ccsR>)$A)S>$-Cj!=x$rz7IvjHIPM(TB+JFf{ehuIvY$ zsDAwREg*%|=>Hw$`us~RP&3{QJg%}RjJKS^mC_!U;E5u>`X`jW$}P`Mf}?7G7FX#{ zE(9u1SO;3q@ZhDL9O({-RD+SqqPX)`0l5IQu4q)49TUTkxR(czeT}4`WV~pV*KY&i zAl3~X%D2cPVD^B43*~&f%+Op)wl<&|D{;=SZwImydWL6@_RJjxP2g)s=dH)u9Npki zs~z9A+3fj0l?yu4N0^4aC5x)Osnm0qrhz@?nwG_`h(71P znbIewljU%T*cC=~NJy|)#hT+lx#^5MuDDnkaMb*Efw9eThXo|*WOQzJ*#3dmRWm@! zfuSc@#kY{Um^gBc^_Xdxnl!n&y&}R4yAbK&RMc+P^Ti;YIUh|C+K1|=Z^{nZ}}rxH*v{xR!i%qO~o zTr`WDE@k$M9o0r4YUFFeQO7xCu_Zgy)==;fCJ94M_rLAv&~NhfvcLWCoaGg2ao~3e zBG?Ms9B+efMkp}7BhmISGWmJsKI@a8b}4lLI48oWKY|8?zuuNc$lt5Npr+p7a#sWu zh!@2nnLBVJK!$S~>r2-pN||^w|fY`CT{TFnJy`B|e5;=+_v4l8O-fkN&UQbA4NKTyntd zqK{xEKh}U{NHoQUf!M=2(&w+eef77VtYr;xs%^cPfKLObyOV_9q<(%76-J%vR>w9!us-0c-~Y?_EVS%v!* z15s2s3eTs$Osz$JayyH|5nPAIPEX=U;r&p;K14G<1)bvn@?bM5kC{am|C5%hyxv}a z(DeSKI5ZfZ1*%dl8frIX2?);R^^~LuDOpNpk-2R8U1w92HmG1m&|j&J{EK=|p$;f9 z7Rs5|jr4r8k5El&qcuM+YRlKny%t+1CgqEWO>3;BSRZi(LA3U%Jm{@{y+A+w(gzA< z7dBq6a1sEWa4cD0W7=Ld9z0H7RI^Z7vl(bfA;72j?SWCo`#5mVC$l1Q2--%V)-uN* z9ha*s-AdfbDZ8R8*fpwjzx=WvOtmSzGFjC#X)hD%Caeo^OWjS(3h|d9_*U)l%{Ab8 zfv$yoP{OuUl@$(-sEVNt{*=qi5P=lpxWVuz2?I7Dc%BRc+NGNw+323^ z5BXGfS71oP^%apUo(Y#xkxE)y?>BFzEBZ}UBbr~R4$%b7h3iZu3S(|A;&HqBR{nK& z$;GApNnz=kNO^FL&nYcfpB7Qg;hGJPsCW44CbkG1@l9pn0`~oKy5S777uH)l{irK!ru|X+;4&0D;VE*Ii|<3P zUx#xUqvZT5kVQxsF#~MwKnv7;1pR^0;PW@$@T7I?s`_rD1EGUdSA5Q(C<>5SzE!vw z;{L&kKFM-MO>hy#-8z`sdVx})^(Dc-dw;k-h*9O2_YZw}|9^y-|8RQ`BWJUJL(Cer zP5Z@fNc>pTXABbTRY-B5*MphpZv6#i802giwV&SkFCR zGMETyUm(KJbh+&$8X*RB#+{surjr;8^REEt`2&Dubw3$mx>|~B5IKZJ`s_6fw zKAZx9&PwBqW1Oz0r0A4GtnZd7XTKViX2%kPfv+^X3|_}RrQ2e3l=KG_VyY`H?I5&CS+lAX5HbA%TD9u6&s#v!G> zzW9n4J%d5ye7x0y`*{KZvqyXUfMEE^ZIffzI=Hh|3J}^yx7eL=s+TPH(Q2GT-sJ~3 zI463C{(ag7-hS1ETtU;_&+49ABt5!A7CwLwe z=SoA8mYZIQeU;9txI=zcQVbuO%q@E)JI+6Q!3lMc=Gbj(ASg-{V27u>z2e8n;Nc*pf}AqKz1D>p9G#QA+7mqqrEjGfw+85Uyh!=tTFTv3|O z+)-kFe_8FF_EkTw!YzwK^Hi^_dV5x-Ob*UWmD-})qKj9@aE8g240nUh=g|j28^?v7 zHRTBo{0KGaWBbyX2+lx$wgXW{3aUab6Bhm1G1{jTC7ota*JM6t+qy)c5<@ zpc&(jVdTJf(q3xB=JotgF$X>cxh7k*(T`-V~AR+`%e?YOeALQ2Qud( zz35YizXt(aW3qndR}fTw1p()Ol4t!D1pitGNL95{SX4ywzh0SF;=!wf=?Q?_h6!f* zh7<+GFi)q|XBsvXZ^qVCY$LUa{5?!CgwY?EG;*)0ceFe&=A;!~o`ae}Z+6me#^sv- z1F6=WNd6>M(~ z+092z>?Clrcp)lYNQl9jN-JF6n&Y0mp7|I0dpPx+4*RRK+VQI~>en0Dc;Zfl+x z_e_b7s`t1_A`RP3$H}y7F9_na%D7EM+**G_Z0l_nwE+&d_kc35n$Fxkd4r=ltRZhh zr9zER8>j(EdV&Jgh(+i}ltESBK62m0nGH6tCBr90!4)-`HeBmz54p~QP#dsu%nb~W z7sS|(Iydi>C@6ZM(Us!jyIiszMkd)^u<1D+R@~O>HqZIW&kearPWmT>63%_t2B{_G zX{&a(gOYJx!Hq=!T$RZ&<8LDnxsmx9+TBL0gTk$|vz9O5GkK_Yx+55^R=2g!K}NJ3 zW?C;XQCHZl7H`K5^BF!Q5X2^Mj93&0l_O3Ea3!Ave|ixx+~bS@Iv18v2ctpSt4zO{ zp#7pj!AtDmti$T`e9{s^jf(ku&E|83JIJO5Qo9weT6g?@vX!{7)cNwymo1+u(YQ94 zopuz-L@|5=h8A!(g-MXgLJC0MA|CgQF8qlonnu#j z;uCeq9ny9QSD|p)9sp3ebgY3rk#y0DA(SHdh$DUm^?GI<>%e1?&}w(b zdip1;P2Z=1wM+$q=TgLP$}svd!vk+BZ@h<^4R=GS2+sri7Z*2f`9 z5_?i)xj?m#pSVchk-SR!2&uNhzEi+#5t1Z$o0PoLGz*pT64%+|Wa+rd5Z}60(j?X= z{NLjtgRb|W?CUADqOS@(*MA-l|E342NxRaxLTDqsOyfWWe%N(jjBh}G zm7WPel6jXijaTiNita+z(5GCO0NM=Melxud57PP^d_U## zbA;9iVi<@wr0DGB8=T9Ab#2K_#zi=$igyK48@;V|W`fg~7;+!q8)aCOo{HA@vpSy-4`^!ze6-~8|QE||hC{ICKllG9fbg_Y7v z$jn{00!ob3!@~-Z%!rSZ0JO#@>|3k10mLK0JRKP-Cc8UYFu>z93=Ab-r^oL2 zl`-&VBh#=-?{l1TatC;VweM^=M7-DUE>m+xO7Xi6vTEsReyLs8KJ+2GZ&rxw$d4IT zPXy6pu^4#e;;ZTsgmG+ZPx>piodegkx2n0}SM77+Y*j^~ICvp#2wj^BuqRY*&cjmL zcKp78aZt>e{3YBb4!J_2|K~A`lN=u&5j!byw`1itV(+Q_?RvV7&Z5XS1HF)L2v6ji z&kOEPmv+k_lSXb{$)of~(BkO^py&7oOzpjdG>vI1kcm_oPFHy38%D4&A4h_CSo#lX z2#oqMCTEP7UvUR3mwkPxbl8AMW(e{ARi@HCYLPSHE^L<1I}OgZD{I#YH#GKnpRmW3 z2jkz~Sa(D)f?V?$gNi?6)Y;Sm{&?~2p=0&BUl_(@hYeX8YjaRO=IqO7neK0RsSNdYjD zaw$g2sG(>JR=8Iz1SK4`*kqd_3-?;_BIcaaMd^}<@MYbYisWZm2C2|Np_l|8r9yM|JkUngSo@?wci(7&O9a z%|V(4C1c9pps0xxzPbXH=}QTxc2rr7fXk$9`a6TbWKPCz&p=VsB8^W96W=BsB|7bc zf(QR8&Ktj*iz)wK&mW`#V%4XTM&jWNnDF56O+2bo<3|NyUhQ%#OZE8$Uv2a@J>D%t zMVMiHh?es!Ex19q&6eC&L=XDU_BA&uR^^w>fpz2_`U87q_?N2y;!Z!bjoeKrzfC)} z?m^PM=(z{%n9K`p|7Bz$LuC7!>tFOuN74MFELm}OD9?%jpT>38J;=1Y-VWtZAscaI z_8jUZ#GwWz{JqvGEUmL?G#l5E=*m>`cY?m*XOc*yOCNtpuIGD+Z|kn4Xww=BLrNYS zGO=wQh}Gtr|7DGXLF%|`G>J~l{k^*{;S-Zhq|&HO7rC_r;o`gTB7)uMZ|WWIn@e0( zX$MccUMv3ABg^$%_lNrgU{EVi8O^UyGHPNRt%R!1#MQJn41aD|_93NsBQhP80yP<9 zG4(&0u7AtJJXLPcqzjv`S~5;Q|5TVGccN=Uzm}K{v)?f7W!230C<``9(64}D2raRU zAW5bp%}VEo{4Rko`bD%Ehf=0voW?-4Mk#d3_pXTF!-TyIt6U+({6OXWVAa;s-`Ta5 zTqx&8msH3+DLrVmQOTBOAj=uoxKYT3DS1^zBXM?1W+7gI!aQNPYfUl{3;PzS9*F7g zWJN8x?KjBDx^V&6iCY8o_gslO16=kh(|Gp)kz8qlQ`dzxQv;)V&t+B}wwdi~uBs4? zu~G|}y!`3;8#vIMUdyC7YEx6bb^1o}G!Jky4cN?BV9ejBfN<&!4M)L&lRKiuMS#3} z_B}Nkv+zzxhy{dYCW$oGC&J(Ty&7%=5B$sD0bkuPmj7g>|962`(Q{ZZMDv%YMuT^KweiRDvYTEop3IgFv#)(w>1 zSzH>J`q!LK)c(AK>&Ib)A{g`Fdykxqd`Yq@yB}E{gnQV$K!}RsgMGWqC3DKE(=!{}ekB3+(1?g}xF>^icEJbc z5bdxAPkW90atZT+&*7qoLqL#p=>t-(-lsnl2XMpZcYeW|o|a322&)yO_8p(&Sw{|b zn(tY$xn5yS$DD)UYS%sP?c|z>1dp!QUD)l;aW#`%qMtQJjE!s2z`+bTSZmLK7SvCR z=@I4|U^sCwZLQSfd*ACw9B@`1c1|&i^W_OD(570SDLK`MD0wTiR8|$7+%{cF&){$G zU~|$^Ed?TIxyw{1$e|D$050n8AjJvvOWhLtLHbSB|HIfhMpqVf>AF&}ZQHhOJ14Bz zww+XL+qP}nww+W`F>b!by|=&a(cM4JIDhsTXY8@|ntQG}-}jm0&Bcj|LV(#sc=BNS zRjh;k9l>EdAFdd)=H!U`~$WP*}~^3HZ_?H>gKw>NBa;tA8M1{>St|)yDF_=~{KEPAGkg3VB`QCHol!AQ0|?e^W?81f{@()Wy!vQ$bY; z0ctx)l7VK83d6;dp!s{Nu=SwXZ8lHQHC*J2g@P0a={B8qHdv(+O3wV=4-t4HK1+smO#=S; z3cSI#Nh+N@AqM#6wPqjDmQM|x95JG|l1#sAU|>I6NdF*G@bD?1t|ytHlkKD+z9}#j zbU+x_cR-j9yX4s{_y>@zk*ElG1yS({BInGJcIT>l4N-DUs6fufF#GlF2lVUNOAhJT zGZThq54GhwCG(h4?yWR&Ax8hU<*U)?g+HY5-@{#ls5CVV(Wc>Bavs|l<}U|hZn z_%m+5i_gaakS*Pk7!v&w3&?R5Xb|AkCdytTY;r+Z7f#Id=q+W8cn)*9tEet=OG+Y} z58U&!%t9gYMx2N=8F?gZhIjtkH!`E*XrVJ?$2rRxLhV1z82QX~PZi8^N5z6~f-MUE zLKxnNoPc-SGl7{|Oh?ZM$jq67sSa)Wr&3)0YxlJt(vKf!-^L)a|HaPv*IYXb;QmWx zsqM>qY;tpK3RH-omtta+Xf2Qeu^$VKRq7`e$N-UCe1_2|1F{L3&}M0XbJ@^xRe&>P zRdKTgD6601x#fkDWkoYzRkxbn#*>${dX+UQ;FbGnTE-+kBJ9KPn)501#_L4O_k`P3 zm+$jI{|EC?8BXJY{P~^f-{**E53k%kVO$%p+=H5DiIdwMmUo>2euq0UzU90FWL!>; z{5@sd0ecqo5j!6AH@g6Mf3keTP$PFztq}@)^ZjK;H6Go$#SV2|2bAFI0%?aXgVH$t zb4Kl`$Xh8qLrMbZUS<2*7^F0^?lrOE=$DHW+O zvLdczsu0^TlA6RhDy3=@s!k^1D~Awulk!Iyo#}W$xq8{yTAK!CLl={H0@YGhg-g~+ z(u>pss4k#%8{J%~%8=H5!T`rqK6w^es-cNVE}=*lP^`i&K4R=peg1tdmT~UAbDKc& zg%Y*1E{hBf<)xO>HDWV7BaMWX6FW4ou1T2m^6{Jb!Su1UaCCYY8RR8hAV$7ho|FyEyP~ zEgK`@%a$-C2`p zV*~G>GOAs*3KN;~IY_UR$ISJxB(N~K>=2C2V6>xTmuX4klRXdrJd&UPAw7&|KEwF8Zcy2j-*({gSNR1^p02Oj88GN9a_Hq;Skdp}kO0;FLbje%2ZvPiltDZgv^ z#pb4&m^!79;O8F+Wr9X71laPY!CdNXG?J6C9KvdAE2xWW1>U~3;0v≫L+crb^Bz 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/examples/powertools-examples-core/gradle/gradlew.bat b/examples/powertools-examples-core/gradle/gradlew.bat new file mode 100644 index 000000000..6689b85be --- /dev/null +++ b/examples/powertools-examples-core/gradle/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/powertools-examples-core/gradle/src/main/java/helloworld/App.java b/examples/powertools-examples-core/gradle/src/main/java/helloworld/App.java new file mode 100644 index 000000000..fccc63b9a --- /dev/null +++ b/examples/powertools-examples-core/gradle/src/main/java/helloworld/App.java @@ -0,0 +1,107 @@ +/* + * 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 helloworld; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; +import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric; +import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.logging.LoggingUtils; +import software.amazon.lambda.powertools.metrics.Metrics; +import software.amazon.lambda.powertools.tracing.CaptureMode; +import software.amazon.lambda.powertools.tracing.Tracing; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Handler for requests to Lambda function. + */ +public class App implements RequestHandler { + private final static Logger log = LogManager.getLogger(App.class); + + @Logging(logEvent = true, samplingRate = 0.7) + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { + Map headers = new HashMap<>(); + + headers.put("Content-Type", "application/json"); + headers.put("X-Custom-Header", "application/json"); + + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); + + LoggingUtils.appendKey("test", "willBeLogged"); + + APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() + .withHeaders(headers); + try { + final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); + log.info(pageContents); + TracingUtils.putAnnotation("Test", "New"); + String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); + + TracingUtils.withSubsegment("loggingResponse", subsegment -> + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (RuntimeException | IOException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + @Tracing + private void log() { + log.info("inside threaded logging for function"); + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + private String getPageContents(String address) throws IOException { + URL url = new URL(address); + putMetadata("getPageContents", address); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } + } +} diff --git a/examples/powertools-examples-core/gradle/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/gradle/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/gradle/src/main/java/helloworld/AppStream.java @@ -0,0 +1,38 @@ +/* + * 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 helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.metrics.Metrics; + +public class AppStream implements RequestStreamHandler { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { + Map map = mapper.readValue(input, Map.class); + + System.out.println(map.size()); + } +} diff --git a/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java new file mode 100644 index 000000000..af3ec1275 --- /dev/null +++ b/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java @@ -0,0 +1,24 @@ +package helloworld; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class AppTest { + @Test + public void successfulResponse() { + App app = new App(); + APIGatewayProxyResponseEvent result = app.handleRequest(null, null); + assertEquals(200, result.getStatusCode().intValue()); + assertEquals("application/json", result.getHeaders().get("Content-Type")); + String content = result.getBody(); + assertNotNull(content); + assertTrue(content.contains("\"message\"")); + assertTrue(content.contains("\"hello world\"")); + assertTrue(content.contains("\"location\"")); + } +} diff --git a/examples/powertools-examples-core/gradle/template.yaml b/examples/powertools-examples-core/gradle/template.yaml new file mode 100644 index 000000000..a717c2998 --- /dev/null +++ b/examples/powertools-examples-core/gradle/template.yaml @@ -0,0 +1,71 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + gradle + + Sample SAM Template for gradle + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 20 + Runtime: java11 + MemorySize: 512 + Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html + Environment: + Variables: + # Powertools for AWS Lambda (Java) env vars: https://docs.powertools.aws.dev/lambda/java/#environment-variables + POWERTOOLS_LOG_LEVEL: INFO + POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1 + POWERTOOLS_LOGGER_LOG_EVENT: true + POWERTOOLS_METRICS_NAMESPACE: Coreutilities + +Resources: + HelloWorldFunction: + Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Properties: + CodeUri: . + Handler: helloworld.App::handleRequest + Runtime: java8 + 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: + POWERTOOLS_SERVICE_NAME: hello + Events: + HelloWorld: + Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api + Properties: + Path: /hello + Method: get + + HelloWorldStreamFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: . + Handler: helloworld.AppStream::handleRequest + Runtime: java8 + MemorySize: 512 + Tracing: Active + Environment: + Variables: + POWERTOOLS_LOGGER_SAMPLE_RATE: 0.7 + Events: + HelloWorld: + Type: Api + Properties: + Path: /hellostream + Method: get + +Outputs: + # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function + # Find out more about other implicit resources you can reference within SAM + # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api + HelloWorldApi: + Description: "API Gateway endpoint URL for Prod stage for Hello World function" + Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" + HelloWorldFunction: + Description: "Hello World Lambda Function ARN" + Value: !GetAtt HelloWorldFunction.Arn + HelloWorldFunctionIamRole: + Description: "Implicit IAM Role created for Hello World function" + Value: !GetAtt HelloWorldFunctionRole.Arn From e35de90f28072814eeb9e6bcb5286c38b8c0338e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Fri, 25 Aug 2023 09:07:00 +0200 Subject: [PATCH 13/74] maven deploy configuration (skip in tests and examples) (#1388) --- examples/pom.xml | 16 +- examples/powertools-examples-batch/pom.xml | 9 +- .../pom.xml | 9 +- .../powertools-examples-core/cdk/app/pom.xml | 9 +- .../cdk/infra/pom.xml | 9 +- examples/powertools-examples-core/sam/pom.xml | 144 +++++++------ .../powertools-examples-idempotency/pom.xml | 202 +++++++++--------- .../powertools-examples-parameters/pom.xml | 75 ++++--- .../powertools-examples-serialization/pom.xml | 9 +- examples/powertools-examples-sqs/pom.xml | 134 ++++++------ .../powertools-examples-validation/pom.xml | 73 ++++--- powertools-e2e-tests/pom.xml | 11 +- powertools-test-suite/pom.xml | 12 +- 13 files changed, 401 insertions(+), 311 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 948005546..eae9e10e5 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -41,9 +41,17 @@ powertools-examples-cloudformation - - - true - + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + \ No newline at end of file diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 9faa4dc24..290fe0cd2 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -14,7 +14,6 @@ 2.20.0 1.8 1.8 - true 2.20.133 @@ -120,6 +119,14 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 20aa5aeaf..030998631 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -13,7 +13,6 @@ 2.20.0 1.8 1.8 - true 1.2.3 3.11.2 2.20.133 @@ -145,6 +144,14 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index a1aba1b8d..7831df839 100644 --- a/examples/powertools-examples-core/cdk/app/pom.xml +++ b/examples/powertools-examples-core/cdk/app/pom.xml @@ -13,7 +13,6 @@ 2.20.0 1.8 1.8 - true @@ -120,6 +119,14 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 5131e22af..cdaccedf4 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -10,7 +10,6 @@ 2.92.0 [10.0.0,11.0.0) 5.10.0 - true @@ -31,6 +30,14 @@ cdk.CdkApp + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index 7350542cd..09cab6cd6 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -1,19 +1,18 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples 1.18.0-SNAPSHOT powertools-examples-core-sam jar - + Powertools for AWS Lambda (Java) library Examples - Core 2.20.0 1.8 1.8 - true @@ -38,9 +37,9 @@ 1.2.3 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -54,72 +53,81 @@ - junit - junit - 4.13.2 - test + junit + junit + 4.13.2 + test - - - dev.aspectj - aspectj-maven-plugin - 1.13.1 - - ${maven.compiler.source} - ${maven.compiler.target} - ${maven.compiler.target} - - - software.amazon.lambda - powertools-tracing - - - software.amazon.lambda - powertools-logging - - - software.amazon.lambda - powertools-metrics - - - - - - - compile - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - - - - - - - - - org.apache.logging.log4j - log4j-transform-maven-shade-plugin-extensions - 0.1.0 - - - - + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - + software.amazon.lambda.examples 1.18.0-SNAPSHOT powertools-examples-idempotency @@ -26,7 +26,6 @@ 2.20.0 1.8 1.8 - true @@ -51,9 +50,9 @@ 1.2.3 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -92,97 +91,106 @@ - - - dev.aspectj - aspectj-maven-plugin - 1.13.1 - - ${maven.compiler.source} - ${maven.compiler.target} - ${maven.compiler.target} - - - software.amazon.lambda - powertools-tracing - - - software.amazon.lambda - powertools-logging - - - software.amazon.lambda - powertools-idempotency - - - - - - - compile - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy - test-compile - - copy-dependencies - - - test - so,dll,dylib - ${project.build.directory}/native-libs - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.1.2 - - - ${project.build.directory}/native-libs - - - idempotency - eu-central-1 - LOG_ERROR - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - - - - - - - - - org.apache.logging.log4j - log4j-transform-maven-shade-plugin-extensions - 0.1.0 - - - - + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-idempotency + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + test-compile + + copy-dependencies + + + test + so,dll,dylib + ${project.build.directory}/native-libs + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + ${project.build.directory}/native-libs + + + idempotency + eu-central-1 + LOG_ERROR + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + - 3.1.2 - - - dev.aspectj - aspectj-maven-plugin - 1.13.1 - - ${maven.compiler.source} - ${maven.compiler.target} - ${maven.compiler.target} - - - software.amazon.lambda - powertools-parameters - - - - - - - compile - - - - - + + + org.apache.maven.plugins + maven-surefire-plugin + + 3.1.2 + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-parameters + + + + + + + compile + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + 3.1.2 + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index b030d22fd..caee0a44d 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples 1.18.0-SNAPSHOT @@ -11,7 +11,6 @@ 2.20.0 1.8 1.8 - true @@ -36,9 +35,9 @@ 1.2.3 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -57,68 +56,77 @@ - junit - junit - 4.13.2 - test + junit + junit + 4.13.2 + test - - - dev.aspectj - aspectj-maven-plugin - 1.13.1 - - ${maven.compiler.source} - ${maven.compiler.target} - ${maven.compiler.target} - - - software.amazon.lambda - powertools-logging - - - software.amazon.lambda - powertools-sqs - - - - - - - compile - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - - - - - - - - - org.apache.logging.log4j - log4j-transform-maven-shade-plugin-extensions - 0.1.0 - - - - + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-sqs + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples 1.18.0-SNAPSHOT @@ -24,7 +24,6 @@ 1.8 1.8 - true @@ -66,37 +65,45 @@ - - - org.apache.maven.plugins - maven-surefire-plugin - - 3.1.2 - - - dev.aspectj - aspectj-maven-plugin - 1.13.1 - - ${maven.compiler.source} - ${maven.compiler.target} - ${maven.compiler.target} - - - software.amazon.lambda - powertools-validation - - - - - - - compile - - - - - + + + org.apache.maven.plugins + maven-surefire-plugin + + 3.1.2 + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-validation + + + + + + + compile + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + - true @@ -183,6 +180,14 @@ org.apache.maven.plugins maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + org.apache.maven.plugins maven-compiler-plugin diff --git a/powertools-test-suite/pom.xml b/powertools-test-suite/pom.xml index 80b8635f5..55e713ec0 100644 --- a/powertools-test-suite/pom.xml +++ b/powertools-test-suite/pom.xml @@ -47,10 +47,6 @@ - - true - - ossrh @@ -159,6 +155,14 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + \ No newline at end of file From 34c6793b5043d09458af88653ba52401c880f92d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 09:17:46 +0200 Subject: [PATCH 14/74] build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib (#1394) Bumps [software.amazon.awscdk:aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.92.0 to 2.93.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/compare/v2.92.0...v2.93.0) --- updated-dependencies: - dependency-name: software.amazon.awscdk:aws-cdk-lib dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-core/cdk/infra/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index cdaccedf4..6facf8a46 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -7,7 +7,7 @@ 1.18.0-SNAPSHOT UTF-8 - 2.92.0 + 2.93.0 [10.0.0,11.0.0) 5.10.0 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 134b71a06..d3acde3ea 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -31,7 +31,7 @@ 1.8 1.8 10.2.69 - 2.92.0 + 2.93.0 From c21d66d3ba2c2adca4b4a2e90a135e1eac6b763c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 13:31:55 +0200 Subject: [PATCH 15/74] build(deps): bump aws.sdk.version from 2.20.133 to 2.20.134 (#1396) Bumps `aws.sdk.version` from 2.20.133 to 2.20.134. Updates `software.amazon.awssdk:bom` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:http-client-spi` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:s3` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:dynamodb` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:lambda` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:cloudwatch` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:xray` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:cloudformation` from 2.20.133 to 2.20.134 Updates `software.amazon.awssdk:sts` from 2.20.133 to 2.20.134 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 030998631..ad84d19a1 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.2 - 2.20.133 + 2.20.134 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index caee0a44d..ac0e577ed 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.20.133 + 2.20.134 com.amazonaws diff --git a/pom.xml b/pom.xml index 8226fa878..9a9b8f05d 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.133 + 2.20.134 2.14.0 2.1.3 UTF-8 From 9f33fed2f62e327f30b38632851ddf891939c9c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 14:18:03 +0200 Subject: [PATCH 16/74] build(deps): bump aws.sdk.version from 2.20.134 to 2.20.135 (#1398) Bumps `aws.sdk.version` from 2.20.134 to 2.20.135. Updates `software.amazon.awssdk:bom` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:http-client-spi` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.135 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.135 Updates `software.amazon.awssdk:s3` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:dynamodb` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:lambda` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.135 Updates `software.amazon.awssdk:cloudwatch` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:xray` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:cloudformation` from 2.20.134 to 2.20.135 Updates `software.amazon.awssdk:sts` from 2.20.134 to 2.20.135 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index ad84d19a1..127c78e66 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.2 - 2.20.134 + 2.20.135 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index ac0e577ed..9692649ec 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.20.134 + 2.20.135 com.amazonaws diff --git a/pom.xml b/pom.xml index 9a9b8f05d..273a4b4a4 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.134 + 2.20.135 2.14.0 2.1.3 UTF-8 From c6932aeb0d0d5689f1c8a5d0f3897c8c69850c3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:09:54 +0200 Subject: [PATCH 17/74] build(deps): bump aws.sdk.version from 2.20.135 to 2.20.136 (#1404) Bumps `aws.sdk.version` from 2.20.135 to 2.20.136. Updates `software.amazon.awssdk:bom` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:http-client-spi` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.136 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.136 Updates `software.amazon.awssdk:s3` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:dynamodb` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:lambda` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.136 Updates `software.amazon.awssdk:cloudwatch` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:xray` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:cloudformation` from 2.20.135 to 2.20.136 Updates `software.amazon.awssdk:sts` from 2.20.135 to 2.20.136 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 127c78e66..1273d8d15 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.2 - 2.20.135 + 2.20.136 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 9692649ec..b2ef7145c 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.20.135 + 2.20.136 com.amazonaws diff --git a/pom.xml b/pom.xml index 273a4b4a4..9066d5880 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.135 + 2.20.136 2.14.0 2.1.3 UTF-8 From 2d7f02449ca2ed863cb4446f14f376ef894c1b1b Mon Sep 17 00:00:00 2001 From: walmsles <2704782+walmsles@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:28:47 +1000 Subject: [PATCH 18/74] docs(logging): align example cloudwatch example to correct output from code: lambda_request_id --> function_request_id (#1411) --- docs/core/logging.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/logging.md b/docs/core/logging.md index 09714a512..2df9a4529 100644 --- a/docs/core/logging.md +++ b/docs/core/logging.md @@ -347,7 +347,7 @@ You can set a Correlation ID using `correlationIdPath` attribute by passing a [J "functionName": "test", "functionMemorySize": 128, "functionArn": "arn:aws:lambda:eu-west-1:12345678910:function:test", - "lambda_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", + "function_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", "correlation_id": "correlation_id_value" } ``` @@ -397,7 +397,7 @@ for known event sources, where either a request ID or X-Ray Trace ID are present "functionName": "test", "functionMemorySize": 128, "functionArn": "arn:aws:lambda:eu-west-1:12345678910:function:test", - "lambda_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", + "function_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", "correlation_id": "correlation_id_value" } ``` @@ -510,7 +510,7 @@ this means that custom keys can be persisted across invocations. If you want all "functionName": "test", "functionMemorySize": 128, "functionArn": "arn:aws:lambda:eu-west-1:12345678910:function:test", - "lambda_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", + "function_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72", "specialKey": "value" } ``` @@ -527,7 +527,7 @@ this means that custom keys can be persisted across invocations. If you want all "functionName": "test", "functionMemorySize": 128, "functionArn": "arn:aws:lambda:eu-west-1:12345678910:function:test", - "lambda_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72" + "function_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72" } ``` From ec48401c0cd230560a55d98702580e8c9c1eb21b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 06:29:33 +0200 Subject: [PATCH 19/74] build(deps): bump aws.sdk.version from 2.20.136 to 2.20.137 (#1406) Bumps `aws.sdk.version` from 2.20.136 to 2.20.137. Updates `software.amazon.awssdk:bom` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:http-client-spi` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.137 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.137 Updates `software.amazon.awssdk:s3` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:dynamodb` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:lambda` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.137 Updates `software.amazon.awssdk:cloudwatch` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:xray` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:cloudformation` from 2.20.136 to 2.20.137 Updates `software.amazon.awssdk:sts` from 2.20.136 to 2.20.137 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 1273d8d15..4e9201aef 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.2 - 2.20.136 + 2.20.137 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index b2ef7145c..7e21bfd28 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.20.136 + 2.20.137 com.amazonaws diff --git a/pom.xml b/pom.xml index 9066d5880..26e9f1612 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.136 + 2.20.137 2.14.0 2.1.3 UTF-8 From 910b4f2e1cffc53321294524c1fc2a45cc485950 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 06:31:32 +0200 Subject: [PATCH 20/74] build(deps): bump com.puppycrawl.tools:checkstyle (#1399) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.2 to 10.12.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.2...checkstyle-10.12.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 26e9f1612..b8a02d2ed 100644 --- a/pom.xml +++ b/pom.xml @@ -561,7 +561,7 @@ com.puppycrawl.tools checkstyle - 10.12.2 + 10.12.3 From 578fd804754d6585db8faecbb3103f60307cacca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:47:24 +0200 Subject: [PATCH 21/74] build(deps): bump aws.sdk.version from 2.20.137 to 2.20.140 (#1412) Bumps `aws.sdk.version` from 2.20.137 to 2.20.140. Updates `software.amazon.awssdk:bom` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:http-client-spi` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:s3` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:dynamodb` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:lambda` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:cloudwatch` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:xray` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:cloudformation` from 2.20.137 to 2.20.140 Updates `software.amazon.awssdk:sts` from 2.20.137 to 2.20.140 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 4e9201aef..142b2e1e9 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.2 - 2.20.137 + 2.20.140 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 7e21bfd28..090905886 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.20.137 + 2.20.140 com.amazonaws diff --git a/pom.xml b/pom.xml index b8a02d2ed..01f63364b 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.137 + 2.20.140 2.14.0 2.1.3 UTF-8 From 6debe05a56717cb8ff9f7f353dfec69f36ed08e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:58:08 +0200 Subject: [PATCH 22/74] build(deps): bump com.amazonaws:aws-lambda-java-events (#1413) Bumps [com.amazonaws:aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs) from 3.11.2 to 3.11.3. - [Commits](https://github.com/aws/aws-lambda-java-libs/commits) --- updated-dependencies: - dependency-name: com.amazonaws:aws-lambda-java-events dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-core/cdk/app/pom.xml | 2 +- examples/powertools-examples-core/sam/pom.xml | 2 +- examples/powertools-examples-idempotency/pom.xml | 2 +- examples/powertools-examples-parameters/pom.xml | 2 +- examples/powertools-examples-serialization/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 142b2e1e9..c63bc9dbe 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -14,7 +14,7 @@ 1.8 1.8 1.2.3 - 3.11.2 + 3.11.3 2.20.140 diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index 7831df839..57397f187 100644 --- a/examples/powertools-examples-core/cdk/app/pom.xml +++ b/examples/powertools-examples-core/cdk/app/pom.xml @@ -39,7 +39,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 org.apache.logging.log4j diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index 09cab6cd6..93c858556 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -39,7 +39,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 org.apache.logging.log4j diff --git a/examples/powertools-examples-idempotency/pom.xml b/examples/powertools-examples-idempotency/pom.xml index 1afce1f29..a98645a29 100644 --- a/examples/powertools-examples-idempotency/pom.xml +++ b/examples/powertools-examples-idempotency/pom.xml @@ -52,7 +52,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 org.apache.logging.log4j diff --git a/examples/powertools-examples-parameters/pom.xml b/examples/powertools-examples-parameters/pom.xml index fe74f859d..deb9c6ba6 100644 --- a/examples/powertools-examples-parameters/pom.xml +++ b/examples/powertools-examples-parameters/pom.xml @@ -31,7 +31,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 diff --git a/examples/powertools-examples-serialization/pom.xml b/examples/powertools-examples-serialization/pom.xml index 7b63d266d..eee3e456a 100644 --- a/examples/powertools-examples-serialization/pom.xml +++ b/examples/powertools-examples-serialization/pom.xml @@ -31,7 +31,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 090905886..65c2e41f3 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -37,7 +37,7 @@ com.amazonaws aws-lambda-java-events - 3.11.2 + 3.11.3 org.apache.logging.log4j diff --git a/pom.xml b/pom.xml index 01f63364b..d66e97397 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 2.1.3 UTF-8 1.2.3 - 3.11.2 + 3.11.3 1.1.2 3.11.0 1.13.1 From 2e769528a662383ece323ea1ef1e471d1f19e362 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 13:36:41 +0200 Subject: [PATCH 23/74] build(deps): bump aws.sdk.version from 2.20.133 to 2.20.140 (#1415) Bumps `aws.sdk.version` from 2.20.133 to 2.20.140. Updates `software.amazon.awssdk:url-connection-client` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:sqs` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:sdk-core` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:kinesis` from 2.20.133 to 2.20.140 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.133 to 2.20.140 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 290fe0cd2..7c0db3174 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.20.133 + 2.20.140 From 9df5830ffdf331e32b743339bd384e2ed7a9c71b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:45:20 +0200 Subject: [PATCH 24/74] build(deps): bump aws.sdk.version from 2.20.140 to 2.20.141 (#1421) Bumps `aws.sdk.version` from 2.20.140 to 2.20.141. Updates `software.amazon.awssdk:bom` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:http-client-spi` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:url-connection-client` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:sqs` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:s3` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:dynamodb` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:lambda` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:kinesis` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:cloudwatch` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:xray` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:cloudformation` from 2.20.140 to 2.20.141 Updates `software.amazon.awssdk:sts` from 2.20.140 to 2.20.141 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index c63bc9dbe..336f79b65 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.3 - 2.20.140 + 2.20.141 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 65c2e41f3..e44f715a7 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.20.140 + 2.20.141 com.amazonaws diff --git a/pom.xml b/pom.xml index d66e97397..009730a4b 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.140 + 2.20.141 2.14.0 2.1.3 UTF-8 From 5d8e8ba78ea5f2e9620604e3ee719d982a27883a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:36:04 +0200 Subject: [PATCH 25/74] build(deps): bump aws.sdk.version from 2.20.140 to 2.20.142 (#1423) Bumps `aws.sdk.version` from 2.20.140 to 2.20.142. Updates `software.amazon.awssdk:url-connection-client` from 2.20.140 to 2.20.142 Updates `software.amazon.awssdk:sqs` from 2.20.140 to 2.20.142 Updates `software.amazon.awssdk:sdk-core` from 2.20.140 to 2.20.142 Updates `software.amazon.awssdk:kinesis` from 2.20.140 to 2.20.142 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.140 to 2.20.142 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 7c0db3174..1e87e9754 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.20.140 + 2.20.142 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index e44f715a7..1dcb9ca6e 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.20.141 + 2.20.142 com.amazonaws From 8935593cf162c3eed93d40098bf5a81fc1b38a21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:08:43 +0200 Subject: [PATCH 26/74] build(deps): bump aws.sdk.version from 2.20.141 to 2.20.143 (#1424) Bumps `aws.sdk.version` from 2.20.141 to 2.20.143. Updates `software.amazon.awssdk:url-connection-client` from 2.20.141 to 2.20.143 Updates `software.amazon.awssdk:sqs` from 2.20.141 to 2.20.143 Updates `software.amazon.awssdk:sdk-core` from 2.20.142 to 2.20.143 Updates `software.amazon.awssdk:kinesis` from 2.20.141 to 2.20.143 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.142 to 2.20.143 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 1e87e9754..7ab895c07 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.20.142 + 2.20.143 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 1dcb9ca6e..12a07a1ce 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.20.142 + 2.20.143 com.amazonaws From f66b46bc953ca2ba46d4d7ddc2fb232d5a2045e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:35:16 +0200 Subject: [PATCH 27/74] build(deps): bump com.github.tomakehurst:wiremock-jre8 (#1426) Bumps [com.github.tomakehurst:wiremock-jre8](https://github.com/wiremock/wiremock) from 2.35.0 to 2.35.1. - [Release notes](https://github.com/wiremock/wiremock/releases) - [Commits](https://github.com/wiremock/wiremock/compare/2.35.0...2.35.1) --- updated-dependencies: - dependency-name: com.github.tomakehurst:wiremock-jre8 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 009730a4b..0bb1de3c6 100644 --- a/pom.xml +++ b/pom.xml @@ -307,7 +307,7 @@ com.github.tomakehurst wiremock-jre8 - 2.35.0 + 2.35.1 test From 6b5b1a4a497e1b9621503f3c539b877508cdf48e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:16:01 +0200 Subject: [PATCH 28/74] build(deps): bump aws.sdk.version from 2.20.141 to 2.20.144 (#1427) Bumps `aws.sdk.version` from 2.20.141 to 2.20.144. Updates `software.amazon.awssdk:bom` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:http-client-spi` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:url-connection-client` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:sqs` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:s3` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:dynamodb` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:lambda` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:kinesis` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:cloudwatch` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:xray` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:cloudformation` from 2.20.141 to 2.20.144 Updates `software.amazon.awssdk:sts` from 2.20.141 to 2.20.144 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 336f79b65..7d49819e4 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.3 - 2.20.141 + 2.20.144 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 12a07a1ce..2ec7a0071 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.20.143 + 2.20.144 com.amazonaws diff --git a/pom.xml b/pom.xml index 0bb1de3c6..e688c5890 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.141 + 2.20.144 2.14.0 2.1.3 UTF-8 From 18294afd40e7200df90e8e256e18d050f1e26957 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Mon, 11 Sep 2023 16:48:26 +0200 Subject: [PATCH 29/74] docs: Fix link to SQS large message migration guide (#1422) * Fix link to SQS large message migration guide * Better --- docs/utilities/sqs_large_message_handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/utilities/sqs_large_message_handling.md b/docs/utilities/sqs_large_message_handling.md index 0924d01cf..9d721f544 100644 --- a/docs/utilities/sqs_large_message_handling.md +++ b/docs/utilities/sqs_large_message_handling.md @@ -6,7 +6,7 @@ description: Utility !!! warning This module is now deprecated and will be removed in version 2. See [Large Message Handling](large_messages.md) and - [the migration guide](http://localhost:8000/lambda-java/utilities/large_messages/#migration-from-the-sqs-large-message-utility) + [the migration guide](large_messages.md#migration-from-the-sqs-large-message-utility) for the new module (`powertools-large-messages`) documentation The large message handling utility handles SQS messages which have had their payloads From 3dfebee220549d4d19a7500bcd483ae01a8f0dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:46:29 +0200 Subject: [PATCH 30/74] fix #1419 (#1420) --- .../persistence/BasePersistenceStore.java | 37 +++++++++---------- .../internal/IdempotencyAspectTest.java | 22 +++++++++++ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java index f58b276fd..a3b1b0ff4 100644 --- a/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java +++ b/powertools-idempotency/src/main/java/software/amazon/lambda/powertools/idempotency/persistence/BasePersistenceStore.java @@ -26,7 +26,6 @@ import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.Map; import java.util.Optional; import java.util.OptionalInt; import java.util.OptionalLong; @@ -122,7 +121,7 @@ public void saveSuccess(JsonNode data, Object result, Instant now) { // missing idempotency key => non-idempotent transaction, we do not store the data, simply return return; } - DataRecord record = new DataRecord( + DataRecord dataRecord = new DataRecord( hashedIdempotencyKey.get(), DataRecord.Status.COMPLETED, getExpiryEpochSecond(now), @@ -130,9 +129,9 @@ public void saveSuccess(JsonNode data, Object result, Instant now) { getHashedPayload(data) ); LOG.debug("Function successfully executed. Saving record to persistence store with idempotency key: {}", - record.getIdempotencyKey()); - updateRecord(record); - saveToCache(record); + dataRecord.getIdempotencyKey()); + updateRecord(dataRecord); + saveToCache(dataRecord); } catch (JsonProcessingException e) { // TODO : throw ? throw new RuntimeException("Error while serializing the response", e); @@ -164,7 +163,7 @@ public void saveInProgress(JsonNode data, Instant now, OptionalInt remainingTime OptionalLong.of(now.plus(remainingTimeInMs.getAsInt(), ChronoUnit.MILLIS).toEpochMilli()); } - DataRecord record = new DataRecord( + DataRecord dataRecord = new DataRecord( idempotencyKey, DataRecord.Status.INPROGRESS, getExpiryEpochSecond(now), @@ -172,8 +171,8 @@ public void saveInProgress(JsonNode data, Instant now, OptionalInt remainingTime getHashedPayload(data), inProgressExpirationMsTimestamp ); - LOG.debug("saving in progress record for idempotency key: {}", record.getIdempotencyKey()); - putRecord(record, now); + LOG.debug("saving in progress record for idempotency key: {}", dataRecord.getIdempotencyKey()); + putRecord(dataRecord, now); } /** @@ -223,10 +222,10 @@ public DataRecord getRecord(JsonNode data, Instant now) return cachedRecord; } - DataRecord record = getRecord(idemPotencyKey); - saveToCache(record); - validatePayload(data, record); - return record; + DataRecord dataRecord = getRecord(idemPotencyKey); + saveToCache(dataRecord); + validatePayload(data, dataRecord); + return dataRecord; } /** @@ -258,10 +257,10 @@ private Optional getHashedIdempotencyKey(JsonNode data) { private boolean isMissingIdemPotencyKey(JsonNode data) { if (data.isContainerNode()) { - Stream> stream = - StreamSupport.stream(Spliterators.spliteratorUnknownSize(data.fields(), Spliterator.ORDERED), + Stream stream = + StreamSupport.stream(Spliterators.spliteratorUnknownSize(data.elements(), Spliterator.ORDERED), false); - return stream.allMatch(e -> e.getValue().isNull()); + return stream.allMatch(JsonNode::isNull); } return data.isNull(); } @@ -378,10 +377,10 @@ private DataRecord retrieveFromCache(String idempotencyKey, Instant now) { return null; } - DataRecord record = cache.get(idempotencyKey); - if (record != null) { - if (!record.isExpired(now)) { - return record; + DataRecord dataRecord = cache.get(idempotencyKey); + if (dataRecord != null) { + if (!dataRecord.isExpired(now)) { + return dataRecord; } LOG.debug("Removing expired local cache record for idempotency key: {}", idempotencyKey); deleteFromCache(idempotencyKey); diff --git a/powertools-idempotency/src/test/java/software/amazon/lambda/powertools/idempotency/internal/IdempotencyAspectTest.java b/powertools-idempotency/src/test/java/software/amazon/lambda/powertools/idempotency/internal/IdempotencyAspectTest.java index 9a30472a8..c72593b66 100644 --- a/powertools-idempotency/src/test/java/software/amazon/lambda/powertools/idempotency/internal/IdempotencyAspectTest.java +++ b/powertools-idempotency/src/test/java/software/amazon/lambda/powertools/idempotency/internal/IdempotencyAspectTest.java @@ -378,6 +378,28 @@ public void idempotencyOnSubMethodAnnotated_keyJMESPath_shouldPutInStoreWithKey( "testFunction.createBasket#a1d0c6e83f027327d8461063f4ac58a6"); } + @Test + public void idempotencyOnSubMethodAnnotated_keyJMESPathArray_shouldPutInStoreWithKey() { + BasePersistenceStore persistenceStore = spy(BasePersistenceStore.class); + + Idempotency.config() + .withPersistenceStore(persistenceStore) + .withConfig(IdempotencyConfig.builder().withEventKeyJMESPath("[id,name]").build()) + .configure(); + + // WHEN + IdempotencyInternalFunctionInternalKey function = new IdempotencyInternalFunctionInternalKey(); + Product p = new Product(42, "fake product", 12); + function.handleRequest(p, context); + + // THEN + ArgumentCaptor recordCaptor = ArgumentCaptor.forClass(DataRecord.class); + verify(persistenceStore).putRecord(recordCaptor.capture(), any()); + // eec7cd392d9e3bb20deb2c9676697c3c = MD5([42,"fake product"]) + assertThat(recordCaptor.getValue().getIdempotencyKey()).isEqualTo( + "testFunction.createBasket#eec7cd392d9e3bb20deb2c9676697c3c"); + } + @Test public void idempotencyOnSubMethodNotAnnotated_shouldThrowException() { Idempotency.config() From aa56890302ea9270f0fd559b7804637fba749ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 13:37:54 +0200 Subject: [PATCH 31/74] build(deps): bump aws.sdk.version from 2.20.143 to 2.20.145 (#1429) Bumps `aws.sdk.version` from 2.20.143 to 2.20.145. Updates `software.amazon.awssdk:url-connection-client` from 2.20.143 to 2.20.145 Updates `software.amazon.awssdk:sqs` from 2.20.143 to 2.20.145 Updates `software.amazon.awssdk:sdk-core` from 2.20.143 to 2.20.145 Updates `software.amazon.awssdk:kinesis` from 2.20.143 to 2.20.145 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.143 to 2.20.145 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 7ab895c07..1dbb5b789 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.20.143 + 2.20.145 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 2ec7a0071..caceab211 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.20.144 + 2.20.145 com.amazonaws From 270b78fcdba4552b6efb0f8f3b6f3d8f73b41954 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 13:30:44 +0200 Subject: [PATCH 32/74] build(deps): bump aws.sdk.version from 2.20.144 to 2.20.146 (#1430) Bumps `aws.sdk.version` from 2.20.144 to 2.20.146. Updates `software.amazon.awssdk:bom` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:http-client-spi` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:url-connection-client` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:sqs` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:s3` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:dynamodb` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:lambda` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:kinesis` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:cloudwatch` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:xray` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:cloudformation` from 2.20.144 to 2.20.146 Updates `software.amazon.awssdk:sts` from 2.20.144 to 2.20.146 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 7d49819e4..5c01f3ce9 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.3 - 2.20.144 + 2.20.146 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index caceab211..5ae2f8b80 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.20.145 + 2.20.146 com.amazonaws diff --git a/pom.xml b/pom.xml index e688c5890..5bfa33373 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.144 + 2.20.146 2.14.0 2.1.3 UTF-8 From ff4571f359a870b2040befde9fa0df10cd287670 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:35:35 +0200 Subject: [PATCH 33/74] build(deps): bump aws.sdk.version from 2.20.146 to 2.20.147 (#1431) Bumps `aws.sdk.version` from 2.20.146 to 2.20.147. Updates `software.amazon.awssdk:bom` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:http-client-spi` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:url-connection-client` from 2.20.145 to 2.20.147 Updates `software.amazon.awssdk:sqs` from 2.20.145 to 2.20.147 Updates `software.amazon.awssdk:s3` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:dynamodb` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:lambda` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:kinesis` from 2.20.145 to 2.20.147 Updates `software.amazon.awssdk:cloudwatch` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:xray` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:cloudformation` from 2.20.146 to 2.20.147 Updates `software.amazon.awssdk:sts` from 2.20.146 to 2.20.147 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 5c01f3ce9..dbb53f497 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.3 - 2.20.146 + 2.20.147 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 5ae2f8b80..75dd2472c 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.20.146 + 2.20.147 com.amazonaws diff --git a/pom.xml b/pom.xml index 5bfa33373..ba83e3d34 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.146 + 2.20.147 2.14.0 2.1.3 UTF-8 From 23b779d65a4044d9b369a7ecbf4e3e704c343f71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:45:05 +0200 Subject: [PATCH 34/74] build(deps): bump aws.sdk.version from 2.20.147 to 2.20.148 (#1433) Bumps `aws.sdk.version` from 2.20.147 to 2.20.148. Updates `software.amazon.awssdk:bom` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:http-client-spi` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:url-connection-client` from 2.20.145 to 2.20.148 Updates `software.amazon.awssdk:sqs` from 2.20.145 to 2.20.148 Updates `software.amazon.awssdk:s3` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:dynamodb` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:lambda` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:kinesis` from 2.20.145 to 2.20.148 Updates `software.amazon.awssdk:cloudwatch` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:xray` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:cloudformation` from 2.20.147 to 2.20.148 Updates `software.amazon.awssdk:sts` from 2.20.147 to 2.20.148 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index dbb53f497..bdc55ab17 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.3 - 2.20.147 + 2.20.148 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 75dd2472c..1041242ff 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.20.147 + 2.20.148 com.amazonaws diff --git a/pom.xml b/pom.xml index ba83e3d34..ae79a72a1 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.147 + 2.20.148 2.14.0 2.1.3 UTF-8 From 4b0b5a862ce5921413a9440997f61ea4e1b297d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:47:39 +0200 Subject: [PATCH 35/74] build(deps): bump aws.sdk.version from 2.20.145 to 2.20.149 (#1436) Bumps `aws.sdk.version` from 2.20.145 to 2.20.149. Updates `software.amazon.awssdk:url-connection-client` from 2.20.145 to 2.20.149 Updates `software.amazon.awssdk:sqs` from 2.20.145 to 2.20.149 Updates `software.amazon.awssdk:sdk-core` from 2.20.145 to 2.20.149 Updates `software.amazon.awssdk:kinesis` from 2.20.145 to 2.20.149 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.145 to 2.20.149 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 1dbb5b789..031b9c6d8 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.20.145 + 2.20.149 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 1041242ff..a59f6193b 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.20.148 + 2.20.149 com.amazonaws From 61db38619d2178ec01175e357bbdf0a1cbbcc168 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:04:11 +0200 Subject: [PATCH 36/74] build(deps): bump aws.sdk.version from 2.20.148 to 2.20.150 (#1437) Bumps `aws.sdk.version` from 2.20.148 to 2.20.150. Updates `software.amazon.awssdk:bom` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:http-client-spi` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:url-connection-client` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:sqs` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:s3` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:dynamodb` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:lambda` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:kinesis` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:cloudwatch` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:xray` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:cloudformation` from 2.20.148 to 2.20.150 Updates `software.amazon.awssdk:sts` from 2.20.148 to 2.20.150 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index bdc55ab17..37b4c56a1 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.3 - 2.20.148 + 2.20.150 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index a59f6193b..0d932a53c 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.20.149 + 2.20.150 com.amazonaws diff --git a/pom.xml b/pom.xml index ae79a72a1..e36616b3a 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.148 + 2.20.150 2.14.0 2.1.3 UTF-8 From 49f2469667592227c0cbf5e9d4efaefbafa43981 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 13:37:38 +0200 Subject: [PATCH 37/74] build(deps): bump aws.sdk.version from 2.20.150 to 2.20.151 (#1438) Bumps `aws.sdk.version` from 2.20.150 to 2.20.151. Updates `software.amazon.awssdk:bom` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:http-client-spi` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:url-connection-client` from 2.20.149 to 2.20.151 Updates `software.amazon.awssdk:sqs` from 2.20.149 to 2.20.151 Updates `software.amazon.awssdk:s3` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:dynamodb` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:lambda` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:kinesis` from 2.20.149 to 2.20.151 Updates `software.amazon.awssdk:cloudwatch` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:xray` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:cloudformation` from 2.20.150 to 2.20.151 Updates `software.amazon.awssdk:sts` from 2.20.150 to 2.20.151 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 37b4c56a1..6db211489 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.3 - 2.20.150 + 2.20.151 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 0d932a53c..6a2d9e6cf 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.20.150 + 2.20.151 com.amazonaws diff --git a/pom.xml b/pom.xml index e36616b3a..809f2af72 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.150 + 2.20.151 2.14.0 2.1.3 UTF-8 From 15d7a99a82e6703deee017727b35947977e51b7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 14:05:20 +0200 Subject: [PATCH 38/74] build(deps): bump aws.sdk.version from 2.20.149 to 2.20.152 (#1439) Bumps `aws.sdk.version` from 2.20.149 to 2.20.152. Updates `software.amazon.awssdk:url-connection-client` from 2.20.149 to 2.20.152 Updates `software.amazon.awssdk:sqs` from 2.20.149 to 2.20.152 Updates `software.amazon.awssdk:sdk-core` from 2.20.149 to 2.20.152 Updates `software.amazon.awssdk:kinesis` from 2.20.149 to 2.20.152 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.149 to 2.20.152 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 031b9c6d8..ea5d1e5f1 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.20.149 + 2.20.152 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 6a2d9e6cf..d9fa8fff1 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.20.151 + 2.20.152 com.amazonaws From 07d91184d5ff58169023c330d1c57e96f861014a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 13:44:45 +0200 Subject: [PATCH 39/74] build(deps): bump aws.sdk.version from 2.20.151 to 2.20.152 (#1440) Bumps `aws.sdk.version` from 2.20.151 to 2.20.152. Updates `software.amazon.awssdk:bom` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:http-client-spi` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:url-connection-client` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:sqs` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:s3` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:dynamodb` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:lambda` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:kinesis` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:cloudwatch` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:xray` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:cloudformation` from 2.20.151 to 2.20.152 Updates `software.amazon.awssdk:sts` from 2.20.151 to 2.20.152 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 6db211489..6b8e90ebd 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.3 - 2.20.151 + 2.20.152 diff --git a/pom.xml b/pom.xml index 809f2af72..a74e13fc2 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.151 + 2.20.152 2.14.0 2.1.3 UTF-8 From 49ae687b6580c9cc693b234a4b5187c6a17bb9cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:03:57 +0200 Subject: [PATCH 40/74] build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib (#1443) Bumps [software.amazon.awscdk:aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.93.0 to 2.97.1. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/compare/v2.93.0...v2.97.1) --- updated-dependencies: - dependency-name: software.amazon.awscdk:aws-cdk-lib dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-core/cdk/infra/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 6facf8a46..99598ba58 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -7,7 +7,7 @@ 1.18.0-SNAPSHOT UTF-8 - 2.93.0 + 2.97.1 [10.0.0,11.0.0) 5.10.0 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index d3acde3ea..c09d03c61 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -31,7 +31,7 @@ 1.8 1.8 10.2.69 - 2.93.0 + 2.97.1 From 6a94862bda9f26209f5762fc439f1076e23b19a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:14:30 +0200 Subject: [PATCH 41/74] build(deps-dev): bump software.constructs:constructs (#1407) Bumps [software.constructs:constructs](https://github.com/aws/constructs) from 10.2.69 to 10.2.70. - [Release notes](https://github.com/aws/constructs/releases) - [Commits](https://github.com/aws/constructs/compare/v10.2.69...v10.2.70) --- updated-dependencies: - dependency-name: software.constructs:constructs dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- powertools-e2e-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index c09d03c61..90427b797 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -30,7 +30,7 @@ 1.8 1.8 - 10.2.69 + 10.2.70 2.97.1 From 24393d8b3e27d2cef6654e12653766236bc70e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:13:26 +0200 Subject: [PATCH 42/74] chore: Reporting size of the jars in GitHub comments (#1196) * reporting size of the jars in the github comments --- .github/workflows/pr_artifacts_size.yml | 57 +++++++++++++++++++ .github/workflows/{build.yml => pr_build.yml} | 0 pom.xml | 8 +++ 3 files changed, 65 insertions(+) create mode 100644 .github/workflows/pr_artifacts_size.yml rename .github/workflows/{build.yml => pr_build.yml} (100%) diff --git a/.github/workflows/pr_artifacts_size.yml b/.github/workflows/pr_artifacts_size.yml new file mode 100644 index 000000000..cbacd78da --- /dev/null +++ b/.github/workflows/pr_artifacts_size.yml @@ -0,0 +1,57 @@ +name: Artifacts Size + +on: + pull_request: + branches: + - master + paths: + - 'powertools-cloudformation/**' + - 'powertools-core/**' + - 'powertools-serialization/**' + - 'powertools-logging/**' + - 'powertools-sqs/**' + - 'powertools-tracing/**' + - 'powertools-validation/**' + - 'powertools-parameters/**' + - 'powertools-idempotency/**' + - 'powertools-metrics/**' + - 'pom.xml' +jobs: + codecheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Setup java JDK 11 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + with: + distribution: 'corretto' + java-version: 11 + - name: Build with Maven + run: mvn clean package --file pom.xml -DskipTests + - name: Get artifacts size & build report + id: artifacts-size-report + run: | + echo '## :floppy_disk: Artifacts Size Report' > report.md + echo '| Module | Version | Size (KB) |' >> report.md + echo '| --- | --- | --- |' >> report.md + artifact_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + for artifact in $(cat target/powertools-parent-*.buildinfo | grep 'outputs.*.jar' | grep -v 'sources.jar'); do + artifact_name=$(echo "$artifact" | cut -d '=' -f2) + artifact_name=${artifact_name%-$artifact_version.jar} + artifact_size=$(grep "${artifact%%.filename*}.length" target/powertools-parent-*.buildinfo | cut -d '=' -f2) + printf "| %s | %s | %.2f |\n" "$artifact_name" "$artifact_version" "$(bc <<< "scale=2; $artifact_size/1000")" >> report.md + done + - name: Find potential existing report + uses: peter-evans/find-comment@a54c31d7fa095754bfef525c0c8e5e5674c4b4b1 # 2.4.0 + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: Artifacts Size Report + - name: Write artifacts size report in comment + uses: peter-evans/create-or-update-comment@c6c9a1a66007646a28c153e2a8580a5bad27bcfa # 3.0.2 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body-path: 'report.md' + edit-mode: replace \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/pr_build.yml similarity index 100% rename from .github/workflows/build.yml rename to .github/workflows/pr_build.yml diff --git a/pom.xml b/pom.xml index a74e13fc2..36abf162e 100644 --- a/pom.xml +++ b/pom.xml @@ -368,6 +368,14 @@ false + + org.apache.maven.plugins + maven-artifact-plugin + 3.4.1 + + true + + dev.aspectj aspectj-maven-plugin From c862a8c53cbbf0988e0e6763a21e787837edffc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:26:55 +0200 Subject: [PATCH 43/74] build(deps): bump aws.sdk.version from 2.20.152 to 2.20.153 (#1441) Bumps `aws.sdk.version` from 2.20.152 to 2.20.153. --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 6b8e90ebd..8fdcb8c08 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.3 - 2.20.152 + 2.20.153 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index d9fa8fff1..c0c302757 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.20.152 + 2.20.153 com.amazonaws diff --git a/pom.xml b/pom.xml index 36abf162e..9e23dcef2 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.152 + 2.20.153 2.14.0 2.1.3 UTF-8 From dd364dd6bbd93523e9669d2fd14eda377d9739a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:15:44 +0200 Subject: [PATCH 44/74] build(deps): bump com.github.spotbugs:spotbugs-maven-plugin (#1448) Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.7.3.5 to 4.7.3.6. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.7.3.5...spotbugs-maven-plugin-4.7.3.6) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e23dcef2..4f4ccb2bd 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.7.3.5 + 4.7.3.6 test From 4d3484fdea1a519f06569ef688efd2bf32a689b8 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 28 Sep 2023 08:12:20 +0100 Subject: [PATCH 45/74] docs: Add Serveless Framework example (#1363) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial * Add memory size and timeouts, same as SAM examples * Add useful Serverless commands * Remove redundant function * Update examples/powertools-examples-core/serverless/README.md Co-authored-by: Scott Gerring * Update examples/powertools-examples-core/serverless/README.md Co-authored-by: Scott Gerring * Update examples/powertools-examples-core/serverless/README.md Co-authored-by: Scott Gerring * Update examples/powertools-examples-core/serverless/README.md Co-authored-by: Scott Gerring * Update examples/powertools-examples-core/serverless/README.md Co-authored-by: Scott Gerring * Remove reduntant command from README * Move most of Powertools configuration to the service-wide environment * Remove more generated comments * Add newlines * Comment out annotations that are preceded by environment variables * Add link to the Serverless example * Update examples/powertools-examples-core/serverless/pom.xml Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> * Update examples/powertools-examples-core/serverless/pom.xml Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> * Update examples/powertools-examples-core/serverless/pom.xml Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> * Remove POWERTOOLS_LOGGER_LOG_EVENT, since it's unsupported --------- Co-authored-by: Scott Gerring Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/README.md | 1 + examples/pom.xml | 1 + examples/powertools-examples-core/README.md | 1 + .../serverless/README.md | 26 +++ .../serverless/pom.xml | 209 ++++++++++++++++++ .../serverless/serverless.yml | 40 ++++ .../src/main/java/helloworld/App.java | 105 +++++++++ .../src/main/java/helloworld/AppStream.java | 38 ++++ .../serverless/src/main/resources/log4j2.xml | 16 ++ .../src/test/java/helloworld/AppTest.java | 59 +++++ 10 files changed, 496 insertions(+) create mode 100644 examples/powertools-examples-core/serverless/README.md create mode 100644 examples/powertools-examples-core/serverless/pom.xml create mode 100644 examples/powertools-examples-core/serverless/serverless.yml create mode 100644 examples/powertools-examples-core/serverless/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/serverless/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/serverless/src/main/resources/log4j2.xml create mode 100644 examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java diff --git a/examples/README.md b/examples/README.md index 0744c2bb1..52dc0c1e9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,6 +8,7 @@ Each example can be copied from its subdirectory and used independently of the r * [powertools-examples-core](powertools-examples-core) - Demonstrates the core logging, tracing, and metrics modules with different build tools * [SAM](./powertools-examples-core/sam) * [CDK](./powertools-examples-core/cdk) + * [Serverless](./powertools-examples-core/serverless) * [powertools-examples-idempotency](powertools-examples-idempotency) - An idempotent HTTP API * [powertools-examples-parameters](powertools-examples-parameters) - Uses the parameters module to provide runtime parameters to a function * [powertools-examples-serialization](powertools-examples-serialization) - Uses the serialization module to serialize and deserialize API Gateway & SQS payloads diff --git a/examples/pom.xml b/examples/pom.xml index eae9e10e5..810ec1b36 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -32,6 +32,7 @@ powertools-examples-core/sam powertools-examples-core/cdk/app powertools-examples-core/cdk/infra + powertools-examples-core/serverless powertools-examples-idempotency powertools-examples-parameters powertools-examples-serialization diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index d690b01c5..1d1dd031f 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -9,6 +9,7 @@ We provide examples for the following infrastructure-as-code tools: * [AWS SAM](sam/) * [AWS CDK](cdk/) +* [Serverless framework](serverless/) We also provide an example showing the integration of SAM, Powertools, and Gradle: diff --git a/examples/powertools-examples-core/serverless/README.md b/examples/powertools-examples-core/serverless/README.md new file mode 100644 index 000000000..aec093182 --- /dev/null +++ b/examples/powertools-examples-core/serverless/README.md @@ -0,0 +1,26 @@ +# Powertools for AWS Lambda (Java) - Core Utilities Example with Serverless Framework + +This project demonstrates the Lambda for Powertools Java module deployed using [Serverless Framework](https://www.serverless.com/framework). +For general information on the deployed example itself, you can refer to the parent [README](../README.md). +To install Serverless Framework if you don't have it yet, you can follow the [Getting Started Guide](https://www.serverless.com/framework/docs/getting-started). + +## Configuration +Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. + + +## Deploy the sample application + +To deploy the app, simply run the following commands: +```bash +mvn package && sls deploy +``` + +## Useful commands + +Deploy a single function +```bash +sls deploy function -f hello +``` \ No newline at end of file diff --git a/examples/powertools-examples-core/serverless/pom.xml b/examples/powertools-examples-core/serverless/pom.xml new file mode 100644 index 000000000..793318da3 --- /dev/null +++ b/examples/powertools-examples-core/serverless/pom.xml @@ -0,0 +1,209 @@ + + 4.0.0 + + software.amazon.lambda.examples + 1.18.0-SNAPSHOT + powertools-examples-core-serverless + jar + + Powertools for AWS Lambda (Java) library Examples - Core + + + 2.20.0 + 1.8 + 1.8 + + + + + software.amazon.lambda + powertools-tracing + ${project.version} + + + software.amazon.lambda + powertools-logging + ${project.version} + + + software.amazon.lambda + powertools-metrics + ${project.version} + + + com.amazonaws + aws-lambda-java-core + 1.2.2 + + + com.amazonaws + aws-lambda-java-events + 3.11.2 + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + + junit + junit + 4.13.2 + test + + + + + helloworld-lambda + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + + com.github.edwgiz + maven-shade-plugin.log4j2-cachefile-transformer + 2.15 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + + + jdk8 + + (,11) + + + 1.9.7 + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + test-compile + + + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + + diff --git a/examples/powertools-examples-core/serverless/serverless.yml b/examples/powertools-examples-core/serverless/serverless.yml new file mode 100644 index 000000000..d8dec8080 --- /dev/null +++ b/examples/powertools-examples-core/serverless/serverless.yml @@ -0,0 +1,40 @@ +service: hello +# app and org for use with dashboard.serverless.com +#app: your-app-name +#org: your-org-name + +# You can pin your service to only deploy with a specific Serverless version +# Check out our docs for more details +frameworkVersion: '3' + +provider: + name: aws + runtime: java11 + +# you can overwrite defaults here +# stage: dev +# region: us-east-1 + +# you can define service wide environment variables here + environment: + POWERTOOLS_LOG_LEVEL: INFO + POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1 + POWERTOOLS_METRICS_NAMESPACE: Coreutilities + +# you can add packaging information here +package: + artifact: target/helloworld-lambda.jar + +functions: + hello: + handler: helloworld.App + memorySize: 512 + timeout: 20 + tracing: "Active" + events: + - httpApi: + path: /hello + method: get +# Define function environment variables here + environment: + POWERTOOLS_SERVICE_NAME: hello diff --git a/examples/powertools-examples-core/serverless/src/main/java/helloworld/App.java b/examples/powertools-examples-core/serverless/src/main/java/helloworld/App.java new file mode 100644 index 000000000..dacd7f1d4 --- /dev/null +++ b/examples/powertools-examples-core/serverless/src/main/java/helloworld/App.java @@ -0,0 +1,105 @@ +/* + * 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 helloworld; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; +import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric; +import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.logging.LoggingUtils; +import software.amazon.lambda.powertools.metrics.Metrics; +import software.amazon.lambda.powertools.tracing.CaptureMode; +import software.amazon.lambda.powertools.tracing.Tracing; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Handler for requests to Lambda function. + */ +public class App implements RequestHandler { + private final static Logger log = LogManager.getLogger(App.class); + + // This is controlled by POWERTOOLS_LOGGER_SAMPLE_RATE environment variable + // @Logging(logEvent = true, samplingRate = 0.7) + // This is controlled by POWERTOOLS_METRICS_NAMESPACE environment variable + // @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + // This is controlled by POWERTOOLS_TRACER_CAPTURE_ERROR environment variable + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { + Map headers = new HashMap<>(); + + headers.put("Content-Type", "application/json"); + headers.put("X-Custom-Header", "application/json"); + + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); + + LoggingUtils.appendKey("test", "willBeLogged"); + + APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() + .withHeaders(headers); + try { + final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); + log.info(pageContents); + TracingUtils.putAnnotation("Test", "New"); + String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); + + TracingUtils.withSubsegment("loggingResponse", subsegment -> + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (RuntimeException | IOException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + private String getPageContents(String address) throws IOException { + URL url = new URL(address); + putMetadata("getPageContents", address); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } + } +} diff --git a/examples/powertools-examples-core/serverless/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/serverless/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/serverless/src/main/java/helloworld/AppStream.java @@ -0,0 +1,38 @@ +/* + * 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 helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.metrics.Metrics; + +public class AppStream implements RequestStreamHandler { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { + Map map = mapper.readValue(input, Map.class); + + System.out.println(map.size()); + } +} diff --git a/examples/powertools-examples-core/serverless/src/main/resources/log4j2.xml b/examples/powertools-examples-core/serverless/src/main/resources/log4j2.xml new file mode 100644 index 000000000..0cc0953f0 --- /dev/null +++ b/examples/powertools-examples-core/serverless/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java new file mode 100644 index 000000000..70dad8d71 --- /dev/null +++ b/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java @@ -0,0 +1,59 @@ +/* + * 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 helloworld; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.xray.AWSXRay; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class AppTest { + + @Before + public void setup() { + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.beginSegment("test"); + } + } + + @After + public void tearDown() { + if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { + AWSXRay.endSubsegment(); + } + + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.endSegment(); + } + } + + @Test + public void successfulResponse() { + App app = new App(); + APIGatewayProxyResponseEvent result = app.handleRequest(null, null); + assertEquals(result.getStatusCode().intValue(), 200); + assertEquals(result.getHeaders().get("Content-Type"), "application/json"); + String content = result.getBody(); + assertNotNull(content); + assertTrue(content.contains("\"message\"")); + assertTrue(content.contains("\"hello world\"")); + assertTrue(content.contains("\"location\"")); + } +} From fa75c7499ab2a8566ad90e6f10dfe84bb873dd1d Mon Sep 17 00:00:00 2001 From: Alexander Schueren Date: Mon, 2 Oct 2023 11:48:09 +0200 Subject: [PATCH 46/74] docs: apply line highlight only for default light mode (#1453) --- docs/stylesheets/extra.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index de2f3b5f9..d135d7210 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -3,7 +3,9 @@ } .highlight .hll { - background-color: lavender + [data-md-color-scheme="default"] { + background-color: lavender; + } } .md-typeset table:not([class]) { From 1140fcfb2ceb16a701608ec82dc255142ac6c815 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Thu, 5 Oct 2023 17:54:53 +0200 Subject: [PATCH 47/74] fix: Fix schema validation unit test build issues (#1456) * Is it just the one test? * What about this * Temporary fix --- .../validation/ValidationUtilsTest.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java index fa0d1394c..cd6ad160c 100644 --- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java +++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java @@ -70,12 +70,19 @@ public void testLoadMetaSchema_NoValidation() { }); } - @Test - public void testLoadMetaSchemaV2019() { - ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V201909); - JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V201909", true); - assertThat(jsonSchema).isNotNull(); - } + /** + * TODO - get this going again on github; commented out to unblock build, and seems to run outside of github + * workers still. See here --> + * + * https://github.com/aws-powertools/powertools-lambda-java/actions/runs/6417845031/job/17424409856?pr=1456 + * https://github.com/aws-powertools/powertools-lambda-java/issues/1455 + */ +// @Test +// public void testLoadMetaSchemaV2019() { +// ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V201909); +// JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V201909", true); +// assertThat(jsonSchema).isNotNull(); +// } @Test public void testLoadMetaSchemaV7() { From 3ea3fa101a5a6a6228051abc70958c10b5374c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:59:29 +0200 Subject: [PATCH 48/74] Use URITranslator to use local files instead of remote (#1457) Remove local schema files, use the ones provided in the dependency Add support for 202012 Update tests --- .../validation/ValidationConfig.java | 2 +- .../validation/ValidationUtils.java | 13 +- .../main/resources/schemas/meta/applicator | 56 ------ .../src/main/resources/schemas/meta/content | 17 -- .../src/main/resources/schemas/meta/core | 57 ------ .../src/main/resources/schemas/meta/format | 14 -- .../src/main/resources/schemas/meta/meta-data | 37 ---- .../main/resources/schemas/meta/validation | 98 ---------- .../resources/schemas/meta_schema_V201909 | 42 ----- .../src/main/resources/schemas/meta_schema_V4 | 149 --------------- .../src/main/resources/schemas/meta_schema_V6 | 155 ---------------- .../src/main/resources/schemas/meta_schema_V7 | 172 ------------------ .../validation/ValidationUtilsTest.java | 34 ++-- 13 files changed, 27 insertions(+), 819 deletions(-) delete mode 100644 powertools-validation/src/main/resources/schemas/meta/applicator delete mode 100644 powertools-validation/src/main/resources/schemas/meta/content delete mode 100644 powertools-validation/src/main/resources/schemas/meta/core delete mode 100644 powertools-validation/src/main/resources/schemas/meta/format delete mode 100644 powertools-validation/src/main/resources/schemas/meta/meta-data delete mode 100644 powertools-validation/src/main/resources/schemas/meta/validation delete mode 100644 powertools-validation/src/main/resources/schemas/meta_schema_V201909 delete mode 100644 powertools-validation/src/main/resources/schemas/meta_schema_V4 delete mode 100644 powertools-validation/src/main/resources/schemas/meta_schema_V6 delete mode 100644 powertools-validation/src/main/resources/schemas/meta_schema_V7 diff --git a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java index baf5e2465..143f0584d 100644 --- a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java +++ b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java @@ -49,7 +49,7 @@ public SpecVersion.VersionFlag getSchemaVersion() { /** * Set the version of the json schema specifications (default is V7) * - * @param version May be V4, V6, V7 or V201909 + * @param version May be V4, V6, V7, V201909 or V202012 */ public void setSchemaVersion(SpecVersion.VersionFlag version) { if (version != jsonSchemaVersion) { diff --git a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java index 4eecb3ab5..221e5fb1d 100644 --- a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java +++ b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java @@ -21,7 +21,9 @@ import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.NullNode; import com.networknt.schema.JsonSchema; +import com.networknt.schema.SchemaValidatorsConfig; import com.networknt.schema.ValidationMessage; +import com.networknt.schema.uri.URITranslator; import io.burt.jmespath.Expression; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -257,7 +259,10 @@ private static JsonSchema createJsonSchema(String schema) { String filePath = schema.substring(CLASSPATH.length()); try (InputStream schemaStream = ValidationAspect.class.getResourceAsStream(filePath)) { - jsonSchema = ValidationConfig.get().getFactory().getSchema(schemaStream); + SchemaValidatorsConfig config = new SchemaValidatorsConfig(); + config.addUriTranslator(URITranslator.prefix("https://json-schema.org", "resource:")); + + jsonSchema = ValidationConfig.get().getFactory().getSchema(schemaStream, config); } catch (Exception e) { throw new IllegalArgumentException( "'" + schema + "' is invalid, verify '" + filePath + "' is in your classpath"); @@ -270,13 +275,13 @@ private static JsonSchema createJsonSchema(String schema) { } private static void validateSchema(String schema, JsonSchema jsonSchema) { - String version = ValidationConfig.get().getSchemaVersion().toString(); + String schemaId = ValidationConfig.get().getSchemaVersion().getId().replace("https://json-schema.org", ""); try { validate(jsonSchema.getSchemaNode(), - getJsonSchema("classpath:/schemas/meta_schema_" + version)); + getJsonSchema(CLASSPATH + schemaId)); } catch (ValidationException ve) { throw new IllegalArgumentException( - "The schema " + schema + " is not valid, it does not respect the specification " + version, ve); + "The schema " + schema + " is not valid, it does not respect the specification " + schemaId, ve); } } diff --git a/powertools-validation/src/main/resources/schemas/meta/applicator b/powertools-validation/src/main/resources/schemas/meta/applicator deleted file mode 100644 index 24a1cc4f4..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/applicator +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/applicator", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/applicator": true - }, - "$recursiveAnchor": true, - - "title": "Applicator vocabulary meta-schema", - "type": ["object", "boolean"], - "properties": { - "additionalItems": { "$recursiveRef": "#" }, - "unevaluatedItems": { "$recursiveRef": "#" }, - "items": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "#/$defs/schemaArray" } - ] - }, - "contains": { "$recursiveRef": "#" }, - "additionalProperties": { "$recursiveRef": "#" }, - "unevaluatedProperties": { "$recursiveRef": "#" }, - "properties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "propertyNames": { "format": "regex" }, - "default": {} - }, - "dependentSchemas": { - "type": "object", - "additionalProperties": { - "$recursiveRef": "#" - } - }, - "propertyNames": { "$recursiveRef": "#" }, - "if": { "$recursiveRef": "#" }, - "then": { "$recursiveRef": "#" }, - "else": { "$recursiveRef": "#" }, - "allOf": { "$ref": "#/$defs/schemaArray" }, - "anyOf": { "$ref": "#/$defs/schemaArray" }, - "oneOf": { "$ref": "#/$defs/schemaArray" }, - "not": { "$recursiveRef": "#" } - }, - "$defs": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$recursiveRef": "#" } - } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta/content b/powertools-validation/src/main/resources/schemas/meta/content deleted file mode 100644 index f6752a8ef..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/content +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/content", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/content": true - }, - "$recursiveAnchor": true, - - "title": "Content vocabulary meta-schema", - - "type": ["object", "boolean"], - "properties": { - "contentMediaType": { "type": "string" }, - "contentEncoding": { "type": "string" }, - "contentSchema": { "$recursiveRef": "#" } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta/core b/powertools-validation/src/main/resources/schemas/meta/core deleted file mode 100644 index eb708a560..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/core +++ /dev/null @@ -1,57 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/core", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/core": true - }, - "$recursiveAnchor": true, - - "title": "Core vocabulary meta-schema", - "type": ["object", "boolean"], - "properties": { - "$id": { - "type": "string", - "format": "uri-reference", - "$comment": "Non-empty fragments not allowed.", - "pattern": "^[^#]*#?$" - }, - "$schema": { - "type": "string", - "format": "uri" - }, - "$anchor": { - "type": "string", - "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" - }, - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "$recursiveRef": { - "type": "string", - "format": "uri-reference" - }, - "$recursiveAnchor": { - "type": "boolean", - "default": false - }, - "$vocabulary": { - "type": "object", - "propertyNames": { - "type": "string", - "format": "uri" - }, - "additionalProperties": { - "type": "boolean" - } - }, - "$comment": { - "type": "string" - }, - "$defs": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta/format b/powertools-validation/src/main/resources/schemas/meta/format deleted file mode 100644 index 09bbfdda9..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/format +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/format", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/format": true - }, - "$recursiveAnchor": true, - - "title": "Format vocabulary meta-schema", - "type": ["object", "boolean"], - "properties": { - "format": { "type": "string" } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta/meta-data b/powertools-validation/src/main/resources/schemas/meta/meta-data deleted file mode 100644 index da04cff6d..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/meta-data +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/meta-data": true - }, - "$recursiveAnchor": true, - - "title": "Meta-data vocabulary meta-schema", - - "type": ["object", "boolean"], - "properties": { - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "default": true, - "deprecated": { - "type": "boolean", - "default": false - }, - "readOnly": { - "type": "boolean", - "default": false - }, - "writeOnly": { - "type": "boolean", - "default": false - }, - "examples": { - "type": "array", - "items": true - } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta/validation b/powertools-validation/src/main/resources/schemas/meta/validation deleted file mode 100644 index 9f59677b3..000000000 --- a/powertools-validation/src/main/resources/schemas/meta/validation +++ /dev/null @@ -1,98 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/meta/validation", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/validation": true - }, - "$recursiveAnchor": true, - - "title": "Validation vocabulary meta-schema", - "type": ["object", "boolean"], - "properties": { - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0 - }, - "maximum": { - "type": "number" - }, - "exclusiveMaximum": { - "type": "number" - }, - "minimum": { - "type": "number" - }, - "exclusiveMinimum": { - "type": "number" - }, - "maxLength": { "$ref": "#/$defs/nonNegativeInteger" }, - "minLength": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, - "pattern": { - "type": "string", - "format": "regex" - }, - "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, - "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, - "uniqueItems": { - "type": "boolean", - "default": false - }, - "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, - "minContains": { - "$ref": "#/$defs/nonNegativeInteger", - "default": 1 - }, - "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, - "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, - "required": { "$ref": "#/$defs/stringArray" }, - "dependentRequired": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/stringArray" - } - }, - "const": true, - "enum": { - "type": "array", - "items": true - }, - "type": { - "anyOf": [ - { "$ref": "#/$defs/simpleTypes" }, - { - "type": "array", - "items": { "$ref": "#/$defs/simpleTypes" }, - "minItems": 1, - "uniqueItems": true - } - ] - } - }, - "$defs": { - "nonNegativeInteger": { - "type": "integer", - "minimum": 0 - }, - "nonNegativeIntegerDefault0": { - "$ref": "#/$defs/nonNegativeInteger", - "default": 0 - }, - "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "uniqueItems": true, - "default": [] - } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta_schema_V201909 b/powertools-validation/src/main/resources/schemas/meta_schema_V201909 deleted file mode 100644 index 2248a0c80..000000000 --- a/powertools-validation/src/main/resources/schemas/meta_schema_V201909 +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://json-schema.org/draft/2019-09/schema", - "$vocabulary": { - "https://json-schema.org/draft/2019-09/vocab/core": true, - "https://json-schema.org/draft/2019-09/vocab/applicator": true, - "https://json-schema.org/draft/2019-09/vocab/validation": true, - "https://json-schema.org/draft/2019-09/vocab/meta-data": true, - "https://json-schema.org/draft/2019-09/vocab/format": false, - "https://json-schema.org/draft/2019-09/vocab/content": true - }, - "$recursiveAnchor": true, - - "title": "Core and Validation specifications meta-schema", - "allOf": [ - {"$ref": "meta/core"}, - {"$ref": "meta/applicator"}, - {"$ref": "meta/validation"}, - {"$ref": "meta/meta-data"}, - {"$ref": "meta/format"}, - {"$ref": "meta/content"} - ], - "type": ["object", "boolean"], - "properties": { - "definitions": { - "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - }, - "dependencies": { - "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", - "type": "object", - "additionalProperties": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "meta/validation#/$defs/stringArray" } - ] - } - } - } -} diff --git a/powertools-validation/src/main/resources/schemas/meta_schema_V4 b/powertools-validation/src/main/resources/schemas/meta_schema_V4 deleted file mode 100644 index bcbb84743..000000000 --- a/powertools-validation/src/main/resources/schemas/meta_schema_V4 +++ /dev/null @@ -1,149 +0,0 @@ -{ - "id": "http://json-schema.org/draft-04/schema#", - "$schema": "http://json-schema.org/draft-04/schema#", - "description": "Core schema meta-schema", - "definitions": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$ref": "#" } - }, - "positiveInteger": { - "type": "integer", - "minimum": 0 - }, - "positiveIntegerDefault0": { - "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] - }, - "simpleTypes": { - "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "minItems": 1, - "uniqueItems": true - } - }, - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "$schema": { - "type": "string" - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "default": {}, - "multipleOf": { - "type": "number", - "minimum": 0, - "exclusiveMinimum": true - }, - "maximum": { - "type": "number" - }, - "exclusiveMaximum": { - "type": "boolean", - "default": false - }, - "minimum": { - "type": "number" - }, - "exclusiveMinimum": { - "type": "boolean", - "default": false - }, - "maxLength": { "$ref": "#/definitions/positiveInteger" }, - "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, - "pattern": { - "type": "string", - "format": "regex" - }, - "additionalItems": { - "anyOf": [ - { "type": "boolean" }, - { "$ref": "#" } - ], - "default": {} - }, - "items": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/schemaArray" } - ], - "default": {} - }, - "maxItems": { "$ref": "#/definitions/positiveInteger" }, - "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, - "uniqueItems": { - "type": "boolean", - "default": false - }, - "maxProperties": { "$ref": "#/definitions/positiveInteger" }, - "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, - "required": { "$ref": "#/definitions/stringArray" }, - "additionalProperties": { - "anyOf": [ - { "type": "boolean" }, - { "$ref": "#" } - ], - "default": {} - }, - "definitions": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "properties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "dependencies": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/stringArray" } - ] - } - }, - "enum": { - "type": "array", - "minItems": 1, - "uniqueItems": true - }, - "type": { - "anyOf": [ - { "$ref": "#/definitions/simpleTypes" }, - { - "type": "array", - "items": { "$ref": "#/definitions/simpleTypes" }, - "minItems": 1, - "uniqueItems": true - } - ] - }, - "format": { "type": "string" }, - "allOf": { "$ref": "#/definitions/schemaArray" }, - "anyOf": { "$ref": "#/definitions/schemaArray" }, - "oneOf": { "$ref": "#/definitions/schemaArray" }, - "not": { "$ref": "#" } - }, - "dependencies": { - "exclusiveMaximum": [ "maximum" ], - "exclusiveMinimum": [ "minimum" ] - }, - "default": {} -} diff --git a/powertools-validation/src/main/resources/schemas/meta_schema_V6 b/powertools-validation/src/main/resources/schemas/meta_schema_V6 deleted file mode 100644 index bd3e763bc..000000000 --- a/powertools-validation/src/main/resources/schemas/meta_schema_V6 +++ /dev/null @@ -1,155 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-06/schema#", - "$id": "http://json-schema.org/draft-06/schema#", - "title": "Core schema meta-schema", - "definitions": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$ref": "#" } - }, - "nonNegativeInteger": { - "type": "integer", - "minimum": 0 - }, - "nonNegativeIntegerDefault0": { - "allOf": [ - { "$ref": "#/definitions/nonNegativeInteger" }, - { "default": 0 } - ] - }, - "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "uniqueItems": true, - "default": [] - } - }, - "type": ["object", "boolean"], - "properties": { - "$id": { - "type": "string", - "format": "uri-reference" - }, - "$schema": { - "type": "string", - "format": "uri" - }, - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "default": {}, - "examples": { - "type": "array", - "items": {} - }, - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0 - }, - "maximum": { - "type": "number" - }, - "exclusiveMaximum": { - "type": "number" - }, - "minimum": { - "type": "number" - }, - "exclusiveMinimum": { - "type": "number" - }, - "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, - "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "pattern": { - "type": "string", - "format": "regex" - }, - "additionalItems": { "$ref": "#" }, - "items": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/schemaArray" } - ], - "default": {} - }, - "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, - "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "uniqueItems": { - "type": "boolean", - "default": false - }, - "contains": { "$ref": "#" }, - "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, - "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "required": { "$ref": "#/definitions/stringArray" }, - "additionalProperties": { "$ref": "#" }, - "definitions": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "properties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "propertyNames": { "format": "regex" }, - "default": {} - }, - "dependencies": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/stringArray" } - ] - } - }, - "propertyNames": { "$ref": "#" }, - "const": {}, - "enum": { - "type": "array", - "minItems": 1, - "uniqueItems": true - }, - "type": { - "anyOf": [ - { "$ref": "#/definitions/simpleTypes" }, - { - "type": "array", - "items": { "$ref": "#/definitions/simpleTypes" }, - "minItems": 1, - "uniqueItems": true - } - ] - }, - "format": { "type": "string" }, - "allOf": { "$ref": "#/definitions/schemaArray" }, - "anyOf": { "$ref": "#/definitions/schemaArray" }, - "oneOf": { "$ref": "#/definitions/schemaArray" }, - "not": { "$ref": "#" } - }, - "default": {} -} diff --git a/powertools-validation/src/main/resources/schemas/meta_schema_V7 b/powertools-validation/src/main/resources/schemas/meta_schema_V7 deleted file mode 100644 index fb92c7f75..000000000 --- a/powertools-validation/src/main/resources/schemas/meta_schema_V7 +++ /dev/null @@ -1,172 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://json-schema.org/draft-07/schema#", - "title": "Core schema meta-schema", - "definitions": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$ref": "#" } - }, - "nonNegativeInteger": { - "type": "integer", - "minimum": 0 - }, - "nonNegativeIntegerDefault0": { - "allOf": [ - { "$ref": "#/definitions/nonNegativeInteger" }, - { "default": 0 } - ] - }, - "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "uniqueItems": true, - "default": [] - } - }, - "type": ["object", "boolean"], - "properties": { - "$id": { - "type": "string", - "format": "uri-reference" - }, - "$schema": { - "type": "string", - "format": "uri" - }, - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "$comment": { - "type": "string" - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "default": true, - "readOnly": { - "type": "boolean", - "default": false - }, - "writeOnly": { - "type": "boolean", - "default": false - }, - "examples": { - "type": "array", - "items": true - }, - "multipleOf": { - "type": "number", - "exclusiveMinimum": 0 - }, - "maximum": { - "type": "number" - }, - "exclusiveMaximum": { - "type": "number" - }, - "minimum": { - "type": "number" - }, - "exclusiveMinimum": { - "type": "number" - }, - "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, - "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "pattern": { - "type": "string", - "format": "regex" - }, - "additionalItems": { "$ref": "#" }, - "items": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/schemaArray" } - ], - "default": true - }, - "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, - "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "uniqueItems": { - "type": "boolean", - "default": false - }, - "contains": { "$ref": "#" }, - "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, - "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, - "required": { "$ref": "#/definitions/stringArray" }, - "additionalProperties": { "$ref": "#" }, - "definitions": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "properties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$ref": "#" }, - "propertyNames": { "format": "regex" }, - "default": {} - }, - "dependencies": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { "$ref": "#" }, - { "$ref": "#/definitions/stringArray" } - ] - } - }, - "propertyNames": { "$ref": "#" }, - "const": true, - "enum": { - "type": "array", - "items": true, - "minItems": 1, - "uniqueItems": true - }, - "type": { - "anyOf": [ - { "$ref": "#/definitions/simpleTypes" }, - { - "type": "array", - "items": { "$ref": "#/definitions/simpleTypes" }, - "minItems": 1, - "uniqueItems": true - } - ] - }, - "format": { "type": "string" }, - "contentMediaType": { "type": "string" }, - "contentEncoding": { "type": "string" }, - "if": { "$ref": "#" }, - "then": { "$ref": "#" }, - "else": { "$ref": "#" }, - "allOf": { "$ref": "#/definitions/schemaArray" }, - "anyOf": { "$ref": "#/definitions/schemaArray" }, - "oneOf": { "$ref": "#/definitions/schemaArray" }, - "not": { "$ref": "#" } - }, - "default": true -} diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java index cd6ad160c..d80670669 100644 --- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java +++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java @@ -57,7 +57,7 @@ public void testLoadSchemaV7KO() { assertThatThrownBy(() -> getJsonSchema("classpath:/schema_v7_ko.json", true)) .isInstanceOf(IllegalArgumentException.class) .hasMessage( - "The schema classpath:/schema_v7_ko.json is not valid, it does not respect the specification V7"); + "The schema classpath:/schema_v7_ko.json is not valid, it does not respect the specification /draft-07/schema"); } @Test @@ -70,38 +70,38 @@ public void testLoadMetaSchema_NoValidation() { }); } - /** - * TODO - get this going again on github; commented out to unblock build, and seems to run outside of github - * workers still. See here --> - * - * https://github.com/aws-powertools/powertools-lambda-java/actions/runs/6417845031/job/17424409856?pr=1456 - * https://github.com/aws-powertools/powertools-lambda-java/issues/1455 - */ -// @Test -// public void testLoadMetaSchemaV2019() { -// ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V201909); -// JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V201909", true); -// assertThat(jsonSchema).isNotNull(); -// } + @Test + public void testLoadMetaSchemaV2019() { + ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V201909); + JsonSchema jsonSchema = getJsonSchema("classpath:/draft/2019-09/schema", true); + assertThat(jsonSchema).isNotNull(); + } + + @Test + public void testLoadMetaSchemaV2020() { + ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V202012); + JsonSchema jsonSchema = getJsonSchema("classpath:/draft/2020-12/schema", true); + assertThat(jsonSchema).isNotNull(); + } @Test public void testLoadMetaSchemaV7() { ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V7); - JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V7", true); + JsonSchema jsonSchema = getJsonSchema("classpath:/draft-07/schema", true); assertThat(jsonSchema).isNotNull(); } @Test public void testLoadMetaSchemaV6() { ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V6); - JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V6", true); + JsonSchema jsonSchema = getJsonSchema("classpath:/draft-06/schema", true); assertThat(jsonSchema).isNotNull(); } @Test public void testLoadMetaSchemaV4() { ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V4); - JsonSchema jsonSchema = getJsonSchema("classpath:/schemas/meta_schema_V4", true); + JsonSchema jsonSchema = getJsonSchema("classpath:/draft-04/schema", true); assertThat(jsonSchema).isNotNull(); } From 965c897d00ef2995c1efb8413115c4a1e18ae098 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:42:53 +0200 Subject: [PATCH 49/74] build(deps): bump aws.sdk.version from 2.20.153 to 2.20.155 (#1447) Bumps `aws.sdk.version` from 2.20.153 to 2.20.155. Updates `software.amazon.awssdk:bom` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:http-client-spi` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:url-connection-client` from 2.20.152 to 2.20.155 Updates `software.amazon.awssdk:sqs` from 2.20.152 to 2.20.155 Updates `software.amazon.awssdk:s3` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:dynamodb` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:lambda` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:kinesis` from 2.20.152 to 2.20.155 Updates `software.amazon.awssdk:cloudwatch` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:xray` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:cloudformation` from 2.20.153 to 2.20.155 Updates `software.amazon.awssdk:sts` from 2.20.153 to 2.20.155 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 8fdcb8c08..db66b8675 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.3 - 2.20.153 + 2.20.155 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index c0c302757..38b46c020 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.20.153 + 2.20.155 com.amazonaws diff --git a/pom.xml b/pom.xml index 4f4ccb2bd..ee3bc1c2e 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.153 + 2.20.155 2.14.0 2.1.3 UTF-8 From e99bfad9f93f3bbac7e4e32670be6d46017cdf1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:43:59 +0200 Subject: [PATCH 50/74] build(deps): bump com.networknt:json-schema-validator (#1446) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.86 to 1.0.87. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.86...1.0.87) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- powertools-validation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powertools-validation/pom.xml b/powertools-validation/pom.xml index 23841777e..606f02139 100644 --- a/powertools-validation/pom.xml +++ b/powertools-validation/pom.xml @@ -87,7 +87,7 @@ com.networknt json-schema-validator - 1.0.86 + 1.0.87 com.amazonaws From 349ea0b937a1b39b7b8926ae6985f4545c9fe33f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:58:49 +0200 Subject: [PATCH 51/74] build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib (#1461) Bumps [software.amazon.awscdk:aws-cdk-lib](https://github.com/aws/aws-cdk) from 2.97.1 to 2.100.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/compare/v2.97.1...v2.100.0) --- updated-dependencies: - dependency-name: software.amazon.awscdk:aws-cdk-lib dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-core/cdk/infra/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 99598ba58..216bf35d4 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -7,7 +7,7 @@ 1.18.0-SNAPSHOT UTF-8 - 2.97.1 + 2.100.0 [10.0.0,11.0.0) 5.10.0 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 90427b797..89a255c8b 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -31,7 +31,7 @@ 1.8 1.8 10.2.70 - 2.97.1 + 2.100.0 From aa53bd924573faf2ae3687d3b07c459a6640b419 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:19:10 +0200 Subject: [PATCH 52/74] build(deps): bump aws.sdk.version from 2.20.155 to 2.20.162 (#1462) Bumps `aws.sdk.version` from 2.20.155 to 2.20.162. --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index db66b8675..c696ef0a8 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.3 - 2.20.155 + 2.20.162 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 38b46c020..988291413 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.20.155 + 2.20.162 com.amazonaws diff --git a/pom.xml b/pom.xml index ee3bc1c2e..277f2f681 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.155 + 2.20.162 2.14.0 2.1.3 UTF-8 From 897f7e9af665299695f5613f3607348e613f46a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 14:02:49 +0200 Subject: [PATCH 53/74] build(deps): bump org.apache.maven.plugins:maven-javadoc-plugin (#1473) Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 277f2f681..fd31bef37 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 3.1.2 0.8.10 1.6.13 - 3.5.0 + 3.6.0 3.3.0 3.1.0 5.10.0 From 533ac9a4aeab3ddfc7b191214dfa6be0a5d62489 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:13:40 +0200 Subject: [PATCH 54/74] build(deps-dev): bump com.amazonaws:amazon-sqs-java-extended-client-lib (#1476) Bumps [com.amazonaws:amazon-sqs-java-extended-client-lib](https://github.com/awslabs/amazon-sqs-java-extended-client-lib) from 2.0.3 to 2.0.4. - [Release notes](https://github.com/awslabs/amazon-sqs-java-extended-client-lib/releases) - [Commits](https://github.com/awslabs/amazon-sqs-java-extended-client-lib/compare/2.0.3...2.0.4) --- updated-dependencies: - dependency-name: com.amazonaws:amazon-sqs-java-extended-client-lib dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- powertools-e2e-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 89a255c8b..0a760bd0d 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -84,7 +84,7 @@ com.amazonaws amazon-sqs-java-extended-client-lib - 2.0.3 + 2.0.4 test From 0fe0d2c4a2fd958d9ed6b35e28a1af386b5be5d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:01:04 +0200 Subject: [PATCH 55/74] build(deps): bump aws.sdk.version from 2.20.162 to 2.21.0 (#1480) Bumps `aws.sdk.version` from 2.20.162 to 2.21.0. Updates `software.amazon.awssdk:bom` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:http-client-spi` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:url-connection-client` from 2.20.152 to 2.21.0 Updates `software.amazon.awssdk:sqs` from 2.20.152 to 2.21.0 Updates `software.amazon.awssdk:s3` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:dynamodb` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:lambda` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:kinesis` from 2.20.152 to 2.21.0 Updates `software.amazon.awssdk:cloudwatch` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:xray` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:cloudformation` from 2.20.162 to 2.21.0 Updates `software.amazon.awssdk:sts` from 2.20.162 to 2.21.0 --- updated-dependencies: - dependency-name: software.amazon.awssdk:bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:http-client-spi dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:s3 dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:dynamodb dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:lambda dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:cloudwatch dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:xray dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:cloudformation dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:sts dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-cloudformation/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index c696ef0a8..01aedcaaf 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.3 - 2.20.162 + 2.21.0 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 988291413..52766608a 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.20.162 + 2.21.0 com.amazonaws diff --git a/pom.xml b/pom.xml index fd31bef37..be696094f 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.20.0 2.15.2 1.9.7 - 2.20.162 + 2.21.0 2.14.0 2.1.3 UTF-8 From 51930d0f67d99764a00c5043b3f6c889d937e80e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:31:11 +0200 Subject: [PATCH 56/74] build(deps): bump aws.sdk.version from 2.20.152 to 2.21.1 (#1481) Bumps `aws.sdk.version` from 2.20.152 to 2.21.1. Updates `software.amazon.awssdk:url-connection-client` from 2.20.152 to 2.21.1 Updates `software.amazon.awssdk:sqs` from 2.20.152 to 2.21.1 Updates `software.amazon.awssdk:sdk-core` from 2.20.152 to 2.21.1 Updates `software.amazon.awssdk:kinesis` from 2.20.152 to 2.21.1 Updates `software.amazon.awssdk:dynamodb-enhanced` from 2.20.152 to 2.21.1 --- updated-dependencies: - dependency-name: software.amazon.awssdk:url-connection-client dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:sqs dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:sdk-core dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:kinesis dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:dynamodb-enhanced dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/powertools-examples-batch/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index ea5d1e5f1..bbdc19b9f 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.20.152 + 2.21.1 diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 52766608a..889fe85da 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.21.0 + 2.21.1 com.amazonaws From 7f4846daeb06a40453c74bd96c84f47ee8a75d43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:05:40 +0200 Subject: [PATCH 57/74] build(deps-dev): bump software.constructs:constructs (#1482) Bumps [software.constructs:constructs](https://github.com/aws/constructs) from 10.2.70 to 10.3.0. - [Release notes](https://github.com/aws/constructs/releases) - [Commits](https://github.com/aws/constructs/compare/v10.2.70...v10.3.0) --- updated-dependencies: - dependency-name: software.constructs:constructs dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- powertools-e2e-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 0a760bd0d..84760eac8 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -30,7 +30,7 @@ 1.8 1.8 - 10.2.70 + 10.3.0 2.100.0 From e9d6b8fb73cf18bda8a6ec74d1994acb288baa64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:39:52 +0200 Subject: [PATCH 58/74] Update dependabot.yml --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4832b1c49..1454df79c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,11 +3,11 @@ updates: - package-ecosystem: "maven" directory: "/" schedule: - interval: "daily" + interval: "weekly" labels: - "maven" - "dependencies" ignore: # Ignore Mockito 5.X.X as it does not support Java 8 - dependency-name: "org.mockito:mockito-*" - update-types: ["version-update:semver-major"] \ No newline at end of file + update-types: ["version-update:semver-major"] From ac90f33664d079c78da09f562f6ea5e8107287f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:50:51 +0200 Subject: [PATCH 59/74] build(deps): bump jackson.version from 2.15.2 to 2.15.3 (#1483) Bumps `jackson.version` from 2.15.2 to 2.15.3. Updates `com.fasterxml.jackson.core:jackson-databind` from 2.15.2 to 2.15.3 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.core:jackson-core` from 2.15.2 to 2.15.3 - [Release notes](https://github.com/FasterXML/jackson-core/releases) - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.15.2...jackson-core-2.15.3) Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.15.2 to 2.15.3 --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be696094f..823b09d61 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 1.8 1.8 2.20.0 - 2.15.2 + 2.15.3 1.9.7 2.21.0 2.14.0 From 5e3a4e63d7cd4b8d505b50f7ef2b36b8cac1e549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:51:17 +0200 Subject: [PATCH 60/74] build(deps): bump com.amazonaws:aws-lambda-java-core from 1.2.2 to 1.2.3 (#1460) Bumps [com.amazonaws:aws-lambda-java-core](https://github.com/aws/aws-lambda-java-libs) from 1.2.2 to 1.2.3. --- examples/powertools-examples-core/serverless/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-core/serverless/pom.xml b/examples/powertools-examples-core/serverless/pom.xml index 793318da3..faa47c591 100644 --- a/examples/powertools-examples-core/serverless/pom.xml +++ b/examples/powertools-examples-core/serverless/pom.xml @@ -34,7 +34,7 @@ com.amazonaws aws-lambda-java-core - 1.2.2 + 1.2.3 com.amazonaws From 34fc20eb91d893384aa60254a310601e6b6fa5db Mon Sep 17 00:00:00 2001 From: skal111 Date: Mon, 23 Oct 2023 09:21:08 +0200 Subject: [PATCH 61/74] feat: Terraform example (#1478) --- .github/workflows/pr_build.yml | 29 +++ .gitignore | 4 +- examples/pom.xml | 1 + examples/powertools-examples-core/README.md | 1 + .../terraform/.tflint.hcl | 3 + .../terraform/README.md | 27 +++ .../terraform/infra/api-gateway.tf | 94 ++++++++ .../terraform/infra/lambda.tf | 95 ++++++++ .../terraform/main.tf | 22 ++ .../terraform/pom.xml | 217 ++++++++++++++++++ .../src/main/java/helloworld/App.java | 105 +++++++++ .../src/main/java/helloworld/AppStream.java | 38 +++ .../terraform/src/main/resources/log4j2.xml | 16 ++ .../src/test/java/helloworld/AppTest.java | 38 +++ 14 files changed, 689 insertions(+), 1 deletion(-) create mode 100644 examples/powertools-examples-core/terraform/.tflint.hcl create mode 100644 examples/powertools-examples-core/terraform/README.md create mode 100644 examples/powertools-examples-core/terraform/infra/api-gateway.tf create mode 100644 examples/powertools-examples-core/terraform/infra/lambda.tf create mode 100644 examples/powertools-examples-core/terraform/main.tf create mode 100644 examples/powertools-examples-core/terraform/pom.xml create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml create mode 100644 examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 73ae67553..79945f237 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -53,6 +53,9 @@ jobs: 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 @@ -68,6 +71,32 @@ jobs: run: | cd examples/powertools-examples-core/gradle ./gradlew build + - name: Setup Terraform + if: ${{ matrix.java == '11' }} + uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Setup AWS credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} + aws-region: ${{ env.AWS_REGION }} + - name: Terraform validate + if: ${{ matrix.java == '11' }} + run: | + terraform -version + cd examples/powertools-examples-core/terraform + terraform init -backend=false + terraform validate + terraform plan + - name: Setup Terraform lint + if: ${{ matrix.java == '11' }} + uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 + - name: Terraform lint + if: ${{ matrix.java == '11' }} + run: | + tflint --version + cd examples/powertools-examples-core/terraform + tflint --init + tflint -f compact - name: Upload coverage to Codecov uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 if: ${{ matrix.java == '11' }} # publish results once diff --git a/.gitignore b/.gitignore index b404d2cb2..6615ac729 100644 --- a/.gitignore +++ b/.gitignore @@ -108,4 +108,6 @@ example/HelloWorldFunction/build /example/.gradle/ /example/.java-version .gradle -build/ \ No newline at end of file +build/ +.terraform* +terraform.tfstate* \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml index 810ec1b36..900f095f8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -33,6 +33,7 @@ powertools-examples-core/cdk/app powertools-examples-core/cdk/infra powertools-examples-core/serverless + powertools-examples-core/terraform powertools-examples-idempotency powertools-examples-parameters powertools-examples-serialization diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index 1d1dd031f..a0ffb125d 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -10,6 +10,7 @@ We provide examples for the following infrastructure-as-code tools: * [AWS SAM](sam/) * [AWS CDK](cdk/) * [Serverless framework](serverless/) +* [Terraform](terraform/) We also provide an example showing the integration of SAM, Powertools, and Gradle: diff --git a/examples/powertools-examples-core/terraform/.tflint.hcl b/examples/powertools-examples-core/terraform/.tflint.hcl new file mode 100644 index 000000000..18e69352b --- /dev/null +++ b/examples/powertools-examples-core/terraform/.tflint.hcl @@ -0,0 +1,3 @@ +rule "terraform_required_version" { + enabled = false +} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md new file mode 100644 index 000000000..71c78d437 --- /dev/null +++ b/examples/powertools-examples-core/terraform/README.md @@ -0,0 +1,27 @@ +# Powertools for AWS Lambda (Java) - Core Utilities Example with Terraform + +This project demonstrates the Lambda for Powertools Java module deployed using [Terraform](https://www.terraform.io/). +For general information on the deployed example itself, you can refer to the parent [README](../README.md). +To install Terraform if you don't have it yet, you can follow the [Install Terraform Guide](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform). + +## Configuration +Terraform uses [main.tf](./main.tf) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. + + +## Deploy the sample application + +To deploy the app, simply run the following commands: +```bash +terraform init +mvn package && terraform apply +``` + +## Useful commands + +To destroy the app +```bash +terraform destroy +``` diff --git a/examples/powertools-examples-core/terraform/infra/api-gateway.tf b/examples/powertools-examples-core/terraform/infra/api-gateway.tf new file mode 100644 index 000000000..dba1c3616 --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/api-gateway.tf @@ -0,0 +1,94 @@ +resource "aws_api_gateway_rest_api" "hello_world_api" { + name = "hello_world_api" + description = "API Gateway endpoint URL for Prod stage for Hello World function" +} + +resource "aws_api_gateway_resource" "hello_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hello" +} + +resource "aws_api_gateway_resource" "hello_stream_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hellostream" +} + +resource "aws_api_gateway_method" "hello_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_method" "hello_stream_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_integration" "java_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "${aws_api_gateway_method.hello_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_lambda.invoke_arn}" +} + +resource "aws_api_gateway_integration" "java_stream_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "${aws_api_gateway_method.hello_stream_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_stream_lambda.invoke_arn}" +} + +resource "aws_api_gateway_deployment" "prod_deployment" { + depends_on = [aws_api_gateway_integration.java_lambda_integration, aws_api_gateway_integration.java_stream_lambda_integration] + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + stage_name = "prod" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hellostream" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hellostream" +} + +output "invoke" {value=aws_api_gateway_deployment.prod_deployment.invoke_url} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/infra/lambda.tf b/examples/powertools-examples-core/terraform/infra/lambda.tf new file mode 100644 index 000000000..abebccf54 --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/lambda.tf @@ -0,0 +1,95 @@ +resource "aws_lambda_function" "hello_world_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_lambda" + + handler = "helloworld.App" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +resource "aws_lambda_function" "hello_world_stream_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_stream_lambda" + + handler = "helloworld.AppStream" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group" { + name = "/aws/lambda/hello_world_lambda" +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group_stream" { + name = "/aws/lambda/hello_world_stream_lambda" +} + +# lambda role +resource "aws_iam_role" "iam_role_for_lambda" { + name = "lambda-invoke-role" + assume_role_policy = < + 4.0.0 + + software.amazon.lambda.examples + 1.18.0-SNAPSHOT + powertools-examples-core-terraform + jar + + Powertools for AWS Lambda (Java) library Examples - Core + + + 2.20.0 + 1.8 + 1.8 + + + + + software.amazon.lambda + powertools-tracing + ${project.version} + + + software.amazon.lambda + powertools-logging + ${project.version} + + + software.amazon.lambda + powertools-metrics + ${project.version} + + + com.amazonaws + aws-lambda-java-core + 1.2.2 + + + com.amazonaws + aws-lambda-java-events + 3.11.2 + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + + junit + junit + 4.13.2 + test + + + + + helloworld-lambda + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + handler + + + + + + + + + jdk8 + + (,11) + + + 1.9.7 + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + test-compile + + + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java new file mode 100644 index 000000000..dacd7f1d4 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java @@ -0,0 +1,105 @@ +/* + * 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 helloworld; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; +import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric; +import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.logging.LoggingUtils; +import software.amazon.lambda.powertools.metrics.Metrics; +import software.amazon.lambda.powertools.tracing.CaptureMode; +import software.amazon.lambda.powertools.tracing.Tracing; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Handler for requests to Lambda function. + */ +public class App implements RequestHandler { + private final static Logger log = LogManager.getLogger(App.class); + + // This is controlled by POWERTOOLS_LOGGER_SAMPLE_RATE environment variable + // @Logging(logEvent = true, samplingRate = 0.7) + // This is controlled by POWERTOOLS_METRICS_NAMESPACE environment variable + // @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + // This is controlled by POWERTOOLS_TRACER_CAPTURE_ERROR environment variable + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { + Map headers = new HashMap<>(); + + headers.put("Content-Type", "application/json"); + headers.put("X-Custom-Header", "application/json"); + + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); + + LoggingUtils.appendKey("test", "willBeLogged"); + + APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() + .withHeaders(headers); + try { + final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); + log.info(pageContents); + TracingUtils.putAnnotation("Test", "New"); + String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); + + TracingUtils.withSubsegment("loggingResponse", subsegment -> + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (RuntimeException | IOException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + private String getPageContents(String address) throws IOException { + URL url = new URL(address); + putMetadata("getPageContents", address); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java @@ -0,0 +1,38 @@ +/* + * 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 helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.metrics.Metrics; + +public class AppStream implements RequestStreamHandler { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { + Map map = mapper.readValue(input, Map.class); + + System.out.println(map.size()); + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml new file mode 100644 index 000000000..0cc0953f0 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java new file mode 100644 index 000000000..0ca4f264d --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java @@ -0,0 +1,38 @@ +/* + * 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 helloworld; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import org.junit.Test; + +public class AppTest { + + @Test + public void successfulResponse() { + App app = new App(); + APIGatewayProxyResponseEvent result = app.handleRequest(null, null); + assertEquals(result.getStatusCode().intValue(), 200); + assertEquals(result.getHeaders().get("Content-Type"), "application/json"); + String content = result.getBody(); + assertNotNull(content); + assertTrue(content.contains("\"message\"")); + assertTrue(content.contains("\"hello world\"")); + assertTrue(content.contains("\"location\"")); + } +} From aed398bd0a99165dc8614147a921393775571af7 Mon Sep 17 00:00:00 2001 From: Jason Harris Date: Mon, 23 Oct 2023 19:18:33 +0100 Subject: [PATCH 62/74] docs: Adding Kotlin example. (#1454) * Setting up Kotlin environment. Converting test to Kotlin. * Deploying via SAM successfully. * Added Kotlin example. * Removing unused Gradle build file. * Adding SAM template so can be used as an existing project and Java target compatibility * Adding SAM template so can be used as an existing project * Updating guidance to use SAM for build and deploy * Restructuring separate Java and Kotlin examples. * Updating core examples readme to represent new structure for Java and Kotlin examples. * Refactoring application code for efficiency, updating build to cover tests too and is more idiomatic and readme to be more descriptive * Updating to fix trailing \n * Updating guidance to be more specific for examples * Adopting new mechanism for specifying jvm target. * accommodating new project structure * Fixing link typo after refactoring * Setting up Kotlin environment. Converting test to Kotlin. * Deploying via SAM successfully. * Added Kotlin example. * Removing unused Gradle build file. * Adding SAM template so can be used as an existing project and Java target compatibility * Adding SAM template so can be used as an existing project * Updating guidance to use SAM for build and deploy * Restructuring separate Java and Kotlin examples. * Updating core examples readme to represent new structure for Java and Kotlin examples. * Refactoring application code for efficiency, updating build to cover tests too and is more idiomatic and readme to be more descriptive * Updating to fix trailing \n * Updating guidance to be more specific for examples * Adopting new mechanism for specifying jvm target. * accommodating new project structure * Fixing link typo after refactoring * Flattening structure back to original to make merging easier for v2 * Adding build for Kotlin Gradle * Adding build for Kotlin Gradle - Restructuring Java examples to v1 approach * Correcting paths * Adding SNAPSHOT support and local capability for Maven. Testing using Java 1.8 * Reviewed and updated against PR comments. * Un-commenting examples --------- Co-authored-by: Jason Harris Co-authored-by: Scott Gerring --- .github/workflows/pr_build.yml | 6 +- examples/README.md | 6 +- examples/powertools-examples-core/README.md | 36 ++- .../powertools-examples-core/cdk/README.md | 6 +- .../gradle/gradlew.bat | 184 ++++++------- .../powertools-examples-core/kotlin/README.md | 38 +++ .../kotlin/build.gradle.kts | 39 +++ .../kotlin/events/event.json | 62 +++++ .../kotlin/gradle/wrapper/.gitignore | 2 + .../kotlin/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63375 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + .../powertools-examples-core/kotlin/gradlew | 248 ++++++++++++++++++ .../kotlin/gradlew.bat | 92 +++++++ .../kotlin/src/main/kotlin/helloworld/App.kt | 96 +++++++ .../src/main/kotlin/helloworld/AppStream.kt | 37 +++ .../src/test/kotlin/helloworld/AppTest.kt | 20 ++ .../kotlin/template.yaml | 71 +++++ .../serverless/README.md | 2 +- 18 files changed, 840 insertions(+), 112 deletions(-) create mode 100644 examples/powertools-examples-core/kotlin/README.md create mode 100644 examples/powertools-examples-core/kotlin/build.gradle.kts create mode 100644 examples/powertools-examples-core/kotlin/events/event.json create mode 100644 examples/powertools-examples-core/kotlin/gradle/wrapper/.gitignore create mode 100644 examples/powertools-examples-core/kotlin/gradle/wrapper/gradle-wrapper.jar create mode 100644 examples/powertools-examples-core/kotlin/gradle/wrapper/gradle-wrapper.properties create mode 100755 examples/powertools-examples-core/kotlin/gradlew create mode 100644 examples/powertools-examples-core/kotlin/gradlew.bat create mode 100644 examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/App.kt create mode 100644 examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/AppStream.kt create mode 100644 examples/powertools-examples-core/kotlin/src/test/kotlin/helloworld/AppTest.kt create mode 100644 examples/powertools-examples-core/kotlin/template.yaml diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 79945f237..e99900ce5 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -66,11 +66,15 @@ jobs: cache: 'maven' - name: Build with Maven run: mvn -B install --file pom.xml - - name: Build Gradle Example + - name: Build Gradle Example - Java if: ${{ matrix.java == '8' }} # Gradle example can only be built on Java 8 run: | cd examples/powertools-examples-core/gradle ./gradlew build + - name: Build Gradle Example - Kotlin + run: | + cd examples/powertools-examples-core/kotlin + ./gradlew build - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 diff --git a/examples/README.md b/examples/README.md index 52dc0c1e9..6dbe00185 100644 --- a/examples/README.md +++ b/examples/README.md @@ -5,10 +5,12 @@ Each example can be copied from its subdirectory and used independently of the r ## Examples -* [powertools-examples-core](powertools-examples-core) - Demonstrates the core logging, tracing, and metrics modules with different build tools - * [SAM](./powertools-examples-core/sam) +* [powertools-examples-core](powertools-examples-core) - Demonstrates the core logging, tracing, and metrics modules with different build tools and languages * [CDK](./powertools-examples-core/cdk) + * [Gradle](./powertools-examples-core/gradle) + * [SAM](./powertools-examples-core/sam) * [Serverless](./powertools-examples-core/serverless) + * [Kotlin](./powertools-examples-core/kotlin) * [powertools-examples-idempotency](powertools-examples-idempotency) - An idempotent HTTP API * [powertools-examples-parameters](powertools-examples-parameters) - Uses the parameters module to provide runtime parameters to a function * [powertools-examples-serialization](powertools-examples-serialization) - Uses the serialization module to serialize and deserialize API Gateway & SQS payloads diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index a0ffb125d..c9ca60f57 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -1,12 +1,13 @@ -# Powertools for AWS Lambda (Java) - Core Utilities Example +# Powertools for AWS Lambda (Java) - Core Utilities Example This project demonstrates the Lambda for Powertools Java module - including [logging](https://docs.powertools.aws.dev/lambda/java/core/logging/), [tracing](https://docs.powertools.aws.dev/lambda/java/core/tracing/), and [metrics](https://docs.powertools.aws.dev/lambda/java/core/metrics/). -We provide examples for the following infrastructure-as-code tools: +The example application is the same, and you can now also use Kotlin! +## Java * [AWS SAM](sam/) * [AWS CDK](cdk/) * [Serverless framework](serverless/) @@ -16,11 +17,21 @@ We also provide an example showing the integration of SAM, Powertools, and Gradl * [AWS SAM with a Gradle build](gradle/) -For each of the tools, the example application is the same, and consists of the following files: +- App.java - Code for the application's Lambda function. +- AppTests.java - Unit tests for the application code. +- events - Invocation events that you can use to invoke the function. -- [App.java](sam/src/main/java/helloworld/App.java) - Code for the application's Lambda function. -- [AppTests.java](sam/src/test/java/helloworld/AppTest.java) - Unit tests for the application code. -- [events](sam/events/event.json) - Invocation events that you can use to invoke the function. +Configuration files and deployment process for each tool are described in corresponding README files. + +## Kotlin + +- [Gradle](kotlin/) + +Example application consists of the following files: + +- App.kt - Code for the application's Lambda function. +- AppTests.kt - Unit tests for the application code. +- events - Invocation events that you can use to invoke the function. Configuration files and deployment process for each tool are described in corresponding README files. @@ -32,14 +43,13 @@ Once the app is deployed, you can invoke the endpoint like this: curl https://[REST-API-ID].execute-api.[REGION].amazonaws.com/Prod/hello/ ``` -The response itself isn't particularly interesting - you will get back some information about your IP address. If +The response itself isn't particularly interesting - you will get back some information about your IP address. If you go to the Lambda Console and locate the lambda you have deployed, then click the "Monitoring" tab you will be able to find: -* **View X-Ray traces** - Display the traces captured by the traces module. These include subsegments for the -different function calls within the example -* **View Cloudwatch logs** - Display the structured logging output of the example +- **View X-Ray traces** - Display the traces captured by the traces module. These include subsegments for the + different function calls within the example +- **View Cloudwatch logs** - Display the structured logging output of the example -Likewise, from the CloudWatch dashboard, under **Metrics**, **all metrics**, you will find the namespaces `Another` -and `ServerlessAirline`. The values in each of these are published by the code in -[App.java](sam/src/main/java/helloworld/App.java). +Likewise, from the CloudWatch dashboard, under **Metrics**, **all metrics**, you will find the namespaces `Another` +and `ServerlessAirline`. The values in each of these are published by the code in the respective application's Lambda function. diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index f15a24168..fbc558943 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -6,9 +6,9 @@ For general information on the deployed example itself, you can refer to the par ## Configuration CDK uses the following project structure: -- [app](./app) - stores the source code of your application, which is similar between all examples -- [infra](./infra) - stores the definition of your infrastructure - - [cdk.json](./infra/cdk.json) - tells the CDK Toolkit how to execute your app +- [app](app) - stores the source code of your application, which is similar between all examples +- [infra](infra) - stores the definition of your infrastructure + - [cdk.json](infra/cdk.json) - tells the CDK Toolkit how to execute your app - [CdkApp](./infra/src/main/java/cdk/CdkApp.java) - bootstraps your stack, taking AWS `account` and `region` as input - [CdkStack](./infra/src/main/java/cdk/CdkStack.java) - defines the Lambda function to be deployed as well as API Gateway for it. diff --git a/examples/powertools-examples-core/gradle/gradlew.bat b/examples/powertools-examples-core/gradle/gradlew.bat index 6689b85be..93e3f59f1 100644 --- a/examples/powertools-examples-core/gradle/gradlew.bat +++ b/examples/powertools-examples-core/gradle/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/powertools-examples-core/kotlin/README.md b/examples/powertools-examples-core/kotlin/README.md new file mode 100644 index 000000000..da9ec5b52 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/README.md @@ -0,0 +1,38 @@ +# Powertools for AWS Lambda (Kotlin) - Core Utilities Example + +This project demonstrates the Lambda for Powertools Kotlin module deployed using [Serverless Application Model](https://aws.amazon.com/serverless/sam/) with +[Gradle](https://gradle.org/) running the build. This example is configured for Java 1.8 only; in order to use a newer version, check out the Gradle +configuration guide [in the main project README](../../../README.md). + +You can also use `sam init` to create a new Gradle-powered Powertools application - choose to use the **AWS Quick Start Templates**, +and then **Hello World Example with Powertools for AWS Lambda**, **Java 17** runtime, and finally **gradle**. + +For general information on the deployed example itself, you can refer to the parent [README](../README.md) + +## Configuration +SAM uses [template.yaml](template.yaml) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +The build of the project is managed by Gradle, and configured in [build.gradle.kts](build.gradle.kts) +. + +## Deploy the sample application +To get started, you can use the included template with SAM to run the build and deploy to your AWS environment: + +```bash +sam build && sam deploy --guided +``` + +Once this is done to deploy the example, check out the instructions for getting started with SAM in +[the examples directory](../../README.md) + +## Additional notes + +You can watch the trace information or log information using the SAM CLI: +```bash +# Tail the logs +sam logs --tail $MY_STACK + +# Tail the traces +sam traces --tail +``` \ No newline at end of file diff --git a/examples/powertools-examples-core/kotlin/build.gradle.kts b/examples/powertools-examples-core/kotlin/build.gradle.kts new file mode 100644 index 000000000..fc363c1b9 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + id("io.freefair.aspectj.post-compile-weaving") version "6.6.3" + kotlin("jvm") version "1.9.10" +} + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + implementation("com.amazonaws:aws-lambda-java-core:1.2.2") + implementation("com.fasterxml.jackson.core:jackson-annotations:2.13.2") + implementation("com.fasterxml.jackson.core:jackson-databind:2.13.2.2") + implementation("com.amazonaws:aws-lambda-java-events:3.11.0") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2") + aspect("software.amazon.lambda:powertools-tracing:1.18.0-SNAPSHOT") + aspect("software.amazon.lambda:powertools-logging:1.18.0-SNAPSHOT") + aspect("software.amazon.lambda:powertools-metrics:1.18.0-SNAPSHOT") + testImplementation("junit:junit:4.13.2") + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") +} + +tasks.compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +tasks.compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +// If using JDK 11 or higher, use the following instead: +//kotlin { +// jvmToolchain(11) +//} \ No newline at end of file diff --git a/examples/powertools-examples-core/kotlin/events/event.json b/examples/powertools-examples-core/kotlin/events/event.json new file mode 100644 index 000000000..070ad8e01 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/events/event.json @@ -0,0 +1,62 @@ +{ + "body": "{\"message\": \"hello world\"}", + "resource": "/{proxy+}", + "path": "/path/to/resource", + "httpMethod": "POST", + "isBase64Encoded": false, + "queryStringParameters": { + "foo": "bar" + }, + "pathParameters": { + "proxy": "/path/to/resource" + }, + "stageVariables": { + "baz": "qux" + }, + "headers": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Encoding": "gzip, deflate, sdch", + "Accept-Language": "en-US,en;q=0.8", + "Cache-Control": "max-age=0", + "CloudFront-Forwarded-Proto": "https", + "CloudFront-Is-Desktop-Viewer": "true", + "CloudFront-Is-Mobile-Viewer": "false", + "CloudFront-Is-SmartTV-Viewer": "false", + "CloudFront-Is-Tablet-Viewer": "false", + "CloudFront-Viewer-Country": "US", + "Host": "1234567890.execute-api.us-east-1.amazonaws.com", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Custom User Agent String", + "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", + "X-Forwarded-For": "127.0.0.1, 127.0.0.2", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https" + }, + "requestContext": { + "accountId": "123456789012", + "resourceId": "123456", + "stage": "prod", + "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", + "requestTime": "09/Apr/2015:12:34:56 +0000", + "requestTimeEpoch": 1428582896000, + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "accessKey": null, + "sourceIp": "127.0.0.1", + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "Custom User Agent String", + "user": null + }, + "path": "/prod/path/to/resource", + "resourcePath": "/{proxy+}", + "httpMethod": "POST", + "apiId": "1234567890", + "protocol": "HTTP/1.1" + } +} diff --git a/examples/powertools-examples-core/kotlin/gradle/wrapper/.gitignore b/examples/powertools-examples-core/kotlin/gradle/wrapper/.gitignore new file mode 100644 index 000000000..59c09e205 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/gradle/wrapper/.gitignore @@ -0,0 +1,2 @@ +!gradle-wrapper.jar + diff --git a/examples/powertools-examples-core/kotlin/gradle/wrapper/gradle-wrapper.jar b/examples/powertools-examples-core/kotlin/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..033e24c4cdf41af1ab109bc7f253b2b887023340 GIT binary patch literal 63375 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≫L+crb^Bz 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/examples/powertools-examples-core/kotlin/gradlew.bat b/examples/powertools-examples-core/kotlin/gradlew.bat new file mode 100644 index 000000000..6689b85be --- /dev/null +++ b/examples/powertools-examples-core/kotlin/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/App.kt b/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/App.kt new file mode 100644 index 000000000..ed4cf267a --- /dev/null +++ b/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/App.kt @@ -0,0 +1,96 @@ +/* + * 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 helloworld + +import com.amazonaws.services.lambda.runtime.Context +import com.amazonaws.services.lambda.runtime.RequestHandler +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent +import com.amazonaws.xray.entities.Subsegment +import org.apache.logging.log4j.LogManager +import software.amazon.cloudwatchlogs.emf.logger.MetricsLogger +import software.amazon.cloudwatchlogs.emf.model.DimensionSet +import software.amazon.cloudwatchlogs.emf.model.Unit +import software.amazon.lambda.powertools.logging.Logging +import software.amazon.lambda.powertools.logging.LoggingUtils +import software.amazon.lambda.powertools.metrics.Metrics +import software.amazon.lambda.powertools.metrics.MetricsUtils +import software.amazon.lambda.powertools.tracing.CaptureMode +import software.amazon.lambda.powertools.tracing.Tracing +import software.amazon.lambda.powertools.tracing.TracingUtils +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.net.URL +import java.util.stream.Collectors + +/** + * Handler for requests to Lambda function. + */ + +class App : RequestHandler { + @Logging(logEvent = true, samplingRate = 0.7) + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + + override fun handleRequest(input: APIGatewayProxyRequestEvent?, context: Context?): APIGatewayProxyResponseEvent { + val headers = mapOf("Content-Type" to "application/json", "X-Custom-Header" to "application/json") + MetricsUtils.metricsLogger().putMetric("CustomMetric1", 1.0, Unit.COUNT) + MetricsUtils.withSingleMetric("CustomMetrics2", 1.0, Unit.COUNT, "Another") { metric: MetricsLogger -> + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")) + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")) + } + LoggingUtils.appendKey("test", "willBeLogged") + val response = APIGatewayProxyResponseEvent().withHeaders(headers) + return try { + val pageContents = getPageContents("https://checkip.amazonaws.com") + log.info(pageContents) + TracingUtils.putAnnotation("Test", "New") + val output = """ + { + "message": "hello world", + "location": "$pageContents" + } + """.trimIndent() + TracingUtils.withSubsegment("loggingResponse") { _: Subsegment? -> + val sampled = "log something out" + log.info(sampled) + log.info(output) + } + log.info("After output") + response.withStatusCode(200).withBody(output) + } catch (e: RuntimeException) { + response.withBody("{}").withStatusCode(500) + } catch (e: IOException) { + response.withBody("{}").withStatusCode(500) + } + } + + @Tracing + private fun log() { + log.info("inside threaded logging for function") + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + @Throws(IOException::class) + private fun getPageContents(address: String): String { + val url = URL(address) + TracingUtils.putMetadata("getPageContents", address) + return InputStreamReader(url.openStream()).use { reader -> + reader.readText().trim() + } + } + + private val log = LogManager.getLogger(App::class) +} diff --git a/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/AppStream.kt b/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/AppStream.kt new file mode 100644 index 000000000..99f6bbfa0 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/src/main/kotlin/helloworld/AppStream.kt @@ -0,0 +1,37 @@ +/* + * 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 helloworld + +import com.amazonaws.services.lambda.runtime.Context +import com.amazonaws.services.lambda.runtime.RequestStreamHandler +import com.fasterxml.jackson.databind.ObjectMapper +import software.amazon.lambda.powertools.logging.Logging +import software.amazon.lambda.powertools.metrics.Metrics +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream + +class AppStream : RequestStreamHandler { + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + @Throws(IOException::class) + override fun handleRequest(input: InputStream, output: OutputStream, context: Context) { + val map: Map<*, *> = mapper.readValue(input, MutableMap::class.java) + println(map.size) + } + + companion object { + private val mapper = ObjectMapper() + } +} diff --git a/examples/powertools-examples-core/kotlin/src/test/kotlin/helloworld/AppTest.kt b/examples/powertools-examples-core/kotlin/src/test/kotlin/helloworld/AppTest.kt new file mode 100644 index 000000000..8aae081e8 --- /dev/null +++ b/examples/powertools-examples-core/kotlin/src/test/kotlin/helloworld/AppTest.kt @@ -0,0 +1,20 @@ +package helloworld + + +import org.junit.Assert +import org.junit.Test + +class AppTest { + @Test + fun successfulResponse() { + val app = App() + val result = app.handleRequest(null, null) + Assert.assertEquals(200, result.statusCode.toLong()) + Assert.assertEquals("application/json", result.headers["Content-Type"]) + val content = result.body + Assert.assertNotNull(content) + Assert.assertTrue(""""message"""" in content) + Assert.assertTrue(""""hello world"""" in content) + Assert.assertTrue(""""location"""" in content) + } +} diff --git a/examples/powertools-examples-core/kotlin/template.yaml b/examples/powertools-examples-core/kotlin/template.yaml new file mode 100644 index 000000000..1a1572fca --- /dev/null +++ b/examples/powertools-examples-core/kotlin/template.yaml @@ -0,0 +1,71 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + gradle + + Sample SAM Template for gradle + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 20 + Runtime: java11 + MemorySize: 512 + Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html + Environment: + Variables: + # Powertools for AWS Lambda (Java) env vars: https://docs.powertools.aws.dev/lambda/java/#environment-variables + POWERTOOLS_LOG_LEVEL: INFO + POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1 + POWERTOOLS_LOGGER_LOG_EVENT: true + POWERTOOLS_METRICS_NAMESPACE: Coreutilities + +Resources: + HelloWorldFunction: + Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Properties: + CodeUri: . + Handler: helloworld.App::handleRequest + Runtime: java11 + 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: + POWERTOOLS_SERVICE_NAME: hello + Events: + HelloWorld: + Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api + Properties: + Path: /hello + Method: get + + HelloWorldStreamFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: . + Handler: helloworld.AppStream::handleRequest + Runtime: java11 + MemorySize: 512 + Tracing: Active + Environment: + Variables: + POWERTOOLS_LOGGER_SAMPLE_RATE: 0.7 + Events: + HelloWorld: + Type: Api + Properties: + Path: /hellostream + Method: get + +Outputs: + # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function + # Find out more about other implicit resources you can reference within SAM + # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api + HelloWorldApi: + Description: "API Gateway endpoint URL for Prod stage for Hello World function" + Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" + HelloWorldFunction: + Description: "Hello World Lambda Function ARN" + Value: !GetAtt HelloWorldFunction.Arn + HelloWorldFunctionIamRole: + Description: "Implicit IAM Role created for Hello World function" + Value: !GetAtt HelloWorldFunctionRole.Arn diff --git a/examples/powertools-examples-core/serverless/README.md b/examples/powertools-examples-core/serverless/README.md index aec093182..9e33aa9ff 100644 --- a/examples/powertools-examples-core/serverless/README.md +++ b/examples/powertools-examples-core/serverless/README.md @@ -5,7 +5,7 @@ For general information on the deployed example itself, you can refer to the par To install Serverless Framework if you don't have it yet, you can follow the [Getting Started Guide](https://www.serverless.com/framework/docs/getting-started). ## Configuration -Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +Serverless Framework uses [serverless.yml](serverless.yml) to define the application's AWS resources. This file defines the Lambda function to be deployed as well as API Gateway for it. It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. From 228c0d8f3b66613d19a59f18b436de9907668ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:15:46 +0200 Subject: [PATCH 63/74] chore: java21 support in our build (#1488) --- .github/workflows/pr_build.yml | 2 +- examples/powertools-examples-batch/pom.xml | 1 + .../pom.xml | 1 + .../powertools-examples-core/cdk/app/pom.xml | 8 +- .../app/src/test/java/helloworld/AppTest.java | 59 ---------- .../gradle/build.gradle | 1 - .../src/test/java/helloworld/AppTest.java | 24 ---- examples/powertools-examples-core/sam/pom.xml | 8 +- .../sam/src/test/java/helloworld/AppTest.java | 59 ---------- .../serverless/pom.xml | 8 +- .../src/test/java/helloworld/AppTest.java | 59 ---------- .../terraform/pom.xml | 8 +- .../src/test/java/helloworld/AppTest.java | 38 ------- .../powertools-examples-idempotency/pom.xml | 25 +---- .../src/test/java/helloworld/AppTest.java | 105 ------------------ .../src/test/resources/event.json | 63 ----------- .../powertools-examples-parameters/pom.xml | 20 ---- .../powertools-examples-serialization/pom.xml | 26 ----- ...wayRequestDeserializationFunctionTest.java | 49 -------- .../SQSEventDeserializationFunctionTest.java | 59 ---------- examples/powertools-examples-sqs/pom.xml | 1 + .../powertools-examples-validation/pom.xml | 26 ----- .../validation/InboundValidationTest.java | 65 ----------- pom.xml | 74 ++++++++++-- powertools-batch/pom.xml | 10 -- powertools-cloudformation/pom.xml | 5 - powertools-core/pom.xml | 11 -- powertools-idempotency/pom.xml | 10 -- powertools-large-messages/pom.xml | 10 -- powertools-logging/pom.xml | 10 -- powertools-metrics/pom.xml | 10 -- powertools-parameters/pom.xml | 10 -- powertools-sqs/pom.xml | 5 - powertools-test-suite/pom.xml | 5 - powertools-tracing/pom.xml | 10 -- powertools-validation/pom.xml | 5 - 36 files changed, 71 insertions(+), 819 deletions(-) delete mode 100644 examples/powertools-examples-core/cdk/app/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-core/sam/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-idempotency/src/test/java/helloworld/AppTest.java delete mode 100644 examples/powertools-examples-idempotency/src/test/resources/event.json delete mode 100644 examples/powertools-examples-serialization/src/test/java/org/demo/serialization/APIGatewayRequestDeserializationFunctionTest.java delete mode 100644 examples/powertools-examples-serialization/src/test/java/org/demo/serialization/SQSEventDeserializationFunctionTest.java delete mode 100644 examples/powertools-examples-validation/src/test/java/org/demo/validation/InboundValidationTest.java diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index e99900ce5..04f35c63b 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -48,7 +48,7 @@ jobs: strategy: max-parallel: 5 matrix: - java: [8, 11, 15, 16, 17, 18, 19, 20 ] + java: [8, 11, 15, 16, 17, 18, 19, 20, 21 ] name: Java ${{ matrix.java }} env: JAVA: ${{ matrix.java }} diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index bbdc19b9f..99d3a97cc 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -105,6 +105,7 @@ shade + false diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index 01aedcaaf..c195cd262 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -130,6 +130,7 @@ shade + false diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index 57397f187..b4652bd65 100644 --- a/examples/powertools-examples-core/cdk/app/pom.xml +++ b/examples/powertools-examples-core/cdk/app/pom.xml @@ -51,13 +51,6 @@ log4j-api ${log4j.version} - - - junit - junit - 4.13.2 - test - @@ -105,6 +98,7 @@ shade + false diff --git a/examples/powertools-examples-core/cdk/app/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/cdk/app/src/test/java/helloworld/AppTest.java deleted file mode 100644 index 70dad8d71..000000000 --- a/examples/powertools-examples-core/cdk/app/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 helloworld; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.xray.AWSXRay; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class AppTest { - - @Before - public void setup() { - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.beginSegment("test"); - } - } - - @After - public void tearDown() { - if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { - AWSXRay.endSubsegment(); - } - - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.endSegment(); - } - } - - @Test - public void successfulResponse() { - App app = new App(); - APIGatewayProxyResponseEvent result = app.handleRequest(null, null); - assertEquals(result.getStatusCode().intValue(), 200); - assertEquals(result.getHeaders().get("Content-Type"), "application/json"); - String content = result.getBody(); - assertNotNull(content); - assertTrue(content.contains("\"message\"")); - assertTrue(content.contains("\"hello world\"")); - assertTrue(content.contains("\"location\"")); - } -} diff --git a/examples/powertools-examples-core/gradle/build.gradle b/examples/powertools-examples-core/gradle/build.gradle index e7367c246..06aec59e8 100644 --- a/examples/powertools-examples-core/gradle/build.gradle +++ b/examples/powertools-examples-core/gradle/build.gradle @@ -30,6 +30,5 @@ dependencies { aspect 'software.amazon.lambda:powertools-tracing:1.17.0' aspect 'software.amazon.lambda:powertools-logging:1.17.0' aspect 'software.amazon.lambda:powertools-metrics:1.17.0' - testImplementation 'junit:junit:4.13.2' } diff --git a/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java deleted file mode 100644 index af3ec1275..000000000 --- a/examples/powertools-examples-core/gradle/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package helloworld; - -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class AppTest { - @Test - public void successfulResponse() { - App app = new App(); - APIGatewayProxyResponseEvent result = app.handleRequest(null, null); - assertEquals(200, result.getStatusCode().intValue()); - assertEquals("application/json", result.getHeaders().get("Content-Type")); - String content = result.getBody(); - assertNotNull(content); - assertTrue(content.contains("\"message\"")); - assertTrue(content.contains("\"hello world\"")); - assertTrue(content.contains("\"location\"")); - } -} diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index 93c858556..997472344 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -51,13 +51,6 @@ log4j-api ${log4j.version} - - - junit - junit - 4.13.2 - test - @@ -104,6 +97,7 @@ shade + false diff --git a/examples/powertools-examples-core/sam/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/sam/src/test/java/helloworld/AppTest.java deleted file mode 100644 index 70dad8d71..000000000 --- a/examples/powertools-examples-core/sam/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 helloworld; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.xray.AWSXRay; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class AppTest { - - @Before - public void setup() { - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.beginSegment("test"); - } - } - - @After - public void tearDown() { - if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { - AWSXRay.endSubsegment(); - } - - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.endSegment(); - } - } - - @Test - public void successfulResponse() { - App app = new App(); - APIGatewayProxyResponseEvent result = app.handleRequest(null, null); - assertEquals(result.getStatusCode().intValue(), 200); - assertEquals(result.getHeaders().get("Content-Type"), "application/json"); - String content = result.getBody(); - assertNotNull(content); - assertTrue(content.contains("\"message\"")); - assertTrue(content.contains("\"hello world\"")); - assertTrue(content.contains("\"location\"")); - } -} diff --git a/examples/powertools-examples-core/serverless/pom.xml b/examples/powertools-examples-core/serverless/pom.xml index faa47c591..6fce1d2dd 100644 --- a/examples/powertools-examples-core/serverless/pom.xml +++ b/examples/powertools-examples-core/serverless/pom.xml @@ -51,13 +51,6 @@ log4j-api ${log4j.version} - - - junit - junit - 4.13.2 - test - @@ -105,6 +98,7 @@ shade + false diff --git a/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java deleted file mode 100644 index 70dad8d71..000000000 --- a/examples/powertools-examples-core/serverless/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 helloworld; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.xray.AWSXRay; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class AppTest { - - @Before - public void setup() { - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.beginSegment("test"); - } - } - - @After - public void tearDown() { - if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { - AWSXRay.endSubsegment(); - } - - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.endSegment(); - } - } - - @Test - public void successfulResponse() { - App app = new App(); - APIGatewayProxyResponseEvent result = app.handleRequest(null, null); - assertEquals(result.getStatusCode().intValue(), 200); - assertEquals(result.getHeaders().get("Content-Type"), "application/json"); - String content = result.getBody(); - assertNotNull(content); - assertTrue(content.contains("\"message\"")); - assertTrue(content.contains("\"hello world\"")); - assertTrue(content.contains("\"location\"")); - } -} diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 8da2780d8..2a55c31bc 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -51,13 +51,6 @@ log4j-api ${log4j.version} - - - junit - junit - 4.13.2 - test - @@ -105,6 +98,7 @@ shade + false diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java deleted file mode 100644 index 0ca4f264d..000000000 --- a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 helloworld; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import org.junit.Test; - -public class AppTest { - - @Test - public void successfulResponse() { - App app = new App(); - APIGatewayProxyResponseEvent result = app.handleRequest(null, null); - assertEquals(result.getStatusCode().intValue(), 200); - assertEquals(result.getHeaders().get("Content-Type"), "application/json"); - String content = result.getBody(); - assertNotNull(content); - assertTrue(content.contains("\"message\"")); - assertTrue(content.contains("\"hello world\"")); - assertTrue(content.contains("\"location\"")); - } -} diff --git a/examples/powertools-examples-idempotency/pom.xml b/examples/powertools-examples-idempotency/pom.xml index a98645a29..8cda4bfb3 100644 --- a/examples/powertools-examples-idempotency/pom.xml +++ b/examples/powertools-examples-idempotency/pom.xml @@ -64,30 +64,6 @@ log4j-api ${log4j.version} - - - org.mockito - mockito-core - 4.11.0 - test - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - com.amazonaws - DynamoDBLocal - 1.22.0 - test - - - com.amazonaws - aws-lambda-java-tests - 1.1.1 - @@ -167,6 +143,7 @@ shade + false diff --git a/examples/powertools-examples-idempotency/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-idempotency/src/test/java/helloworld/AppTest.java deleted file mode 100644 index 7f097906a..000000000 --- a/examples/powertools-examples-idempotency/src/test/java/helloworld/AppTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 helloworld; - -import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; -import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.services.lambda.runtime.tests.EventLoader; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.URI; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; -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.AttributeDefinition; -import software.amazon.awssdk.services.dynamodb.model.BillingMode; -import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; -import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; -import software.amazon.awssdk.services.dynamodb.model.KeyType; -import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; - -public class AppTest { - private static DynamoDbClient client; - @Mock - private Context context; - private App app; - - @BeforeAll - public static void setupDynamoLocal() { - int port = getFreePort(); - try { - DynamoDBProxyServer dynamoProxy = ServerRunner.createServerFromCommandLineArgs(new String[] { - "-inMemory", - "-port", - Integer.toString(port) - }); - dynamoProxy.start(); - } catch (Exception e) { - throw new RuntimeException(); - } - - client = DynamoDbClient.builder() - .httpClient(UrlConnectionHttpClient.builder().build()) - .region(Region.EU_WEST_1) - .endpointOverride(URI.create("http://localhost:" + port)) - .credentialsProvider(StaticCredentialsProvider.create( - AwsBasicCredentials.create("FAKE", "FAKE"))) - .build(); - - client.createTable(CreateTableRequest.builder() - .tableName("idempotency") - .keySchema(KeySchemaElement.builder().keyType(KeyType.HASH).attributeName("id").build()) - .attributeDefinitions( - AttributeDefinition.builder().attributeName("id").attributeType(ScalarAttributeType.S).build() - ) - .billingMode(BillingMode.PAY_PER_REQUEST) - .build()); - } - - private static int getFreePort() { - try { - ServerSocket socket = new ServerSocket(0); - int port = socket.getLocalPort(); - socket.close(); - return port; - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - app = new App(client); - } - - @Test - public void testApp() { - APIGatewayProxyResponseEvent response = - app.handleRequest(EventLoader.loadApiGatewayRestEvent("event.json"), context); - Assertions.assertNotNull(response); - Assertions.assertTrue(response.getBody().contains("hello world")); - } -} diff --git a/examples/powertools-examples-idempotency/src/test/resources/event.json b/examples/powertools-examples-idempotency/src/test/resources/event.json deleted file mode 100644 index fd7f5ace7..000000000 --- a/examples/powertools-examples-idempotency/src/test/resources/event.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "body": "{\"address\": \"https://checkip.amazonaws.com\"}", - "resource": "/{proxy+}", - "path": "/path/to/resource", - "httpMethod": "POST", - "isBase64Encoded": false, - "queryStringParameters": { - "foo": "bar" - }, - "pathParameters": { - "proxy": "/path/to/resource" - }, - "stageVariables": { - "baz": "qux" - }, - "headers": { - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", - "Accept-Encoding": "gzip, deflate, sdch", - "Accept-Language": "en-US,en;q=0.8", - "Cache-Control": "max-age=0", - "CloudFront-Forwarded-Proto": "https", - "CloudFront-Is-Desktop-Viewer": "true", - "CloudFront-Is-Mobile-Viewer": "false", - "CloudFront-Is-SmartTV-Viewer": "false", - "CloudFront-Is-Tablet-Viewer": "false", - "CloudFront-Viewer-Country": "US", - "Host": "1234567890.execute-api.us-east-1.amazonaws.com", - "Upgrade-Insecure-Requests": "1", - "User-Agent": "Custom User Agent String", - "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", - "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", - "X-Forwarded-For": "127.0.0.1, 127.0.0.2", - "X-Forwarded-Port": "443", - "X-Forwarded-Proto": "https" - }, - "requestContext": { - "accountId": "123456789012", - "resourceId": "123456", - "stage": "prod", - "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", - "requestTime": "09/Apr/2015:12:34:56 +0000", - "requestTimeEpoch": 1428582896000, - "identity": { - "cognitoIdentityPoolId": null, - "accountId": null, - "cognitoIdentityId": null, - "caller": null, - "accessKey": null, - "sourceIp": "127.0.0.1", - "cognitoAuthenticationType": null, - "cognitoAuthenticationProvider": null, - "userArn": null, - "userAgent": "Custom User Agent String", - "user": null - }, - "path": "/prod/path/to/resource", - "resourcePath": "/{proxy+}", - "httpMethod": "POST", - "apiId": "1234567890", - "protocol": "HTTP/1.1" - } - } - \ No newline at end of file diff --git a/examples/powertools-examples-parameters/pom.xml b/examples/powertools-examples-parameters/pom.xml index deb9c6ba6..0e07b0cbb 100644 --- a/examples/powertools-examples-parameters/pom.xml +++ b/examples/powertools-examples-parameters/pom.xml @@ -33,26 +33,6 @@ aws-lambda-java-events 3.11.3 - - - - org.mockito - mockito-core - 5.1.1 - test - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.9.3 - test - diff --git a/examples/powertools-examples-serialization/pom.xml b/examples/powertools-examples-serialization/pom.xml index eee3e456a..495fe8b77 100644 --- a/examples/powertools-examples-serialization/pom.xml +++ b/examples/powertools-examples-serialization/pom.xml @@ -33,36 +33,10 @@ aws-lambda-java-events 3.11.3 - - - - org.mockito - mockito-core - 4.11.0 - test - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.9.3 - test - - - org.apache.maven.plugins - maven-surefire-plugin - - 3.1.2 - org.apache.maven.plugins diff --git a/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/APIGatewayRequestDeserializationFunctionTest.java b/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/APIGatewayRequestDeserializationFunctionTest.java deleted file mode 100644 index ec8cdbd33..000000000 --- a/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/APIGatewayRequestDeserializationFunctionTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 org.demo.serialization; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -class APIGatewayRequestDeserializationFunctionTest { - - @Mock - private Context context; - private APIGatewayRequestDeserializationFunction deserializationFunction; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - deserializationFunction = new APIGatewayRequestDeserializationFunction(); - } - - @Test - public void shouldReturnOkStatusWithProductId() { - String body = "{\"id\":1234, \"name\":\"product\", \"price\":42}"; - APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent().withBody(body); - - APIGatewayProxyResponseEvent response = deserializationFunction.handleRequest(request, context); - - assertEquals(200, response.getStatusCode()); - assertEquals("Received request for productId: 1234", response.getBody()); - } -} \ No newline at end of file diff --git a/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/SQSEventDeserializationFunctionTest.java b/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/SQSEventDeserializationFunctionTest.java deleted file mode 100644 index b46af3052..000000000 --- a/examples/powertools-examples-serialization/src/test/java/org/demo/serialization/SQSEventDeserializationFunctionTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 org.demo.serialization; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.SQSEvent; -import java.util.ArrayList; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -class SQSEventDeserializationFunctionTest { - - @Mock - private Context context; - private SQSEventDeserializationFunction deserializationFunction; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - deserializationFunction = new SQSEventDeserializationFunction(); - } - - @Test - public void shouldReturnNumberOfReceivedMessages() { - SQSEvent.SQSMessage message1 = messageWithBody("{ \"id\": 1234, \"name\": \"product\", \"price\": 42}"); - SQSEvent.SQSMessage message2 = messageWithBody("{ \"id\": 12345, \"name\": \"product5\", \"price\": 45}"); - SQSEvent event = new SQSEvent(); - event.setRecords(new ArrayList() {{ - add(message1); - add(message2); - }}); - - String response = deserializationFunction.handleRequest(event, context); - - assertEquals("Number of received messages: 2", response); - } - - private SQSEvent.SQSMessage messageWithBody(String body) { - SQSEvent.SQSMessage record1 = new SQSEvent.SQSMessage(); - record1.setBody(body); - return record1; - } -} \ No newline at end of file diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 889fe85da..0338fe7d9 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -103,6 +103,7 @@ shade + false diff --git a/examples/powertools-examples-validation/pom.xml b/examples/powertools-examples-validation/pom.xml index 29f52b33e..65628f6b2 100644 --- a/examples/powertools-examples-validation/pom.xml +++ b/examples/powertools-examples-validation/pom.xml @@ -42,36 +42,10 @@ aws-lambda-java-core 1.2.3 - - - - org.mockito - mockito-core - 4.11.0 - test - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.9.3 - test - - - org.apache.maven.plugins - maven-surefire-plugin - - 3.1.2 - dev.aspectj aspectj-maven-plugin diff --git a/examples/powertools-examples-validation/src/test/java/org/demo/validation/InboundValidationTest.java b/examples/powertools-examples-validation/src/test/java/org/demo/validation/InboundValidationTest.java deleted file mode 100644 index d5e6de313..000000000 --- a/examples/powertools-examples-validation/src/test/java/org/demo/validation/InboundValidationTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 org.demo.validation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import software.amazon.lambda.powertools.validation.ValidationException; - -public class InboundValidationTest { - - @Mock - private Context context; - private InboundValidation inboundValidation; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - inboundValidation = new InboundValidation(); - } - - @Test - public void shouldReturnOkStatusWhenInputIsValid() { - String body = "{\n" + - " \"id\": 43242,\n" + - " \"name\": \"FooBar XY\",\n" + - " \"price\": 258\n" + - " }"; - APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent().withBody(body); - - APIGatewayProxyResponseEvent response = inboundValidation.handleRequest(request, context); - - assertEquals(200, response.getStatusCode()); - } - - @Test - public void shouldThrowExceptionWhenRequestInInvalid() { - String bodyWithMissedId = "{\n" + - " \"name\": \"FooBar XY\",\n" + - " \"price\": 258\n" + - " }"; - APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent().withBody(bodyWithMissedId); - - assertThrows(ValidationException.class, () -> inboundValidation.handleRequest(request, context)); - } -} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 823b09d61..e1a0c5a6c 100644 --- a/pom.xml +++ b/pom.xml @@ -263,18 +263,6 @@ 3.13.0 test - - org.mockito - mockito-core - 4.11.0 - test - - - org.mockito - mockito-inline - 4.11.0 - test - org.aspectj aspectjweaver @@ -286,6 +274,12 @@ assertj-core 3.24.2 test + + + net.bytebuddy + byte-buddy + + org.skyscreamer @@ -544,6 +538,62 @@ + + olderThanJdk11 + + (,11) + + + + 4.11.0 + + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-inline + ${mockito.version} + test + + + + + newerThanJdk11 + + [11,) + + + 5.6.0 + + + + + org.mockito + mockito-core + ${mockito.version} + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + true + + + + + + newerThanJdk8 diff --git a/powertools-batch/pom.xml b/powertools-batch/pom.xml index 27bb33a42..0c59ce497 100644 --- a/powertools-batch/pom.xml +++ b/powertools-batch/pom.xml @@ -56,16 +56,6 @@ aws-lambda-java-tests test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - \ No newline at end of file diff --git a/powertools-cloudformation/pom.xml b/powertools-cloudformation/pom.xml index 1347d95a3..f6cd822a6 100644 --- a/powertools-cloudformation/pom.xml +++ b/powertools-cloudformation/pom.xml @@ -97,11 +97,6 @@ junit-jupiter-params test - - org.mockito - mockito-core - test - org.assertj assertj-core diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml index a5460031d..b848e9f79 100644 --- a/powertools-core/pom.xml +++ b/powertools-core/pom.xml @@ -86,11 +86,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - org.aspectj aspectjweaver @@ -101,11 +96,6 @@ assertj-core test - - org.mockito - mockito-inline - test - @@ -122,5 +112,4 @@ - \ No newline at end of file diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index e89df47f7..9dfde1bd1 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -107,16 +107,6 @@ junit-pioneer test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.apache.commons commons-lang3 diff --git a/powertools-large-messages/pom.xml b/powertools-large-messages/pom.xml index aed8cc2e4..8fdae2139 100644 --- a/powertools-large-messages/pom.xml +++ b/powertools-large-messages/pom.xml @@ -118,16 +118,6 @@ junit-pioneer test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.apache.commons commons-lang3 diff --git a/powertools-logging/pom.xml b/powertools-logging/pom.xml index 26ad8c243..c31448e30 100644 --- a/powertools-logging/pom.xml +++ b/powertools-logging/pom.xml @@ -104,16 +104,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.aspectj aspectjweaver diff --git a/powertools-metrics/pom.xml b/powertools-metrics/pom.xml index cb3acf110..eff7296c8 100644 --- a/powertools-metrics/pom.xml +++ b/powertools-metrics/pom.xml @@ -104,16 +104,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.aspectj aspectjweaver diff --git a/powertools-parameters/pom.xml b/powertools-parameters/pom.xml index f99a3d3cd..808232ab1 100644 --- a/powertools-parameters/pom.xml +++ b/powertools-parameters/pom.xml @@ -120,16 +120,6 @@ junit-jupiter-engine test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.apache.commons commons-lang3 diff --git a/powertools-sqs/pom.xml b/powertools-sqs/pom.xml index f824f409d..c4b2b54f0 100644 --- a/powertools-sqs/pom.xml +++ b/powertools-sqs/pom.xml @@ -115,11 +115,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - org.aspectj aspectjweaver diff --git a/powertools-test-suite/pom.xml b/powertools-test-suite/pom.xml index 55e713ec0..34e80b06e 100644 --- a/powertools-test-suite/pom.xml +++ b/powertools-test-suite/pom.xml @@ -100,11 +100,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - org.aspectj aspectjweaver diff --git a/powertools-tracing/pom.xml b/powertools-tracing/pom.xml index d2f14c3e0..d98a97e2a 100644 --- a/powertools-tracing/pom.xml +++ b/powertools-tracing/pom.xml @@ -105,16 +105,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - org.aspectj aspectjweaver diff --git a/powertools-validation/pom.xml b/powertools-validation/pom.xml index 606f02139..24de0ba2a 100644 --- a/powertools-validation/pom.xml +++ b/powertools-validation/pom.xml @@ -111,11 +111,6 @@ commons-lang3 test - - org.mockito - mockito-core - test - org.aspectj aspectjweaver From 5f26c7683eb1b5ec182837f3b14df8fad2886645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:28:00 +0200 Subject: [PATCH 64/74] chore: add missing projects and improve workflow (#1487) --- .github/workflows/pr_build.yml | 53 ++++++++++++++++------------- .github/workflows/run-e2e-tests.yml | 12 ++++--- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 04f35c63b..c316c0073 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -6,18 +6,21 @@ on: - main - v2 paths: + - 'powertools-batch/**' - 'powertools-cloudformation/**' - - 'powertools-core/**' - - 'powertools-serialization/**' + - 'powertools-core/**' # not in v2 + - 'powertools-common/**' # v2 only + - 'powertools-e2e-tests/**' + - 'powertools-idempotency/**' + - 'powertools-large-messages/**' - 'powertools-logging/**' - - 'powertools-sqs/**' + - 'powertools-metrics/**' + - 'powertools-parameters/**' + - 'powertools-serialization/**' + - 'powertools-sqs/**' # not in v2 + - 'powertools-test-suite/**' # not in v2 - 'powertools-tracing/**' - 'powertools-validation/**' - - 'powertools-idempotency/**' - - 'powertools-parameters/**' - - 'powertools-metrics/**' - - 'powertools-test-suite/**' - - 'powertools-e2e-tests/**' - 'examples/**' - 'pom.xml' - 'examples/pom.xml' @@ -26,18 +29,20 @@ on: branches: - main paths: + - 'powertools-batch/**' - 'powertools-cloudformation/**' - 'powertools-core/**' - - 'powertools-serialization/**' + - '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/**' - - 'powertools-idempotency/**' - - 'powertools-parameters/**' - - 'powertools-metrics/**' - - 'powertools-test-suite/**' - - 'powertools-e2e-tests/**' - 'examples/**' - 'pom.xml' - 'examples/pom.xml' @@ -48,7 +53,7 @@ jobs: strategy: max-parallel: 5 matrix: - java: [8, 11, 15, 16, 17, 18, 19, 20, 21 ] + java: [8, 11, 17, 21, 15, 16, 18, 19, 20] name: Java ${{ matrix.java }} env: JAVA: ${{ matrix.java }} @@ -68,26 +73,26 @@ jobs: 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 - run: | - cd examples/powertools-examples-core/gradle - ./gradlew build + working-directory: examples/powertools-examples-core/gradle + run: ./gradlew build - name: Build Gradle Example - Kotlin - run: | - cd examples/powertools-examples-core/kotlin - ./gradlew build + if: ${{ matrix.java == '8' }} # Gradle example can only be built on Java 8 + working-directory: examples/powertools-examples-core/kotlin + run: ./gradlew build - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 - name: Setup AWS credentials + if: ${{ matrix.java == '11' }} uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} aws-region: ${{ env.AWS_REGION }} - name: Terraform validate + working-directory: examples/powertools-examples-core/terraform if: ${{ matrix.java == '11' }} run: | terraform -version - cd examples/powertools-examples-core/terraform terraform init -backend=false terraform validate terraform plan @@ -95,17 +100,17 @@ jobs: if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 - name: Terraform lint + working-directory: examples/powertools-examples-core/terraform if: ${{ matrix.java == '11' }} run: | tflint --version - cd examples/powertools-examples-core/terraform tflint --init tflint -f compact - 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 + 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 diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index c4a8c6fb2..a2a1b9aec 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -9,14 +9,16 @@ on: - v2 paths: # add other modules when there are under e2e tests - 'powertools-e2e-tests/**' + - 'powertools-batch/**' - 'powertools-core/**' - - 'powertools-serialization/**' - - 'powertools-logging/**' - - 'powertools-tracing/**' + - 'powertools-common/**' - 'powertools-idempotency/**' - - 'powertools-parameters/**' + - 'powertools-large-message/**' + - 'powertools-logging/**' - 'powertools-metrics/**' - - 'powertools-large-messages/**' + - 'powertools-parameters/**' + - 'powertools-serialization/**' + - 'powertools-tracing/**' - 'pom.xml' - '.github/workflows/**' From cd0f3dc1b00f5c4a34138febe9e7dc0cae9ea4f9 Mon Sep 17 00:00:00 2001 From: Scott Gerring Date: Tue, 24 Oct 2023 16:18:23 +0200 Subject: [PATCH 65/74] docs(customer-reference): add Vertex Pharmaceuticals as a customer reference (#1486) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2afb40e5d..900395554 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ The following companies, among others, use Powertools: * [Capital One](https://www.capitalone.com/) * [CPQi (Exadel Financial Services)](https://cpqi.com/) * [Europace AG](https://europace.de/) +* [Vertex Pharmaceuticals](https://www.vrtx.com/) ## Credits From cfe069f61161c26e85d570c7b15a1d44b5949c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:18:04 +0200 Subject: [PATCH 66/74] enforce our version of jackson-databind in serialization module (#1472) --- powertools-serialization/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/powertools-serialization/pom.xml b/powertools-serialization/pom.xml index b1f228df7..e5c4087fe 100644 --- a/powertools-serialization/pom.xml +++ b/powertools-serialization/pom.xml @@ -67,6 +67,10 @@ org.apache.logging.log4j log4j-slf4j2-impl + + com.fasterxml.jackson.core + jackson-databind + From 6e334199976f004e0d4ab115e1bc1eb35fd13a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Thu, 26 Oct 2023 11:12:43 +0200 Subject: [PATCH 67/74] chore: artifacts size on good branches (#1493) --- .github/workflows/pr_artifacts_size.yml | 23 ++++++++++++------- .../powertools-examples-idempotency/pom.xml | 7 ------ powertools-idempotency/pom.xml | 7 ------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.github/workflows/pr_artifacts_size.yml b/.github/workflows/pr_artifacts_size.yml index cbacd78da..f37f83a8d 100644 --- a/.github/workflows/pr_artifacts_size.yml +++ b/.github/workflows/pr_artifacts_size.yml @@ -3,19 +3,26 @@ name: Artifacts Size on: pull_request: branches: - - master + - main + - v2 paths: + - 'powertools-batch/**' - 'powertools-cloudformation/**' - - 'powertools-core/**' - - 'powertools-serialization/**' + - 'powertools-core/**' # not in v2 + - 'powertools-common/**' # v2 only + - 'powertools-e2e-tests/**' + - 'powertools-idempotency/**' + - 'powertools-large-messages/**' - 'powertools-logging/**' - - 'powertools-sqs/**' + - 'powertools-metrics/**' + - 'powertools-parameters/**' + - 'powertools-serialization/**' + - 'powertools-sqs/**' # not in v2 + - 'powertools-test-suite/**' # not in v2 - 'powertools-tracing/**' - 'powertools-validation/**' - - 'powertools-parameters/**' - - 'powertools-idempotency/**' - - 'powertools-metrics/**' - 'pom.xml' + - '.github/workflows/pr_artifacts_size.yml' jobs: codecheck: runs-on: ubuntu-latest @@ -27,7 +34,7 @@ jobs: distribution: 'corretto' java-version: 11 - name: Build with Maven - run: mvn clean package --file pom.xml -DskipTests + run: mvn clean package --file pom.xml -DskipTests artifact:buildinfo - name: Get artifacts size & build report id: artifacts-size-report run: | diff --git a/examples/powertools-examples-idempotency/pom.xml b/examples/powertools-examples-idempotency/pom.xml index 8cda4bfb3..4b8eba9c9 100644 --- a/examples/powertools-examples-idempotency/pom.xml +++ b/examples/powertools-examples-idempotency/pom.xml @@ -244,11 +244,4 @@ - - - dynamodb-local-oregon - DynamoDB Local Release Repository - https://s3.eu-central-1.amazonaws.com/dynamodb-local-frankfurt/release - - diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index 9dfde1bd1..8b3459dee 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -189,11 +189,4 @@ - - - dynamodb-local-oregon - DynamoDB Local Release Repository - https://s3.eu-central-1.amazonaws.com/dynamodb-local-frankfurt/release - - \ No newline at end of file From 0a30d8e9e6cfa117e998509883233ebf411263c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Wed, 8 Nov 2023 11:06:35 +0100 Subject: [PATCH 68/74] Update CONTRIBUTING.md --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8db303737..c4330cf8e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,8 +55,7 @@ We strongly recommend installing the CheckStyle-IDEA plugin and apply the provid 2. After installing the plugin, open the preferences (`⌘,` on macOS, or `Ctrl+Alt+S` on Windows/Linux) and search for _Code Style_. Click on the gear icon near the scheme and import checkstyle configuration. Click on "Apply" and "OK". ![](docs/media/intellij_checkstyle_1.png) -3. Select the code you've created (module, package, class) and reformat code: `⌘⌥L` (macOS), or `Ctrl+Alt+L` (Windows/Linux): -![](docs/media/intellij_checkstyle_2.png) +3. Select the code you've created (module, package, class) and reformat code: `⌘⌥L` (macOS), or `Ctrl+Alt+L` (Windows/Linux). 4. Apply the reformat, optimize imports, rearrange and cleanup to your code and only to java files: ![](docs/media/intellij_checkstyle_3.png) From 7918d9a862cdaa30dbb93b51232216e31f79f5c3 Mon Sep 17 00:00:00 2001 From: Michele Ricciardi Date: Wed, 8 Nov 2023 16:35:51 +0100 Subject: [PATCH 69/74] fix: get trace id from system property when env var is not set (#1503) * fix: check if XRAY Trace ID is present in System property * chore: remove erroneous extra char in tests --- .../core/internal/LambdaConstants.java | 1 + .../core/internal/LambdaHandlerProcessor.java | 8 +++- .../core/internal/SystemWrapper.java | 4 ++ .../amazon/lambda/powertools/LoggingE2ET.java | 2 + .../internal/LambdaLoggingAspectTest.java | 21 ++++++++- .../powertools/metrics/MetricsLoggerTest.java | 44 +++++++++++++++++-- .../internal/LambdaMetricsAspectTest.java | 6 +-- 7 files changed, 77 insertions(+), 9 deletions(-) diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java index d0f94260b..e64e334c5 100644 --- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java +++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaConstants.java @@ -24,6 +24,7 @@ public class LambdaConstants { @Deprecated public static final String ON_DEMAND = "on-demand"; public static final String X_AMZN_TRACE_ID = "_X_AMZN_TRACE_ID"; + public static final String XRAY_TRACE_HEADER = "com.amazonaws.xray.traceHeader"; public static final String AWS_SAM_LOCAL = "AWS_SAM_LOCAL"; public static final String ROOT_EQUALS = "Root="; public static final String POWERTOOLS_SERVICE_NAME = "POWERTOOLS_SERVICE_NAME"; diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java index e9e220e41..91c93c3f3 100644 --- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java +++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java @@ -16,6 +16,7 @@ import static java.util.Optional.empty; import static java.util.Optional.of; +import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getProperty; import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv; import com.amazonaws.services.lambda.runtime.Context; @@ -93,7 +94,12 @@ public static boolean isSamLocal() { } public static Optional getXrayTraceId() { - final String X_AMZN_TRACE_ID = getenv(LambdaConstants.X_AMZN_TRACE_ID); + String X_AMZN_TRACE_ID = getenv(LambdaConstants.X_AMZN_TRACE_ID); + // For the Java Lambda 17+ runtime, the Trace ID is set as a System Property + if (X_AMZN_TRACE_ID == null) { + X_AMZN_TRACE_ID = getProperty(LambdaConstants.XRAY_TRACE_HEADER); + } + if (X_AMZN_TRACE_ID != null) { return of(X_AMZN_TRACE_ID.split(";")[0].replace(LambdaConstants.ROOT_EQUALS, "")); } diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/SystemWrapper.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/SystemWrapper.java index 30f72232f..99046ffec 100644 --- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/SystemWrapper.java +++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/SystemWrapper.java @@ -21,4 +21,8 @@ private SystemWrapper() { public static String getenv(String name) { return System.getenv(name); } + + public static String getProperty(String name) { + return System.getProperty(name); + } } diff --git a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/LoggingE2ET.java b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/LoggingE2ET.java index f958970d8..b060879d3 100644 --- a/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/LoggingE2ET.java +++ b/powertools-e2e-tests/src/test/java/software/amazon/lambda/powertools/LoggingE2ET.java @@ -46,6 +46,7 @@ public class LoggingE2ET { public static void setup() { infrastructure = Infrastructure.builder() .testName(LoggingE2ET.class.getSimpleName()) + .tracing(true) .pathToFunction("logging") .environmentVariables( Stream.of(new String[][] { @@ -83,6 +84,7 @@ public void test_logInfoWithAdditionalKeys() throws JsonProcessingException { assertThat(jsonNode.get("message").asText()).isEqualTo("New Order"); assertThat(jsonNode.get("orderId").asText()).isEqualTo(orderId); assertThat(jsonNode.get("coldStart").asBoolean()).isTrue(); + assertThat(jsonNode.get("xray_trace_id").asText()).isNotBlank(); assertThat(jsonNode.get("function_request_id").asText()).isEqualTo(invocationResult1.getRequestId()); // second call should not be cold start diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java index b78710586..6952fe755 100644 --- a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java +++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getProperty; import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv; import com.amazonaws.services.lambda.runtime.Context; @@ -245,13 +246,31 @@ void shouldLogServiceNameWhenEnvVarSet() throws IllegalAccessException { .containsEntry("service", "testService"); } + @Test + void shouldLogxRayTraceIdSystemPropertySet() { + String xRayTraceId = "1-5759e988-bd862e3fe1be46a994272793"; + + try (MockedStatic mocked = mockStatic(SystemWrapper.class)) { + mocked.when(() -> getenv("_X_AMZN_TRACE_ID")) + .thenReturn(null); + mocked.when(() -> getProperty("com.amazonaws.xray.traceHeader")) + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); + + requestHandler.handleRequest(new Object(), context); + + assertThat(ThreadContext.getImmutableContext()) + .hasSize(EXPECTED_CONTEXT_SIZE + 1) + .containsEntry("xray_trace_id", xRayTraceId); + } + } + @Test void shouldLogxRayTraceIdEnvVarSet() { String xRayTraceId = "1-5759e988-bd862e3fe1be46a994272793"; try (MockedStatic mocked = mockStatic(SystemWrapper.class)) { mocked.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); requestHandler.handleRequest(new Object(), context); diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java index 7f234a4d6..16a068849 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNullPointerException; import static org.mockito.Mockito.mockStatic; +import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getProperty; import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv; import com.fasterxml.jackson.core.JsonProcessingException; @@ -66,7 +67,7 @@ void singleMetricsCaptureUtilityWithDefaultDimension() { software.amazon.lambda.powertools.core.internal.SystemWrapper.class)) { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); MetricsUtils.defaultDimensions(DimensionSet.of("Service", "Booking")); @@ -96,7 +97,7 @@ void singleMetricsCaptureUtility() { software.amazon.lambda.powertools.core.internal.SystemWrapper.class)) { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, "test", metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); @@ -123,7 +124,7 @@ void singleMetricsCaptureUtilityWithDefaultNameSpace() { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); mocked.when(() -> SystemWrapper.getenv("POWERTOOLS_METRICS_NAMESPACE")).thenReturn("GlobalName"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); @@ -165,6 +166,41 @@ void shouldThrowExceptionWhenDefaultDimensionIsNull() { .withMessage("Null dimension set not allowed"); } + @Test + void shouldUseTraceIdFromSystemPropertyIfEnvVarNotPresent() { + try (MockedStatic mocked = mockStatic(SystemWrapper.class); + MockedStatic internalWrapper = mockStatic( + software.amazon.lambda.powertools.core.internal.SystemWrapper.class)) { + mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); + mocked.when(() -> SystemWrapper.getenv("POWERTOOLS_METRICS_NAMESPACE")).thenReturn("GlobalName"); + internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) + .thenReturn(null); + internalWrapper.when(() -> getProperty("com.amazonaws.xray.traceHeader")) + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); + + MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, + metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); + + assertThat(out.toString()) + .satisfies(s -> + { + Map logAsJson = readAsJson(s); + + assertThat(logAsJson) + .containsEntry("Metric1", 1.0) + .containsEntry("Dimension1", "Value1") + .containsKey("_aws") + .containsEntry("xray_trace_id", "1-5759e988-bd862e3fe1be46a994272793"); + + Map aws = (Map) logAsJson.get("_aws"); + + assertThat(aws.get("CloudWatchMetrics")) + .asString() + .contains("Namespace=GlobalName"); + }); + } + } + private void testLogger(Consumer> methodToTest) { try (MockedStatic mocked = mockStatic(SystemWrapper.class); MockedStatic internalWrapper = mockStatic( @@ -172,7 +208,7 @@ private void testLogger(Consumer> methodToTest) { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); mocked.when(() -> SystemWrapper.getenv("POWERTOOLS_METRICS_NAMESPACE")).thenReturn("GlobalName"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); methodToTest.accept(metricsLogger -> { diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java index eaddfa75d..0a735c75e 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/internal/LambdaMetricsAspectTest.java @@ -91,7 +91,7 @@ public void metricsWithoutColdStart() { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); MetricsUtils.defaultDimensions(null); requestHandler = new PowertoolsMetricsEnabledHandler(); @@ -135,7 +135,7 @@ public void metricsWithDefaultDimensionSpecified() { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); requestHandler = new PowertoolsMetricsEnabledDefaultDimensionHandler(); @@ -179,7 +179,7 @@ public void metricsWithDefaultNoDimensionSpecified() { mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); internalWrapper.when(() -> getenv("_X_AMZN_TRACE_ID")) - .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\""); + .thenReturn("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); requestHandler = new PowertoolsMetricsEnabledDefaultNoDimensionHandler(); From 0f3e8960d5fab2f658e5e855e7bd979c9d77d17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:52:08 +0100 Subject: [PATCH 70/74] fix #1500 (#1506) --- .../powertools/metrics/MetricsUtils.java | 8 +++-- .../powertools/metrics/MetricsLoggerTest.java | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java index 09517d46e..7891b22ec 100644 --- a/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java +++ b/powertools-metrics/src/main/java/software/amazon/lambda/powertools/metrics/MetricsUtils.java @@ -178,8 +178,12 @@ private static void captureRequestAndTraceId(MetricsLogger metricsLogger) { private static String defaultNameSpace() { MetricsContext context = MetricsLoggerHelper.metricsContext(); - return "aws-embedded-metrics".equals(context.getNamespace()) ? - SystemWrapper.getenv("POWERTOOLS_METRICS_NAMESPACE") : context.getNamespace(); + if ("aws-embedded-metrics".equals(context.getNamespace())) { + String namespace = SystemWrapper.getenv("POWERTOOLS_METRICS_NAMESPACE"); + return namespace != null ? namespace : "aws-embedded-metrics"; + } else { + return context.getNamespace(); + } } private static Optional awsRequestId() { diff --git a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java index 16a068849..ce9d63cfd 100644 --- a/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java +++ b/powertools-metrics/src/test/java/software/amazon/lambda/powertools/metrics/MetricsLoggerTest.java @@ -112,6 +112,37 @@ void singleMetricsCaptureUtility() { .containsEntry("Dimension1", "Value1") .containsKey("_aws") .containsEntry("xray_trace_id", "1-5759e988-bd862e3fe1be46a994272793"); + + Map aws = (Map) logAsJson.get("_aws"); + + assertThat(aws.get("CloudWatchMetrics")) + .asString() + .contains("Namespace=test"); + }); + } + } + + @Test + void singleMetricsCaptureUtilityWithNullNamespace() { + try (MockedStatic mocked = mockStatic(SystemWrapper.class); + MockedStatic internalWrapper = mockStatic( + software.amazon.lambda.powertools.core.internal.SystemWrapper.class)) { + mocked.when(() -> SystemWrapper.getenv("AWS_EMF_ENVIRONMENT")).thenReturn("Lambda"); + // POWERTOOLS_METRICS_NAMESPACE is not defined + + MetricsUtils.withSingleMetric("Metric1", 1, Unit.COUNT, + metricsLogger -> metricsLogger.setDimensions(DimensionSet.of("Dimension1", "Value1"))); + + assertThat(out.toString()) + .satisfies(s -> + { + Map logAsJson = readAsJson(s); + + Map aws = (Map) logAsJson.get("_aws"); + + assertThat(aws.get("CloudWatchMetrics")) + .asString() + .contains("Namespace=aws-embedded-metrics"); }); } } From de547d02754216c06812d73d80159d55be8007e3 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 14 Nov 2023 14:27:38 +0000 Subject: [PATCH 71/74] feat: Add support for POWERTOOLS_LOGGER_LOG_EVENT (#1510) --- docs/core/logging.md | 4 +- docs/index.md | 2 + .../core/internal/LambdaHandlerProcessor.java | 7 ++ .../logging/internal/LambdaLoggingAspect.java | 14 ++- .../handlers/PowerToolLogEventDisabled.java | 28 +++++ .../internal/LambdaLoggingAspectTest.java | 119 +++++++++++------- 6 files changed, 127 insertions(+), 47 deletions(-) create mode 100644 powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/handlers/PowerToolLogEventDisabled.java diff --git a/docs/core/logging.md b/docs/core/logging.md index 2df9a4529..fd74db3d2 100644 --- a/docs/core/logging.md +++ b/docs/core/logging.md @@ -217,9 +217,7 @@ Key | Type | Example | Description ## Capturing context Lambda info -You can enrich your structured logs with key Lambda context information via `logEvent` annotation parameter. -You can also explicitly log any incoming event using `logEvent` param. Refer [Override default object mapper](#override-default-object-mapper) -to customise what is logged. +When debugging in non-production environments, you can instruct Logger to log the incoming event with `@Logger(logEvent = true)` or via `POWERTOOLS_LOGGER_LOG_EVENT=true` environment variable. !!! warning Log event is disabled by default to prevent sensitive info being logged. diff --git a/docs/index.md b/docs/index.md index 6af4c5e8d..92589be7c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -285,5 +285,7 @@ Depending on your version of Java (either Java 1.8 or 11+), the configuration sl | **POWERTOOLS_METRICS_NAMESPACE** | Sets namespace used for metrics | [Metrics](./core/metrics) | | **POWERTOOLS_LOGGER_SAMPLE_RATE** | Debug log sampling | [Logging](./core/logging) | | **POWERTOOLS_LOG_LEVEL** | Sets logging level | [Logging](./core/logging) | +| **POWERTOOLS_LOGGER_LOG_EVENT** | Enables/Disables whether to log the incoming event when using the aspect | [Logging](./core/logging) | | **POWERTOOLS_TRACER_CAPTURE_RESPONSE** | Enables/Disables tracing mode to capture method response | [Tracing](./core/tracing) | | **POWERTOOLS_TRACER_CAPTURE_ERROR** | Enables/Disables tracing mode to capture method error | [Tracing](./core/tracing) | + diff --git a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java index 91c93c3f3..d4e18dddc 100644 --- a/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java +++ b/powertools-core/src/main/java/software/amazon/lambda/powertools/core/internal/LambdaHandlerProcessor.java @@ -47,6 +47,13 @@ public static boolean isHandlerMethod(final ProceedingJoinPoint pjp) { return placedOnRequestHandler(pjp) || placedOnStreamHandler(pjp); } + /** + * The class needs to implement RequestHandler interface + * The function needs to have exactly two arguments + * The second argument needs to be of type com.amazonaws.services.lambda.runtime.Context + * @param pjp + * @return + */ public static boolean placedOnRequestHandler(final ProceedingJoinPoint pjp) { return RequestHandler.class.isAssignableFrom(pjp.getSignature().getDeclaringType()) && pjp.getArgs().length == 2 diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java index 4a98735af..ff556d89a 100644 --- a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java @@ -33,6 +33,7 @@ import com.fasterxml.jackson.core.JsonPointer; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -42,6 +43,7 @@ import java.util.Map; import java.util.Optional; import java.util.Random; + import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -65,6 +67,7 @@ public final class LambdaLoggingAspect { private static final String LOG_LEVEL = System.getenv("POWERTOOLS_LOG_LEVEL"); private static final String SAMPLING_RATE = System.getenv("POWERTOOLS_LOGGER_SAMPLE_RATE"); + private static Boolean LOG_EVENT; private static Level LEVEL_AT_INITIALISATION; @@ -74,6 +77,13 @@ public final class LambdaLoggingAspect { } LEVEL_AT_INITIALISATION = LOG.getLevel(); + + String logEvent = System.getenv("POWERTOOLS_LOGGER_LOG_EVENT"); + if (logEvent != null) { + LOG_EVENT = Boolean.parseBoolean(logEvent); + } else { + LOG_EVENT = false; + } } private static void resetLogLevels(Level logLevel) { @@ -104,7 +114,9 @@ public Object around(ProceedingJoinPoint pjp, getXrayTraceId().ifPresent(xRayTraceId -> appendKey("xray_trace_id", xRayTraceId)); - if (logging.logEvent()) { + // Check that the environment variable was enabled explicitly + // Or that the handler was annotated with @Logging(logEvent = true) + if (LOG_EVENT || logging.logEvent()) { proceedArgs = logEvent(pjp); } diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/handlers/PowerToolLogEventDisabled.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/handlers/PowerToolLogEventDisabled.java new file mode 100644 index 000000000..77103e450 --- /dev/null +++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/handlers/PowerToolLogEventDisabled.java @@ -0,0 +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.logging.handlers; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import software.amazon.lambda.powertools.logging.Logging; + +public class PowerToolLogEventDisabled implements RequestHandler { + + @Logging(logEvent = false) + @Override + public Object handleRequest(Object input, Context context) { + return null; + } +} diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java index 6952fe755..75cf22aa5 100644 --- a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java +++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java @@ -14,19 +14,6 @@ package software.amazon.lambda.powertools.logging.internal; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.joining; -import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.openMocks; -import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; -import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getProperty; -import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv; - import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; @@ -37,24 +24,10 @@ import com.amazonaws.services.lambda.runtime.tests.annotations.Event; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.channels.FileChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.ThreadContext; import org.json.JSONException; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -62,18 +35,33 @@ import org.mockito.MockedStatic; import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor; import software.amazon.lambda.powertools.core.internal.SystemWrapper; -import software.amazon.lambda.powertools.logging.handlers.PowerLogToolApiGatewayHttpApiCorrelationId; -import software.amazon.lambda.powertools.logging.handlers.PowerLogToolApiGatewayRestApiCorrelationId; -import software.amazon.lambda.powertools.logging.handlers.PowerLogToolEnabled; -import software.amazon.lambda.powertools.logging.handlers.PowerLogToolEnabledForStream; -import software.amazon.lambda.powertools.logging.handlers.PowerToolDisabled; -import software.amazon.lambda.powertools.logging.handlers.PowerToolDisabledForStream; -import software.amazon.lambda.powertools.logging.handlers.PowerToolLogEventEnabled; -import software.amazon.lambda.powertools.logging.handlers.PowerToolLogEventEnabledForStream; -import software.amazon.lambda.powertools.logging.handlers.PowerToolLogEventEnabledWithCustomMapper; -import software.amazon.lambda.powertools.logging.handlers.PowertoolsLogAlbCorrelationId; -import software.amazon.lambda.powertools.logging.handlers.PowertoolsLogEnabledWithClearState; -import software.amazon.lambda.powertools.logging.handlers.PowertoolsLogEventBridgeCorrelationId; +import software.amazon.lambda.powertools.logging.handlers.*; + +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.openMocks; +import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getProperty; +import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv; class LambdaLoggingAspectTest { @@ -116,7 +104,7 @@ void shouldSetLambdaContextWhenEnabled() { void shouldSetLambdaContextForStreamHandlerWhenEnabled() throws IOException { requestStreamHandler = new PowerLogToolEnabledForStream(); - requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[] {}), new ByteArrayOutputStream(), + requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[]{}), new ByteArrayOutputStream(), context); assertThat(ThreadContext.getImmutableContext()) @@ -132,14 +120,14 @@ void shouldSetLambdaContextForStreamHandlerWhenEnabled() throws IOException { @Test void shouldSetColdStartFlag() throws IOException { - requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[] {}), new ByteArrayOutputStream(), + requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[]{}), new ByteArrayOutputStream(), context); assertThat(ThreadContext.getImmutableContext()) .hasSize(EXPECTED_CONTEXT_SIZE) .containsEntry("coldStart", "true"); - requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[] {}), new ByteArrayOutputStream(), + requestStreamHandler.handleRequest(new ByteArrayInputStream(new byte[]{}), new ByteArrayOutputStream(), context); assertThat(ThreadContext.getImmutableContext()) @@ -195,6 +183,51 @@ void shouldLogEventForHandler() throws IOException, JSONException { assertEquals(expectEvent, event, false); } + /** + * If POWERTOOLS_LOGGER_LOG_EVENT was set to true, the handler should log, despite @Logging(logEvent=false) + * + * @throws IOException + */ + @Test + void shouldLogEventForHandlerWhenEnvVariableSetToTrue() throws IOException, IllegalAccessException, JSONException { + try { + writeStaticField(LambdaLoggingAspect.class, "LOG_EVENT", Boolean.TRUE, true); + + requestHandler = new PowerToolLogEventDisabled(); + S3EventNotification s3EventNotification = s3EventNotification(); + + requestHandler.handleRequest(s3EventNotification, context); + + Map log = parseToMap(Files.lines(Paths.get("target/logfile.json")).collect(joining())); + + String event = (String) log.get("message"); + + String expectEvent = new BufferedReader( + new InputStreamReader(this.getClass().getResourceAsStream("/s3EventNotification.json"))) + .lines().collect(joining("\n")); + + assertEquals(expectEvent, event, false); + } finally { + writeStaticField(LambdaLoggingAspect.class, "LOG_EVENT", Boolean.FALSE, true); + } + } + + /** + * If POWERTOOLS_LOGGER_LOG_EVENT was set to false and @Logging(logEvent=false), the handler shouldn't log + * + * @throws IOException + */ + @Test + void shouldNotLogEventForHandlerWhenEnvVariableSetToFalse() throws IOException { + requestHandler = new PowerToolLogEventDisabled(); + S3EventNotification s3EventNotification = s3EventNotification(); + + requestHandler.handleRequest(s3EventNotification, context); + + Assertions.assertEquals(0, + Files.lines(Paths.get("target/logfile.json")).collect(joining()).length()); + } + @Test void shouldLogEventForHandlerWithOverriddenObjectMapper() throws IOException, JSONException { RequestHandler handler = new PowerToolLogEventEnabledWithCustomMapper(); From 30c8d33d0d663ec0d6512cfbcea49e2e68aff0c9 Mon Sep 17 00:00:00 2001 From: jdoherty Date: Tue, 14 Nov 2023 14:29:35 +0000 Subject: [PATCH 72/74] chore: Addition of Warn Message If Invalid Annotation Key While Tracing #1511 (#1512) --- .../powertools/tracing/TracingUtils.java | 21 +++++++++++++++++++ .../powertools/tracing/TracingUtilsTest.java | 21 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/TracingUtils.java b/powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/TracingUtils.java index 9fb021548..47c4e7422 100644 --- a/powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/TracingUtils.java +++ b/powertools-tracing/src/main/java/software/amazon/lambda/powertools/tracing/TracingUtils.java @@ -21,12 +21,15 @@ import com.amazonaws.xray.entities.Subsegment; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.function.Consumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A class of helper functions to add additional functionality and ease * of use. */ public final class TracingUtils { + private static final Logger LOG = LoggerFactory.getLogger(TracingUtils.class); private static ObjectMapper objectMapper; /** @@ -36,6 +39,10 @@ public final class TracingUtils { * @param value the value of the annotation */ public static void putAnnotation(String key, String value) { + if (!isValidAnnotationKey(key)) { + LOG.warn("Ignoring annotation with unsupported characters in key: {}", key); + return; + } AWSXRay.getCurrentSubsegmentOptional() .ifPresent(segment -> segment.putAnnotation(key, value)); } @@ -47,10 +54,24 @@ public static void putAnnotation(String key, String value) { * @param value the value of the annotation */ public static void putAnnotation(String key, Number value) { + if (!isValidAnnotationKey(key)) { + LOG.warn("Ignoring annotation with unsupported characters in key: {}", key); + return; + } AWSXRay.getCurrentSubsegmentOptional() .ifPresent(segment -> segment.putAnnotation(key, value)); } + /** + Make sure that the annotation key is valid according to + the documentation. + + Annotation keys that are added that are invalid are ignored by x-ray. + **/ + private static boolean isValidAnnotationKey(String key) { + return key.matches("^[a-zA-Z0-9_]+$"); + } + /** * Put an annotation to the current subsegment with a Boolean value. * diff --git a/powertools-tracing/src/test/java/software/amazon/lambda/powertools/tracing/TracingUtilsTest.java b/powertools-tracing/src/test/java/software/amazon/lambda/powertools/tracing/TracingUtilsTest.java index 78283fbc2..01f25f37a 100644 --- a/powertools-tracing/src/test/java/software/amazon/lambda/powertools/tracing/TracingUtilsTest.java +++ b/powertools-tracing/src/test/java/software/amazon/lambda/powertools/tracing/TracingUtilsTest.java @@ -28,7 +28,6 @@ import org.junit.jupiter.api.Test; class TracingUtilsTest { - @BeforeEach void setUp() { AWSXRay.beginSegment("test"); @@ -123,6 +122,24 @@ void shouldInvokeCodeBlockWrappedWithinSubsegment() { }); } + @Test + void shouldNotAddAnnotationIfInvalidCharacterInKey() { + AWSXRay.beginSubsegment("subSegment"); + String inputKey = "stringKey with spaces"; + TracingUtils.putAnnotation(inputKey, "val"); + AWSXRay.getCurrentSubsegmentOptional() + .ifPresent(segment -> assertThat(segment.getAnnotations()).size().isEqualTo(0)); + } + + @Test + void shouldAddAnnotationIfValidCharactersInKey() { + AWSXRay.beginSubsegment("subSegment"); + String inputKey = "validKey"; + TracingUtils.putAnnotation(inputKey, "val"); + AWSXRay.getCurrentSubsegmentOptional() + .ifPresent(segment -> assertThat(segment.getAnnotations()).size().isEqualTo(1)); + } + @Test void shouldInvokeCodeBlockWrappedWithinNamespacedSubsegment() { Context test = mock(Context.class); @@ -221,4 +238,4 @@ void shouldInvokeCodeBlockWrappedWithinNamespacedEntitySubsegment() throws Inter .containsEntry("key", "val"); }); } -} \ No newline at end of file +} From 6b8fe49dddf33c8d63b1346a365b3e7cfdff4f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Thu, 16 Nov 2023 13:23:18 +0100 Subject: [PATCH 73/74] feat: ALC (#1514) * handle AWS_LAMBDA_LOG configuration * ALC documentation + code review * update doc --- docs/core/logging.md | 44 ++++- powertools-logging/pom.xml | 10 ++ .../logging/internal/LambdaLoggingAspect.java | 19 +- .../internal/LambdaTimestampResolver.java | 169 ++++++++++++++++++ .../LambdaTimestampResolverFactory.java | 49 +++++ .../logging/internal/LoggingConstants.java | 27 +++ .../src/main/resources/LambdaJsonLayout.json | 2 +- .../core/layout/LambdaJsonLayoutTest.java | 31 +++- 8 files changed, 344 insertions(+), 7 deletions(-) create mode 100644 powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolver.java create mode 100644 powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolverFactory.java create mode 100644 powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LoggingConstants.java diff --git a/docs/core/logging.md b/docs/core/logging.md index fd74db3d2..0391ae7b4 100644 --- a/docs/core/logging.md +++ b/docs/core/logging.md @@ -263,7 +263,7 @@ When debugging in non-production environments, you can instruct Logger to log th } ``` -### Customising fields in logs +### Customising fields in logs - Utility by default emits `timestamp` field in the logs in format `yyyy-MM-dd'T'HH:mm:ss.SSSZz` and in system default timezone. If you need to customize format and timezone, you can do so by configuring `log4j2.component.properties` and configuring properties as shown in example below: @@ -596,6 +596,48 @@ via `samplingRate` attribute on annotation. POWERTOOLS_LOGGER_SAMPLE_RATE: 0.5 ``` +## AWS Lambda Advanced Logging Controls +With AWS [Lambda Advanced Logging Controls (ALC)](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced), you can control the output format of your logs as either `TEXT` or `JSON` and specify the minimum accepted log level for your application. +Regardless of the output format setting in Lambda, Powertools for AWS Lambda will always output JSON formatted logging messages. + +When you have this feature enabled, log messages that don’t meet the configured log level are discarded by Lambda. +For example, if you set the minimum log level to `WARN`, you will only receive `WARN` and `ERROR` messages in your AWS CloudWatch Logs, all other log levels will be discarded by Lambda. + +```mermaid +sequenceDiagram + participant Lambda service + participant Lambda function + participant Application Logger + + Note over Lambda service: AWS_LAMBDA_LOG_LEVEL="WARN" + Lambda service->>Lambda function: Invoke (event) + Lambda function->>Lambda function: Calls handler + Lambda function->>Application Logger: logger.warn("Something happened") + Lambda function-->>Application Logger: logger.debug("Something happened") + Lambda function-->>Application Logger: logger.info("Something happened") + + Lambda service->>Lambda service: DROP INFO and DEBUG logs + + Lambda service->>CloudWatch Logs: Ingest error logs +``` + +Logger will automatically listen for the `AWS_LAMBDA_LOG_FORMAT` and `AWS_LAMBDA_LOG_LEVEL` environment variables, and change behaviour if they’re found to ensure as much compatibility as possible. + +### Priority of log level settings in Powertools for AWS Lambda + +When the Advanced Logging Controls feature is enabled, we are unable to increase the minimum log level below the `AWS_LAMBDA_LOG_LEVEL` environment variable value, see [AWS Lambda service documentation](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-log-level) for more details. + +We prioritise log level settings in this order: + +1. `AWS_LAMBDA_LOG_LEVEL` environment variable +2. `POWERTOOLS_LOG_LEVEL` environment variable + +In the event you have set `POWERTOOLS_LOG_LEVEL` to a level lower than the ACL setting, Powertools for AWS Lambda will output a warning log message informing you that your messages will be discarded by Lambda. + +### Timestamp format + +When the Advanced Logging Controls feature is enabled, Powertools for AWS Lambda must comply with the timestamp format required by AWS Lambda, which is [RFC3339](https://www.rfc-editor.org/rfc/rfc3339). +In this case the format will be `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. ## Upgrade to JsonTemplateLayout from deprecated LambdaJsonLayout configuration in log4j2.xml diff --git a/powertools-logging/pom.xml b/powertools-logging/pom.xml index c31448e30..e4767893b 100644 --- a/powertools-logging/pom.xml +++ b/powertools-logging/pom.xml @@ -137,6 +137,16 @@ org.apache.maven.plugins maven-checkstyle-plugin + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + JSON + + + \ No newline at end of file diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java index ff556d89a..da770ccdb 100644 --- a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspect.java @@ -28,6 +28,7 @@ import static software.amazon.lambda.powertools.logging.LoggingUtils.appendKey; import static software.amazon.lambda.powertools.logging.LoggingUtils.appendKeys; import static software.amazon.lambda.powertools.logging.LoggingUtils.objectMapper; +import static software.amazon.lambda.powertools.logging.internal.LoggingConstants.LAMBDA_LOG_LEVEL; import com.amazonaws.services.lambda.runtime.Context; import com.fasterxml.jackson.core.JsonPointer; @@ -63,17 +64,27 @@ @DeclarePrecedence("*, software.amazon.lambda.powertools.logging.internal.LambdaLoggingAspect") public final class LambdaLoggingAspect { private static final Logger LOG = LogManager.getLogger(LambdaLoggingAspect.class); - private static final Random SAMPLER = new Random(); + private static final String POWERTOOLS_LOG_LEVEL = System.getenv("POWERTOOLS_LOG_LEVEL"); - private static final String LOG_LEVEL = System.getenv("POWERTOOLS_LOG_LEVEL"); + private static final Random SAMPLER = new Random(); private static final String SAMPLING_RATE = System.getenv("POWERTOOLS_LOGGER_SAMPLE_RATE"); private static Boolean LOG_EVENT; private static Level LEVEL_AT_INITIALISATION; static { - if (null != LOG_LEVEL) { - resetLogLevels(Level.getLevel(LOG_LEVEL)); + if (POWERTOOLS_LOG_LEVEL != null) { + Level powertoolsLevel = Level.getLevel(POWERTOOLS_LOG_LEVEL); + if (LAMBDA_LOG_LEVEL != null) { + Level lambdaLevel = Level.getLevel(LAMBDA_LOG_LEVEL); + if (powertoolsLevel.intLevel() > lambdaLevel.intLevel()) { + LOG.warn("Current log level ({}) does not match AWS Lambda Advanced Logging Controls minimum log level ({}). This can lead to data loss, consider adjusting them.", + POWERTOOLS_LOG_LEVEL, LAMBDA_LOG_LEVEL); + } + } + resetLogLevels(powertoolsLevel); + } else if (LAMBDA_LOG_LEVEL != null) { + resetLogLevels(Level.getLevel(LAMBDA_LOG_LEVEL)); } LEVEL_AT_INITIALISATION = LOG.getLevel(); diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolver.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolver.java new file mode 100644 index 000000000..500b36c95 --- /dev/null +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolver.java @@ -0,0 +1,169 @@ +/* + * 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.logging.internal; + +import static software.amazon.lambda.powertools.logging.internal.LoggingConstants.LAMBDA_LOG_FORMAT; +import static software.amazon.lambda.powertools.logging.internal.LoggingConstants.LOG_DATE_RFC3339_FORMAT; + +import java.util.Locale; +import java.util.TimeZone; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.time.MutableInstant; +import org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutDefaults; +import org.apache.logging.log4j.layout.template.json.resolver.EventResolver; +import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig; +import org.apache.logging.log4j.layout.template.json.util.InstantFormatter; +import org.apache.logging.log4j.layout.template.json.util.JsonWriter; + +/** + * Default timestamp used by log4j is not RFC3339, which is used by Lambda internally to filter logs. + * When `AWS_LAMBDA_LOG_FORMAT` is set to JSON (i.e. using Lambda logging configuration), we should use the appropriate pattern, + * otherwise logs with invalid date format are considered as INFO. + * Inspired from org.apache.logging.log4j.layout.template.json.resolver.TimestampResolver + * + * TODO: remove in v2 an replace with the good pattern in LambdaJsonLayout.json + */ +public class LambdaTimestampResolver implements EventResolver { + + private final EventResolver internalResolver; + + public LambdaTimestampResolver(final TemplateResolverConfig config) { + final PatternResolverContext patternResolverContext = + PatternResolverContext.fromConfig(config); + internalResolver = new PatternResolver(patternResolverContext); + } + + @Override + public void resolve(LogEvent value, JsonWriter jsonWriter) { + internalResolver.resolve(value, jsonWriter); + } + + static String getName() { + return "lambda-timestamp"; + } + + private static final class PatternResolverContext { + + public static final String PATTERN = "pattern"; + private final InstantFormatter formatter; + + private final StringBuilder lastFormattedInstantBuffer = new StringBuilder(); + + private final MutableInstant lastFormattedInstant = new MutableInstant(); + + private PatternResolverContext( + final String pattern, + final TimeZone timeZone, + final Locale locale) { + this.formatter = InstantFormatter + .newBuilder() + .setPattern(pattern) + .setTimeZone(timeZone) + .setLocale(locale) + .build(); + lastFormattedInstant.initFromEpochSecond(-1, 0); + } + + private static PatternResolverContext fromConfig( + final TemplateResolverConfig config) { + final String pattern = readPattern(config); + final TimeZone timeZone = readTimeZone(config); + final Locale locale = config.getLocale(new String[]{PATTERN, "locale"}); + return new PatternResolverContext(pattern, timeZone, locale); + } + + private static String readPattern(final TemplateResolverConfig config) { + final String format = config.getString(new String[]{PATTERN, "format"}); + return format != null + ? format + : getLambdaTimestampFormatOrDefault(); + } + + private static String getLambdaTimestampFormatOrDefault() { + return "JSON".equals(LAMBDA_LOG_FORMAT) ? LOG_DATE_RFC3339_FORMAT : + JsonTemplateLayoutDefaults.getTimestampFormatPattern(); + } + + private static TimeZone readTimeZone(final TemplateResolverConfig config) { + final String timeZoneId = config.getString(new String[]{PATTERN, "timeZone"}); + if (timeZoneId == null) { + return JsonTemplateLayoutDefaults.getTimeZone(); + } + boolean found = false; + for (final String availableTimeZone : TimeZone.getAvailableIDs()) { + if (availableTimeZone.equalsIgnoreCase(timeZoneId)) { + found = true; + break; + } + } + if (!found) { + throw new IllegalArgumentException( + "invalid timestamp time zone: " + config); + } + return TimeZone.getTimeZone(timeZoneId); + } + + } + + private static final class PatternResolver implements EventResolver { + + private final PatternResolverContext patternResolverContext; + + private PatternResolver(final PatternResolverContext patternResolverContext) { + this.patternResolverContext = patternResolverContext; + } + + @Override + public synchronized void resolve( + final LogEvent logEvent, + final JsonWriter jsonWriter) { + + // Format timestamp if it doesn't match the last cached one. + final boolean instantMatching = patternResolverContext.formatter.isInstantMatching( + patternResolverContext.lastFormattedInstant, + logEvent.getInstant()); + if (!instantMatching) { + + // Format the timestamp. + patternResolverContext.lastFormattedInstantBuffer.setLength(0); + patternResolverContext.lastFormattedInstant.initFrom(logEvent.getInstant()); + patternResolverContext.formatter.format( + patternResolverContext.lastFormattedInstant, + patternResolverContext.lastFormattedInstantBuffer); + + // Write the formatted timestamp. + final StringBuilder jsonWriterStringBuilder = jsonWriter.getStringBuilder(); + final int startIndex = jsonWriterStringBuilder.length(); + jsonWriter.writeString(patternResolverContext.lastFormattedInstantBuffer); + + // Cache the written value. + patternResolverContext.lastFormattedInstantBuffer.setLength(0); + patternResolverContext.lastFormattedInstantBuffer.append( + jsonWriterStringBuilder, + startIndex, + jsonWriterStringBuilder.length()); + + } + + // Write the cached formatted timestamp. + else { + jsonWriter.writeRawString( + patternResolverContext.lastFormattedInstantBuffer); + } + + } + + } +} diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolverFactory.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolverFactory.java new file mode 100644 index 000000000..2022c6d4a --- /dev/null +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LambdaTimestampResolverFactory.java @@ -0,0 +1,49 @@ +/* + * 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.logging.internal; + +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.layout.template.json.resolver.EventResolverContext; +import org.apache.logging.log4j.layout.template.json.resolver.EventResolverFactory; +import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolver; +import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig; +import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverFactory; + +@Plugin(name = "LambdaTimestampResolverFactory", category = TemplateResolverFactory.CATEGORY) +public final class LambdaTimestampResolverFactory implements EventResolverFactory { + + private static final LambdaTimestampResolverFactory INSTANCE = new LambdaTimestampResolverFactory(); + + private LambdaTimestampResolverFactory() { + } + + @PluginFactory + public static LambdaTimestampResolverFactory getInstance() { + return INSTANCE; + } + + @Override + public String getName() { + return LambdaTimestampResolver.getName(); + } + + @Override + public TemplateResolver create(EventResolverContext context, + TemplateResolverConfig config) { + return new LambdaTimestampResolver(config); + } +} diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LoggingConstants.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LoggingConstants.java new file mode 100644 index 000000000..e58ca4109 --- /dev/null +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/LoggingConstants.java @@ -0,0 +1,27 @@ +/* + * 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.logging.internal; + +public class LoggingConstants { + public static final String LAMBDA_LOG_LEVEL = System.getenv("AWS_LAMBDA_LOG_LEVEL"); + + public static final String LAMBDA_LOG_FORMAT = System.getenv("AWS_LAMBDA_LOG_FORMAT"); + + public static final String LOG_DATE_RFC3339_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + + private LoggingConstants() { + // constants + } +} diff --git a/powertools-logging/src/main/resources/LambdaJsonLayout.json b/powertools-logging/src/main/resources/LambdaJsonLayout.json index dfc1fc78f..da3385032 100644 --- a/powertools-logging/src/main/resources/LambdaJsonLayout.json +++ b/powertools-logging/src/main/resources/LambdaJsonLayout.json @@ -1,6 +1,6 @@ { "timestamp": { - "$resolver": "timestamp" + "$resolver": "lambda-timestamp" }, "instant": { "epochSecond": { diff --git a/powertools-logging/src/test/java/org/apache/logging/log4j/core/layout/LambdaJsonLayoutTest.java b/powertools-logging/src/test/java/org/apache/logging/log4j/core/layout/LambdaJsonLayoutTest.java index 9b0c6165a..95fb9c47f 100644 --- a/powertools-logging/src/test/java/org/apache/logging/log4j/core/layout/LambdaJsonLayoutTest.java +++ b/powertools-logging/src/test/java/org/apache/logging/log4j/core/layout/LambdaJsonLayoutTest.java @@ -16,6 +16,7 @@ import static java.util.Collections.emptyMap; import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import static org.mockito.Mockito.when; @@ -32,8 +33,12 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.format.ResolverStyle; import java.util.Map; import org.apache.logging.log4j.Level; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -42,7 +47,6 @@ import software.amazon.lambda.powertools.logging.internal.LambdaLoggingAspect; class LambdaJsonLayoutTest { - private RequestHandler handler = new PowerLogToolEnabled(); @Mock @@ -73,6 +77,31 @@ void shouldLogInStructuredFormat() throws IOException { .containsKey("service")); } + @Test + void shouldLogWithRFC3339TimestampFormat_WhenLambdaLoggingIsJSON() throws Exception { + // Given: AWS_LAMBDA_LOG_FORMAT=JSON defined in pom.xml + + // When + handler.handleRequest("test", context); + + // Then + assertThat(Files.lines(Paths.get("target/logfile.json"))) + .hasSize(1) + .allSatisfy(line -> assertThat(parseToMap(line)) + .extracting("timestamp", as(InstanceOfAssertFactories.STRING)) + .satisfies(s -> assertThat(hasDateFormat(s, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")).isTrue())); + } + + private boolean hasDateFormat(String timestamp, String format) { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format).withResolverStyle(ResolverStyle.STRICT); + try { + dtf.parse(timestamp); + return true; + } catch (DateTimeParseException e) { + return false; + } + } + @Test void shouldModifyLogLevelBasedOnEnvVariable() throws IllegalAccessException, IOException, NoSuchMethodException, InvocationTargetException { From 877ab51c10e19db78a06ee703121ac749342d043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Van=20Der=20Linden?= <117538+jeromevdl@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:36:51 +0100 Subject: [PATCH 74/74] chore:Prep release 1.18.0 (#1515) * chore:prep release 1.18.0 * update version * update version in kotlin example * maven local repo in gradle example * update changelog --------- Co-authored-by: scottgerring --- CHANGELOG.md | 31 +++++++++++++++++++ README.md | 8 ++--- examples/pom.xml | 2 +- examples/powertools-examples-batch/pom.xml | 2 +- .../pom.xml | 2 +- .../powertools-examples-core/cdk/app/pom.xml | 2 +- .../cdk/infra/pom.xml | 2 +- .../gradle/build.gradle | 7 +++-- .../kotlin/build.gradle.kts | 6 ++-- examples/powertools-examples-core/sam/pom.xml | 2 +- .../serverless/pom.xml | 2 +- .../terraform/pom.xml | 2 +- .../powertools-examples-idempotency/pom.xml | 2 +- .../powertools-examples-parameters/pom.xml | 2 +- .../powertools-examples-serialization/pom.xml | 2 +- examples/powertools-examples-sqs/pom.xml | 2 +- .../powertools-examples-validation/pom.xml | 2 +- mkdocs.yml | 2 +- pom.xml | 2 +- powertools-batch/pom.xml | 2 +- powertools-cloudformation/pom.xml | 2 +- powertools-core/pom.xml | 2 +- powertools-e2e-tests/handlers/pom.xml | 2 +- powertools-e2e-tests/pom.xml | 2 +- powertools-idempotency/pom.xml | 2 +- powertools-large-messages/pom.xml | 2 +- powertools-logging/pom.xml | 2 +- powertools-metrics/pom.xml | 2 +- powertools-parameters/pom.xml | 2 +- powertools-serialization/pom.xml | 2 +- powertools-sqs/pom.xml | 2 +- powertools-test-suite/pom.xml | 2 +- powertools-tracing/pom.xml | 2 +- powertools-validation/pom.xml | 2 +- 34 files changed, 72 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbb90ce3f..4b9f664fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,37 @@ This project follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) fo ## [Unreleased] +## [1.18.0] - 2023-11-16 + +### Added + +* feat: add support for [Lambda Advanced Logging Controls (ALC)](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced) (#1514) by @jeromevdl +* feat: Add support for POWERTOOLS_LOGGER_LOG_EVENT (#1510) by @AlexeySoshin + +### Maintenance + +* fix: json schema 403 error (#1457) by @jeromevdl +* fix: array jmespath fail in idempotency module (#1420) by @jeromevdl +* chore: java21 support in our build (#1488) by @jeromevdl +* chore: Addition of Warn Message If Invalid Annotation Key While Tracing #1511 (#1512) by @jdoherty +* fix: null namespace should fallback to default namespace (#1506) by @jeromevdl +* fix: get trace id from system property when env var is not set (#1503) by @mriccia +* chore: artifacts size on good branches (#1493) by @jeromevdl +* fix: enforce jackson databind version (#1472) by @jeromevdl +* chore: add missing projects and improve workflow (#1487) by @jeromevdl +* chore: Reporting size of the jars in GitHub comments (#1196) by @jeromevdl +* Deps: Bump third party dependencies to the latest versions. + +### Documentation + +* docs(customer-reference): add Vertex Pharmaceuticals as a customer reference (#1486) by @scottgerring +* docs: Adding Kotlin example. (#1454) by @jasoniharris +* docs: Terraform example (#1478) by @skal111 +* docs: Add Serveless Framework example (#1363) by @AlexeySoshin +* docs: Fix link to SQS large message migration guide (#1422) by @scottgerring +* docs(logging): correct log example keys (#1411) by @walmsles +* docs: Update gradle configuration readme (#1359) by @scottgerring + ## [1.17.0] - 2023-08-21 ### Added diff --git a/README.md b/README.md index 900395554..63ba35cc6 100644 --- a/README.md +++ b/README.md @@ -20,17 +20,17 @@ Powertools for AWS Lambda (Java) is available in Maven Central. You can use your software.amazon.lambda powertools-tracing - 1.17.0 + 1.18.0 software.amazon.lambda powertools-logging - 1.17.0 + 1.18.0 software.amazon.lambda powertools-metrics - 1.17.0 + 1.18.0 ... @@ -190,7 +190,7 @@ Next, configure the aspectj-maven-plugin to compile-time weave (CTW) the aws-lam ## Examples -See the latest release of the **[examples](https://github.com/aws-powertools/powertools-lambda-java/tree/v1.17.0/examples)** for example projects showcasing usage of different utilities. +See the latest release of the **[examples](https://github.com/aws-powertools/powertools-lambda-java/tree/v1.18.0/examples)** for example projects showcasing usage of different utilities. Have a demo project to contribute which showcase usage of different utilities from powertools? We are happy to accept it [here](CONTRIBUTING.md#security-issue-notifications). diff --git a/examples/pom.xml b/examples/pom.xml index 900f095f8..428c74af8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -20,7 +20,7 @@ software.amazon.lambda powertools-examples - 1.18.0-SNAPSHOT + 1.18.0 pom Powertools for AWS Lambda (Java) library Examples diff --git a/examples/powertools-examples-batch/pom.xml b/examples/powertools-examples-batch/pom.xml index 99d3a97cc..af3655b9a 100644 --- a/examples/powertools-examples-batch/pom.xml +++ b/examples/powertools-examples-batch/pom.xml @@ -5,7 +5,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-batch jar Powertools for AWS Lambda (Java) library Examples - Batch diff --git a/examples/powertools-examples-cloudformation/pom.xml b/examples/powertools-examples-cloudformation/pom.xml index c195cd262..2df1ce9f6 100644 --- a/examples/powertools-examples-cloudformation/pom.xml +++ b/examples/powertools-examples-cloudformation/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-cloudformation jar diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index b4652bd65..9d9435ac3 100644 --- a/examples/powertools-examples-core/cdk/app/pom.xml +++ b/examples/powertools-examples-core/cdk/app/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.16.1 + 1.17.0 powertools-examples-core-cdk jar diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 216bf35d4..fd3cd313b 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -4,7 +4,7 @@ 4.0.0 software.amazon.lambda.examples cdk - 1.18.0-SNAPSHOT + 1.18.0 UTF-8 2.100.0 diff --git a/examples/powertools-examples-core/gradle/build.gradle b/examples/powertools-examples-core/gradle/build.gradle index 06aec59e8..0d6b0eee8 100644 --- a/examples/powertools-examples-core/gradle/build.gradle +++ b/examples/powertools-examples-core/gradle/build.gradle @@ -18,6 +18,7 @@ compileJava { } repositories { + mavenLocal() mavenCentral() } @@ -27,8 +28,8 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.0' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2' - aspect 'software.amazon.lambda:powertools-tracing:1.17.0' - aspect 'software.amazon.lambda:powertools-logging:1.17.0' - aspect 'software.amazon.lambda:powertools-metrics:1.17.0' + aspect 'software.amazon.lambda:powertools-tracing:1.18.0' + aspect 'software.amazon.lambda:powertools-logging:1.18.0' + aspect 'software.amazon.lambda:powertools-metrics:1.18.0' } diff --git a/examples/powertools-examples-core/kotlin/build.gradle.kts b/examples/powertools-examples-core/kotlin/build.gradle.kts index fc363c1b9..f95d1099d 100644 --- a/examples/powertools-examples-core/kotlin/build.gradle.kts +++ b/examples/powertools-examples-core/kotlin/build.gradle.kts @@ -14,9 +14,9 @@ dependencies { implementation("com.fasterxml.jackson.core:jackson-databind:2.13.2.2") implementation("com.amazonaws:aws-lambda-java-events:3.11.0") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2") - aspect("software.amazon.lambda:powertools-tracing:1.18.0-SNAPSHOT") - aspect("software.amazon.lambda:powertools-logging:1.18.0-SNAPSHOT") - aspect("software.amazon.lambda:powertools-metrics:1.18.0-SNAPSHOT") + aspect("software.amazon.lambda:powertools-tracing:1.18.0") + aspect("software.amazon.lambda:powertools-logging:1.18.0") + aspect("software.amazon.lambda:powertools-metrics:1.18.0") testImplementation("junit:junit:4.13.2") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") } diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index 997472344..adb5e13eb 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-core-sam jar diff --git a/examples/powertools-examples-core/serverless/pom.xml b/examples/powertools-examples-core/serverless/pom.xml index 6fce1d2dd..36c7e7280 100644 --- a/examples/powertools-examples-core/serverless/pom.xml +++ b/examples/powertools-examples-core/serverless/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-core-serverless jar diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 2a55c31bc..532675717 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -3,7 +3,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-core-terraform jar diff --git a/examples/powertools-examples-idempotency/pom.xml b/examples/powertools-examples-idempotency/pom.xml index 4b8eba9c9..5e79debf4 100644 --- a/examples/powertools-examples-idempotency/pom.xml +++ b/examples/powertools-examples-idempotency/pom.xml @@ -17,7 +17,7 @@ 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-idempotency jar Powertools for AWS Lambda (Java) library Examples - Idempotency diff --git a/examples/powertools-examples-parameters/pom.xml b/examples/powertools-examples-parameters/pom.xml index 0e07b0cbb..495d6c59c 100644 --- a/examples/powertools-examples-parameters/pom.xml +++ b/examples/powertools-examples-parameters/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-parameters jar Powertools for AWS Lambda (Java) library Examples - Parameters diff --git a/examples/powertools-examples-serialization/pom.xml b/examples/powertools-examples-serialization/pom.xml index 495fe8b77..e54c84315 100644 --- a/examples/powertools-examples-serialization/pom.xml +++ b/examples/powertools-examples-serialization/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-serialization jar Powertools for AWS Lambda (Java) library Examples - Serialization diff --git a/examples/powertools-examples-sqs/pom.xml b/examples/powertools-examples-sqs/pom.xml index 0338fe7d9..9d0b3f2a8 100644 --- a/examples/powertools-examples-sqs/pom.xml +++ b/examples/powertools-examples-sqs/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-sqs jar Powertools for AWS Lambda (Java) library Examples - SQS diff --git a/examples/powertools-examples-validation/pom.xml b/examples/powertools-examples-validation/pom.xml index 65628f6b2..3cb4264c0 100644 --- a/examples/powertools-examples-validation/pom.xml +++ b/examples/powertools-examples-validation/pom.xml @@ -16,7 +16,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 software.amazon.lambda.examples - 1.18.0-SNAPSHOT + 1.18.0 powertools-examples-validation jar Powertools for AWS Lambda (Java) library Examples - Validation diff --git a/mkdocs.yml b/mkdocs.yml index 0f9c065a7..a271c1260 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -88,7 +88,7 @@ extra_javascript: extra: powertools: - version: 1.17.0 # to update after each release (we do not want snapshot version here) + version: 1.18.0 # to update after each release (we do not want snapshot version here) repo_url: https://github.com/aws-powertools/powertools-lambda-java edit_uri: edit/main/docs diff --git a/pom.xml b/pom.xml index e1a0c5a6c..76b59d747 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ software.amazon.lambda powertools-parent - 1.18.0-SNAPSHOT + 1.18.0 pom Powertools for AWS Lambda (Java) library Parent diff --git a/powertools-batch/pom.xml b/powertools-batch/pom.xml index 0c59ce497..cedbcf317 100644 --- a/powertools-batch/pom.xml +++ b/powertools-batch/pom.xml @@ -6,7 +6,7 @@ software.amazon.lambda powertools-parent - 1.18.0-SNAPSHOT + 1.18.0 A suite of utilities that makes batch message processing using AWS Lambda easier. diff --git a/powertools-cloudformation/pom.xml b/powertools-cloudformation/pom.xml index f6cd822a6..660f6e34a 100644 --- a/powertools-cloudformation/pom.xml +++ b/powertools-cloudformation/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java)library Cloudformation diff --git a/powertools-core/pom.xml b/powertools-core/pom.xml index b848e9f79..0d82530a0 100644 --- a/powertools-core/pom.xml +++ b/powertools-core/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library Core diff --git a/powertools-e2e-tests/handlers/pom.xml b/powertools-e2e-tests/handlers/pom.xml index 6507e3104..995aeb1c7 100644 --- a/powertools-e2e-tests/handlers/pom.xml +++ b/powertools-e2e-tests/handlers/pom.xml @@ -10,7 +10,7 @@ Fake handlers that use Powertools for AWS Lambda (Java). - 1.18.0-SNAPSHOT + 1.18.0 UTF-8 1.8 1.8 diff --git a/powertools-e2e-tests/pom.xml b/powertools-e2e-tests/pom.xml index 84760eac8..d2aeaed66 100644 --- a/powertools-e2e-tests/pom.xml +++ b/powertools-e2e-tests/pom.xml @@ -20,7 +20,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 powertools-e2e-tests diff --git a/powertools-idempotency/pom.xml b/powertools-idempotency/pom.xml index 8b3459dee..fe85d74fd 100644 --- a/powertools-idempotency/pom.xml +++ b/powertools-idempotency/pom.xml @@ -21,7 +21,7 @@ software.amazon.lambda powertools-parent - 1.18.0-SNAPSHOT + 1.18.0 powertools-idempotency diff --git a/powertools-large-messages/pom.xml b/powertools-large-messages/pom.xml index 8fdae2139..2d5540c54 100644 --- a/powertools-large-messages/pom.xml +++ b/powertools-large-messages/pom.xml @@ -23,7 +23,7 @@ software.amazon.lambda powertools-parent - 1.18.0-SNAPSHOT + 1.18.0 powertools-large-messages diff --git a/powertools-logging/pom.xml b/powertools-logging/pom.xml index e4767893b..6fd4ce89f 100644 --- a/powertools-logging/pom.xml +++ b/powertools-logging/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library Logging diff --git a/powertools-metrics/pom.xml b/powertools-metrics/pom.xml index eff7296c8..677e18ed7 100644 --- a/powertools-metrics/pom.xml +++ b/powertools-metrics/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library Metrics diff --git a/powertools-parameters/pom.xml b/powertools-parameters/pom.xml index 808232ab1..0e86a0a06 100644 --- a/powertools-parameters/pom.xml +++ b/powertools-parameters/pom.xml @@ -21,7 +21,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 powertools-parameters diff --git a/powertools-serialization/pom.xml b/powertools-serialization/pom.xml index e5c4087fe..06b828923 100644 --- a/powertools-serialization/pom.xml +++ b/powertools-serialization/pom.xml @@ -21,7 +21,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 powertools-serialization diff --git a/powertools-sqs/pom.xml b/powertools-sqs/pom.xml index c4b2b54f0..e14ec59b5 100644 --- a/powertools-sqs/pom.xml +++ b/powertools-sqs/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library SQS diff --git a/powertools-test-suite/pom.xml b/powertools-test-suite/pom.xml index 34e80b06e..a6e84c4ac 100644 --- a/powertools-test-suite/pom.xml +++ b/powertools-test-suite/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library Test Suite diff --git a/powertools-tracing/pom.xml b/powertools-tracing/pom.xml index d98a97e2a..f16bedd2f 100644 --- a/powertools-tracing/pom.xml +++ b/powertools-tracing/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) library Tracing diff --git a/powertools-validation/pom.xml b/powertools-validation/pom.xml index 24de0ba2a..a372e4740 100644 --- a/powertools-validation/pom.xml +++ b/powertools-validation/pom.xml @@ -24,7 +24,7 @@ powertools-parent software.amazon.lambda - 1.18.0-SNAPSHOT + 1.18.0 Powertools for AWS Lambda (Java) validation library