From 27ad36a24ec87cf6f6b6ef5bd4e40d8be68593ab Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 27 Jul 2023 13:26:46 +0100 Subject: [PATCH 01/45] Move the current example, which is for SAM, under /sam directory --- examples/powertools-examples-core/{ => cdk}/.gitignore | 0 examples/powertools-examples-core/{ => cdk}/pom.xml | 0 .../{ => cdk}/src/main/java/helloworld/App.java | 0 .../{ => cdk}/src/main/java/helloworld/AppStream.java | 0 .../{ => cdk}/src/main/resources/log4j2.xml | 0 .../{ => cdk}/src/test/java/helloworld/AppTest.java | 0 examples/powertools-examples-core/{ => sam}/README.md | 2 +- examples/powertools-examples-core/{ => sam}/events/event.json | 0 examples/powertools-examples-core/{ => sam}/template.yaml | 0 9 files changed, 1 insertion(+), 1 deletion(-) rename examples/powertools-examples-core/{ => cdk}/.gitignore (100%) rename examples/powertools-examples-core/{ => cdk}/pom.xml (100%) rename examples/powertools-examples-core/{ => cdk}/src/main/java/helloworld/App.java (100%) rename examples/powertools-examples-core/{ => cdk}/src/main/java/helloworld/AppStream.java (100%) rename examples/powertools-examples-core/{ => cdk}/src/main/resources/log4j2.xml (100%) rename examples/powertools-examples-core/{ => cdk}/src/test/java/helloworld/AppTest.java (100%) rename examples/powertools-examples-core/{ => sam}/README.md (96%) rename examples/powertools-examples-core/{ => sam}/events/event.json (100%) rename examples/powertools-examples-core/{ => sam}/template.yaml (100%) diff --git a/examples/powertools-examples-core/.gitignore b/examples/powertools-examples-core/cdk/.gitignore similarity index 100% rename from examples/powertools-examples-core/.gitignore rename to examples/powertools-examples-core/cdk/.gitignore diff --git a/examples/powertools-examples-core/pom.xml b/examples/powertools-examples-core/cdk/pom.xml similarity index 100% rename from examples/powertools-examples-core/pom.xml rename to examples/powertools-examples-core/cdk/pom.xml diff --git a/examples/powertools-examples-core/src/main/java/helloworld/App.java b/examples/powertools-examples-core/cdk/src/main/java/helloworld/App.java similarity index 100% rename from examples/powertools-examples-core/src/main/java/helloworld/App.java rename to examples/powertools-examples-core/cdk/src/main/java/helloworld/App.java diff --git a/examples/powertools-examples-core/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/cdk/src/main/java/helloworld/AppStream.java similarity index 100% rename from examples/powertools-examples-core/src/main/java/helloworld/AppStream.java rename to examples/powertools-examples-core/cdk/src/main/java/helloworld/AppStream.java diff --git a/examples/powertools-examples-core/src/main/resources/log4j2.xml b/examples/powertools-examples-core/cdk/src/main/resources/log4j2.xml similarity index 100% rename from examples/powertools-examples-core/src/main/resources/log4j2.xml rename to examples/powertools-examples-core/cdk/src/main/resources/log4j2.xml diff --git a/examples/powertools-examples-core/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/cdk/src/test/java/helloworld/AppTest.java similarity index 100% rename from examples/powertools-examples-core/src/test/java/helloworld/AppTest.java rename to examples/powertools-examples-core/cdk/src/test/java/helloworld/AppTest.java diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/sam/README.md similarity index 96% rename from examples/powertools-examples-core/README.md rename to examples/powertools-examples-core/sam/README.md index a47d0d26c..404413e07 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/sam/README.md @@ -15,7 +15,7 @@ It is made up of the following: ## Deploy the sample application This sample is based on Serverless Application Model (SAM). To deploy it, check out the instructions for getting -started with SAM in [the examples directory](../README.md) +started with SAM in [the examples directory](../../README.md) ## Test the application diff --git a/examples/powertools-examples-core/events/event.json b/examples/powertools-examples-core/sam/events/event.json similarity index 100% rename from examples/powertools-examples-core/events/event.json rename to examples/powertools-examples-core/sam/events/event.json diff --git a/examples/powertools-examples-core/template.yaml b/examples/powertools-examples-core/sam/template.yaml similarity index 100% rename from examples/powertools-examples-core/template.yaml rename to examples/powertools-examples-core/sam/template.yaml From 1b4982cd5d0610e969a7f05b0088c1d3dbab6137 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 27 Jul 2023 13:27:28 +0100 Subject: [PATCH 02/45] Create a new directory for CDK --- .../powertools-examples-core/cdk/README.md | 47 ++++ .../powertools-examples-core/sam/.gitignore | 0 examples/powertools-examples-core/sam/pom.xml | 201 ++++++++++++++++++ .../sam/src/main/java/helloworld/App.java | 131 ++++++++++++ .../src/main/java/helloworld/AppStream.java | 38 ++++ .../sam/src/main/resources/log4j2.xml | 16 ++ .../sam/src/test/java/helloworld/AppTest.java | 59 +++++ 7 files changed, 492 insertions(+) create mode 100644 examples/powertools-examples-core/cdk/README.md create mode 100644 examples/powertools-examples-core/sam/.gitignore create mode 100644 examples/powertools-examples-core/sam/pom.xml create mode 100644 examples/powertools-examples-core/sam/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/sam/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/sam/src/main/resources/log4j2.xml create mode 100644 examples/powertools-examples-core/sam/src/test/java/helloworld/AppTest.java diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md new file mode 100644 index 000000000..404413e07 --- /dev/null +++ b/examples/powertools-examples-core/cdk/README.md @@ -0,0 +1,47 @@ +# 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/). + +It is made up of the following: + +- [App.java](src/main/java/helloworld/App.java) - Code for the application's Lambda function. +- [events](events) - Invocation events that you can use to invoke the function. +- [AppTests.java](src/test/java/helloworld/AppTest.java) - Unit tests for the application code. +- [template.yaml](template.yaml) - A template that defines the application's AWS resources. + +## Deploy the sample application + +This sample is based on Serverless Application Model (SAM). To deploy it, check out the instructions for getting +started with SAM in [the examples directory](../../README.md) + +## Test the application + +Once the app is deployed, you can invoke the endpoint like this: + +```bash + 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 +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 + +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](src/main/java/helloworld/App.java). + +You can also 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/sam/.gitignore b/examples/powertools-examples-core/sam/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml new file mode 100644 index 000000000..a5d854d6b --- /dev/null +++ b/examples/powertools-examples-core/sam/pom.xml @@ -0,0 +1,201 @@ + + 4.0.0 + + software.amazon.lambda.examples + 1.17.0-SNAPSHOT + powertools-examples-core + jar + + Powertools for AWS Lambda (Java) library Examples - Core + + + 2.20.0 + 1.8 + 1.8 + true + + + + + 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 + + + + + + + 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 + + + + + + + + + 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/sam/src/main/java/helloworld/App.java b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java new file mode 100644 index 000000000..94360cf59 --- /dev/null +++ b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java @@ -0,0 +1,131 @@ +/* + * 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 static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment; + +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.AWSXRay; +import com.amazonaws.xray.entities.Entity; +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); + }); + + threadOption1(); + + threadOption2(); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (IOException | InterruptedException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + private void threadOption1() throws InterruptedException { + final Entity traceEntity = AWSXRay.getTraceEntity(); + assert traceEntity != null; + traceEntity.run(new Thread(this::log)); + } + + private void threadOption2() throws InterruptedException { + Entity traceEntity = AWSXRay.getTraceEntity(); + Thread anotherThread = new Thread(() -> withEntitySubsegment("inlineLog", traceEntity, subsegment -> + { + String var = "somethingToProcess"; + log.info("inside threaded logging inline {}", var); + })); + anotherThread.start(); + anotherThread.join(); + } + + @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/sam/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/sam/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/sam/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/sam/src/main/resources/log4j2.xml b/examples/powertools-examples-core/sam/src/main/resources/log4j2.xml new file mode 100644 index 000000000..e1fd14cea --- /dev/null +++ b/examples/powertools-examples-core/sam/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..70dad8d71 --- /dev/null +++ b/examples/powertools-examples-core/sam/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 537124ac57d9daa54a5b83c02217205c7244ff64 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 27 Jul 2023 13:32:50 +0100 Subject: [PATCH 03/45] Add CDK Example as a Maven module --- examples/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/pom.xml b/examples/pom.xml index 72f1dc03b..1731d263d 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -29,7 +29,8 @@ - powertools-examples-core + powertools-examples-core/sam + powertools-examples-core/cdk powertools-examples-idempotency powertools-examples-parameters powertools-examples-serialization From c9159925830902586b83638d38b8acb270089118 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 27 Jul 2023 14:46:47 +0100 Subject: [PATCH 04/45] CDK Stack stub --- .../powertools-examples-core/cdk/.gitignore | 13 ++ .../powertools-examples-core/cdk/README.md | 23 ++- .../powertools-examples-core/cdk/cdk.json | 53 ++++++ examples/powertools-examples-core/cdk/pom.xml | 177 ++++++++++-------- .../cdk/src/main/java/cdk/CdkApp.java | 40 ++++ .../cdk/src/main/java/cdk/CdkStack.java | 25 +++ .../cdk/src/test/java/helloworld/AppTest.java | 20 +- 7 files changed, 264 insertions(+), 87 deletions(-) create mode 100644 examples/powertools-examples-core/cdk/cdk.json create mode 100644 examples/powertools-examples-core/cdk/src/main/java/cdk/CdkApp.java create mode 100644 examples/powertools-examples-core/cdk/src/main/java/cdk/CdkStack.java diff --git a/examples/powertools-examples-core/cdk/.gitignore b/examples/powertools-examples-core/cdk/.gitignore index e69de29bb..1db21f162 100644 --- a/examples/powertools-examples-core/cdk/.gitignore +++ b/examples/powertools-examples-core/cdk/.gitignore @@ -0,0 +1,13 @@ +.classpath.txt +target +.classpath +.project +.idea +.settings +.vscode +*.iml + +# CDK asset staging directory +.cdk.staging +cdk.out + diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index 404413e07..3c9a27e65 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -10,12 +10,29 @@ It is made up of the following: - [App.java](src/main/java/helloworld/App.java) - Code for the application's Lambda function. - [events](events) - Invocation events that you can use to invoke the function. - [AppTests.java](src/test/java/helloworld/AppTest.java) - Unit tests for the application code. -- [template.yaml](template.yaml) - A template that defines the application's AWS resources. ## Deploy the sample application -This sample is based on Serverless Application Model (SAM). To deploy it, check out the instructions for getting -started with SAM in [the examples directory](../../README.md) +This is a blank project for CDK development with Java. + +The `cdk.json` file tells the CDK Toolkit how to execute your app. + +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. + +The minimum to deploy the app should be +```bash +cdk bootstrap && mvn package && cdk deploy +``` + +## Useful commands + +* `mvn package` compile and run tests +* `cdk ls` list all stacks in the app +* `cdk synth` emits the synthesized CloudFormation template +* `cdk deploy` deploy this stack to your default AWS account/region +* `cdk diff` compare deployed stack with current state +* `cdk docs` open CDK documentation + ## Test the application diff --git a/examples/powertools-examples-core/cdk/cdk.json b/examples/powertools-examples-core/cdk/cdk.json new file mode 100644 index 000000000..6bd0271fd --- /dev/null +++ b/examples/powertools-examples-core/cdk/cdk.json @@ -0,0 +1,53 @@ +{ + "app": "mvn -e -q compile exec:java", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "target", + "pom.xml", + "src/test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-iam:standardizedServicePrincipals": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true + } +} diff --git a/examples/powertools-examples-core/cdk/pom.xml b/examples/powertools-examples-core/cdk/pom.xml index a5d854d6b..731e713c5 100644 --- a/examples/powertools-examples-core/cdk/pom.xml +++ b/examples/powertools-examples-core/cdk/pom.xml @@ -1,12 +1,12 @@ + 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-SNAPSHOT powertools-examples-core jar - + Powertools for AWS Lambda (Java) library Examples - Core @@ -14,23 +14,45 @@ 1.8 1.8 true + UTF-8 + 2.88.0 + [10.0.0,11.0.0) + 5.7.1 - + + + software.amazon.awscdk + aws-cdk-lib + ${cdk.version} + + + + software.constructs + constructs + ${constructs.version} + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + software.amazon.lambda powertools-tracing - ${project.version} + 1.16.1 software.amazon.lambda powertools-logging - ${project.version} + 1.16.1 software.amazon.lambda powertools-metrics - ${project.version} + 1.16.1 com.amazonaws @@ -38,9 +60,9 @@ 1.2.2 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -52,76 +74,83 @@ log4j-api ${log4j.version} - - junit - junit - 4.13.2 - test + org.junit.jupiter + junit-jupiter + ${junit.version} + 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 - - - - - - - - - - - - com.github.edwgiz - maven-shade-plugin.log4j2-cachefile-transformer - 2.15 - - - - + + + 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.codehaus.mojo + exec-maven-plugin + 3.0.0 + + cdk.CdkApp + + + - - software.amazon.awscdk - aws-cdk-lib - ${cdk.version} - - - software.constructs - constructs - ${constructs.version} - - - - org.junit.jupiter - junit-jupiter - ${junit.version} - test - + software.amazon.lambda powertools-tracing - 1.16.1 + ${project.version} software.amazon.lambda powertools-logging - 1.16.1 + ${project.version} software.amazon.lambda powertools-metrics - 1.16.1 + ${project.version} com.amazonaws @@ -60,9 +38,9 @@ 1.2.2 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -74,83 +52,76 @@ log4j-api ${log4j.version} + - org.junit.jupiter - junit-jupiter - ${junit.version} - 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 - - - - - - - - - - - - com.github.edwgiz - maven-shade-plugin.log4j2-cachefile-transformer - 2.15 - - - - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - cdk.CdkApp - - - + + + 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 + + + + + + software.amazon.awscdk + aws-cdk-lib + ${cdk.version} + + + software.constructs + constructs + ${constructs.version} + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + diff --git a/examples/powertools-examples-core/cdk/src/main/java/cdk/CdkApp.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java similarity index 100% rename from examples/powertools-examples-core/cdk/src/main/java/cdk/CdkApp.java rename to examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java new file mode 100644 index 000000000..0a0507a7f --- /dev/null +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -0,0 +1,44 @@ +package cdk; + + +import software.amazon.awscdk.services.lambda.Code; +import software.amazon.awscdk.services.lambda.Function; +import software.constructs.Construct; +import software.amazon.awscdk.Stack; +import software.amazon.awscdk.StackProps; +// import software.amazon.awscdk.Duration; +// import software.amazon.awscdk.services.sqs.Queue; +import software.amazon.awscdk.App; +import software.amazon.awscdk.BundlingOptions; +import software.amazon.awscdk.CfnOutput; +import software.amazon.awscdk.CfnOutputProps; +import software.constructs.Construct; +import software.amazon.awscdk.DockerVolume; +import software.amazon.awscdk.Duration; +import software.amazon.awscdk.Stack; +import software.amazon.awscdk.StackProps; +import software.amazon.awscdk.services.lambda.Code; +import software.amazon.awscdk.services.lambda.Function; +import software.amazon.awscdk.services.lambda.FunctionProps; +import software.amazon.awscdk.services.lambda.Runtime; +import software.amazon.awscdk.services.logs.RetentionDays; +import software.amazon.awscdk.services.s3.assets.AssetOptions; + +public class CdkStack extends Stack { + public CdkStack(final Construct scope, final String id) { + this(scope, id, null); + } + + public CdkStack(final Construct scope, final String id, final StackProps props) { + super(scope, id, props); + + // The code that defines your stack goes here + + final Function hello = Function.Builder.create(this, "HelloWorldFunction") + .runtime(Runtime.JAVA_11) // execution environment + .code(Code.fromAsset("../helloworld/", AssetOptions.builder() + .build())) // code loaded from the "lambda" directory + .handler("helloworld.App::handleRequest") // file is "hello", function is "handler" + .build(); + } +} diff --git a/examples/powertools-examples-core/cdk/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/src/main/java/cdk/CdkStack.java deleted file mode 100644 index de6081e69..000000000 --- a/examples/powertools-examples-core/cdk/src/main/java/cdk/CdkStack.java +++ /dev/null @@ -1,25 +0,0 @@ -package cdk; - - -import software.constructs.Construct; -import software.amazon.awscdk.Stack; -import software.amazon.awscdk.StackProps; -// import software.amazon.awscdk.Duration; -// import software.amazon.awscdk.services.sqs.Queue; - -public class CdkStack extends Stack { - public CdkStack(final Construct scope, final String id) { - this(scope, id, null); - } - - public CdkStack(final Construct scope, final String id, final StackProps props) { - super(scope, id, props); - - // The code that defines your stack goes here - - // example resource - // final Queue queue = Queue.Builder.create(this, "TestQueue") - // .visibilityTimeout(Duration.seconds(300)) - // .build(); - } -} diff --git a/examples/powertools-examples-core/sam/pom.xml b/examples/powertools-examples-core/sam/pom.xml index a5d854d6b..bc3667b4f 100644 --- a/examples/powertools-examples-core/sam/pom.xml +++ b/examples/powertools-examples-core/sam/pom.xml @@ -4,7 +4,7 @@ software.amazon.lambda.examples 1.17.0-SNAPSHOT - powertools-examples-core + powertools-examples-core-sam jar Powertools for AWS Lambda (Java) library Examples - Core From db09638185988a0abd8175c2acd9eaf78156e02c Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Mon, 31 Jul 2023 14:32:09 +0100 Subject: [PATCH 06/45] Define the build of the project inside the CDK stack --- .../powertools-examples-core/cdk/README.md | 2 +- .../powertools-examples-core/cdk/app/pom.xml | 2 +- .../cdk/infra/pom.xml | 2 +- .../cdk/infra/src/main/java/cdk/CdkStack.java | 53 ++++++++++++------- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index 3c9a27e65..fdbe6fae0 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -21,7 +21,7 @@ It is a [Maven](https://maven.apache.org/) based project, so you can open this p The minimum to deploy the app should be ```bash -cdk bootstrap && mvn package && cdk deploy +cdk bootstrap && cdk deploy ``` ## Useful commands diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index 90ffca588..a24d9d9d9 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.17.0-SNAPSHOT + 1.16.1 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 03e71c333..6431de073 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -27,7 +27,7 @@ exec-maven-plugin 3.0.0 - com.myorg.InfraApp + cdk.CdkApp diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 0a0507a7f..758764e41 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -1,28 +1,21 @@ package cdk; -import software.amazon.awscdk.services.lambda.Code; -import software.amazon.awscdk.services.lambda.Function; -import software.constructs.Construct; -import software.amazon.awscdk.Stack; -import software.amazon.awscdk.StackProps; -// import software.amazon.awscdk.Duration; -// import software.amazon.awscdk.services.sqs.Queue; -import software.amazon.awscdk.App; import software.amazon.awscdk.BundlingOptions; -import software.amazon.awscdk.CfnOutput; -import software.amazon.awscdk.CfnOutputProps; -import software.constructs.Construct; -import software.amazon.awscdk.DockerVolume; import software.amazon.awscdk.Duration; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; +import software.amazon.awscdk.services.apigateway.LambdaIntegration; +import software.amazon.awscdk.services.apigateway.RestApi; import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; -import software.amazon.awscdk.services.lambda.FunctionProps; import software.amazon.awscdk.services.lambda.Runtime; -import software.amazon.awscdk.services.logs.RetentionDays; +import software.amazon.awscdk.services.lambda.Tracing; import software.amazon.awscdk.services.s3.assets.AssetOptions; +import software.constructs.Construct; + +import java.util.Arrays; +import java.util.List; public class CdkStack extends Stack { public CdkStack(final Construct scope, final String id) { @@ -34,11 +27,35 @@ public CdkStack(final Construct scope, final String id, final StackProps props) // The code that defines your stack goes here - final Function hello = Function.Builder.create(this, "HelloWorldFunction") + // CDK will use this command to package your Java Lambda + List functionPackageInstructions = Arrays.asList( + "/bin/sh", + "-c", + "mvn package " + + "&& cp /asset-input/target/powertools-examples-core-cdk-1.16.1.jar /asset-output/" + ); + + final Function helloWorldFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.JAVA_11) // execution environment - .code(Code.fromAsset("../helloworld/", AssetOptions.builder() - .build())) // code loaded from the "lambda" directory - .handler("helloworld.App::handleRequest") // file is "hello", function is "handler" + .memorySize(512) + .timeout(Duration.seconds(20)) + .tracing(Tracing.ACTIVE) + .code(Code.fromAsset("../app/", AssetOptions.builder() + .bundling(BundlingOptions.builder() + .image(Runtime.JAVA_11.getBundlingImage()) + .command(functionPackageInstructions) + .build()) + .build())) + .handler("helloworld.App") + .build(); + + RestApi reastApi = RestApi.Builder.create(this, "HelloWorldApi") + .description("API Gateway endpoint URL for Prod stage for Hello World function") .build(); + + reastApi.getRoot().resourceForPath("/hello") + .addMethod("GET", LambdaIntegration.Builder.create(helloWorldFunction) + .build()); + } } From 3e7091beab0010421282ba12c1dae2fbfb24803f Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Mon, 31 Jul 2023 14:37:06 +0100 Subject: [PATCH 07/45] Use default account and region --- .../cdk/infra/src/main/java/cdk/CdkApp.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java index 67c3ce09d..b742c4ec8 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkApp.java @@ -27,10 +27,12 @@ public static void main(final String[] args) { // Uncomment the next block if you know exactly what Account and Region you // want to deploy the stack to. + /* .env(Environment.builder() - .account("965995096314") - .region("eu-west-2") + .account("1234567890") + .region("region") .build()) + */ // For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html .build()); From 7b7aef77b250db9532dcccb50e164d66b0ca6466 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Mon, 31 Jul 2023 15:13:48 +0100 Subject: [PATCH 08/45] Add example of setting environment variables in CDK --- .../cdk/infra/src/main/java/cdk/CdkStack.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 758764e41..62b5506ea 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -15,7 +15,9 @@ import software.constructs.Construct; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class CdkStack extends Stack { public CdkStack(final Construct scope, final String id) { @@ -47,6 +49,12 @@ public CdkStack(final Construct scope, final String id, final StackProps props) .build()) .build())) .handler("helloworld.App") + .environment(new HashMap() {{ + put("POWERTOOLS_LOG_LEVEL", "0.1"); + put("POWERTOOLS_LOGGER_SAMPLE_RATE", "INFO"); + put("POWERTOOLS_LOGGER_LOG_EVENT", "true"); + put("POWERTOOLS_METRICS_NAMESPACE", "Coreutilities"); + }}) .build(); RestApi reastApi = RestApi.Builder.create(this, "HelloWorldApi") From 5fae08d7eed448999177b1bf35319a343b213359 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 11:51:25 +0100 Subject: [PATCH 09/45] Remove threads from the examples, as this should be covered by documentation --- .../cdk/app/src/main/java/helloworld/App.java | 67 ++++++------------- .../sam/src/main/java/helloworld/App.java | 67 ++++++------------- 2 files changed, 44 insertions(+), 90 deletions(-) diff --git a/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java b/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java index 94360cf59..9a679d338 100644 --- a/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java @@ -14,24 +14,10 @@ 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 static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment; - 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.AWSXRay; -import com.amazonaws.xray.entities.Entity; -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; @@ -43,6 +29,18 @@ 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.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +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; + /** * Handler for requests to Lambda function. */ @@ -61,10 +59,10 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv 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")); - }); + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); LoggingUtils.appendKey("test", "willBeLogged"); @@ -77,44 +75,23 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv 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); - }); - - threadOption1(); - - threadOption2(); + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); log.info("After output"); return response .withStatusCode(200) .withBody(output); - } catch (IOException | InterruptedException e) { + } catch (RuntimeException | IOException e) { return response .withBody("{}") .withStatusCode(500); } } - private void threadOption1() throws InterruptedException { - final Entity traceEntity = AWSXRay.getTraceEntity(); - assert traceEntity != null; - traceEntity.run(new Thread(this::log)); - } - - private void threadOption2() throws InterruptedException { - Entity traceEntity = AWSXRay.getTraceEntity(); - Thread anotherThread = new Thread(() -> withEntitySubsegment("inlineLog", traceEntity, subsegment -> - { - String var = "somethingToProcess"; - log.info("inside threaded logging inline {}", var); - })); - anotherThread.start(); - anotherThread.join(); - } - @Tracing private void log() { log.info("inside threaded logging for function"); diff --git a/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java index 94360cf59..9a679d338 100644 --- a/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java @@ -14,24 +14,10 @@ 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 static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment; - 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.AWSXRay; -import com.amazonaws.xray.entities.Entity; -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; @@ -43,6 +29,18 @@ 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.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +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; + /** * Handler for requests to Lambda function. */ @@ -61,10 +59,10 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv 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")); - }); + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); LoggingUtils.appendKey("test", "willBeLogged"); @@ -77,44 +75,23 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv 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); - }); - - threadOption1(); - - threadOption2(); + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); log.info("After output"); return response .withStatusCode(200) .withBody(output); - } catch (IOException | InterruptedException e) { + } catch (RuntimeException | IOException e) { return response .withBody("{}") .withStatusCode(500); } } - private void threadOption1() throws InterruptedException { - final Entity traceEntity = AWSXRay.getTraceEntity(); - assert traceEntity != null; - traceEntity.run(new Thread(this::log)); - } - - private void threadOption2() throws InterruptedException { - Entity traceEntity = AWSXRay.getTraceEntity(); - Thread anotherThread = new Thread(() -> withEntitySubsegment("inlineLog", traceEntity, subsegment -> - { - String var = "somethingToProcess"; - log.info("inside threaded logging inline {}", var); - })); - anotherThread.start(); - anotherThread.join(); - } - @Tracing private void log() { log.info("inside threaded logging for function"); From 3ef58f7444af36277761f5cb5b474c02c8f3cd39 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 15:45:24 +0100 Subject: [PATCH 10/45] Add general README for the project --- examples/powertools-examples-core/README.md | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/powertools-examples-core/README.md diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md new file mode 100644 index 000000000..db3a624f6 --- /dev/null +++ b/examples/powertools-examples-core/README.md @@ -0,0 +1,38 @@ +# 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 architectures: +* [SAM](sam/) +* [CDK](cdk/) + +For all the architectures, 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. +- [AppTests.java](sam/src/test/java/helloworld/AppTest.java) - Unit tests for the application code. +- [events](events) - Invocation events that you can use to invoke the function. + +Configuration files and deployment process for each architecture are described in corresponding README files. + +## Test the application + +Once the app is deployed, you can invoke the endpoint like this: + +```bash + 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 +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 + +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). From 7c0278f2ab3f4e643e6a1b438f42c4fcc75d88f2 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 15:45:33 +0100 Subject: [PATCH 11/45] Add specific README for SAM --- .../powertools-examples-core/sam/README.md | 41 ++++--------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/examples/powertools-examples-core/sam/README.md b/examples/powertools-examples-core/sam/README.md index 404413e07..fa1c455c7 100644 --- a/examples/powertools-examples-core/sam/README.md +++ b/examples/powertools-examples-core/sam/README.md @@ -1,43 +1,20 @@ -# Powertools for AWS Lambda (Java) - Core Utilities Example +# Powertools for AWS Lambda (Java) - Core Utilities Example with SAM -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/). +This project demonstrates the Lambda for Powertools Java module deployed using [Serverless Application Model](https://aws.amazon.com/serverless/sam/). -It is made up of the following: +For general information on project structure similar to all architectures, you can refer to the parent [README](../README.md) -- [App.java](src/main/java/helloworld/App.java) - Code for the application's Lambda function. -- [events](events) - Invocation events that you can use to invoke the function. -- [AppTests.java](src/test/java/helloworld/AppTest.java) - Unit tests for the application code. -- [template.yaml](template.yaml) - A template that defines the application's AWS resources. +## 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. ## Deploy the sample application - -This sample is based on Serverless Application Model (SAM). To deploy it, check out the instructions for getting +To deploy the example, check out the instructions for getting started with SAM in [the examples directory](../../README.md) -## Test the application - -Once the app is deployed, you can invoke the endpoint like this: - -```bash - 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 -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 - -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](src/main/java/helloworld/App.java). +## Additional notes -You can also watch the trace information or log information using the SAM CLI: +You can watch the trace information or log information using the SAM CLI: ```bash # Tail the logs sam logs --tail $MY_STACK From ff16cb57ac3aede5461804e15c802660d48be0a0 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 15:52:01 +0100 Subject: [PATCH 12/45] Add specific README for CDK --- .../powertools-examples-core/cdk/README.md | 60 +++++-------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index fdbe6fae0..7abebe515 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -1,23 +1,23 @@ -# Powertools for AWS Lambda (Java) - Core Utilities Example +# Powertools for AWS Lambda (Java) - Core Utilities Example with CDK -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/). +This project demonstrates the Lambda for Powertools Java module deployed using [Cloud Development Kit](https://aws.amazon.com/cdk/). -It is made up of the following: +For general information on project structure similar to all architectures, you can refer to the parent [README](../README.md) -- [App.java](src/main/java/helloworld/App.java) - Code for the application's Lambda function. -- [events](events) - Invocation events that you can use to invoke the function. -- [AppTests.java](src/test/java/helloworld/AppTest.java) - Unit tests for the application code. +## 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 + - [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. -## Deploy the sample application - -This is a blank project for CDK development with Java. +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. -The `cdk.json` file tells the CDK Toolkit how to execute your app. -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 example, check out the instructions for getting +started with SAM in [the examples directory](../../README.md) The minimum to deploy the app should be ```bash @@ -31,34 +31,4 @@ cdk bootstrap && cdk deploy * `cdk synth` emits the synthesized CloudFormation template * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state -* `cdk docs` open CDK documentation - - -## Test the application - -Once the app is deployed, you can invoke the endpoint like this: - -```bash - 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 -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 - -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](src/main/java/helloworld/App.java). - -You can also 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 +* `cdk docs` open CDK documentation \ No newline at end of file From eeeaa6dc0b3969cd14a6cc518a8f6a31b261ec3f Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 16:56:41 +0100 Subject: [PATCH 13/45] Use Java11 syntax for CDK --- .../cdk/infra/pom.xml | 4 ++-- .../cdk/infra/src/main/java/cdk/CdkStack.java | 22 ++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/pom.xml b/examples/powertools-examples-core/cdk/infra/pom.xml index 6431de073..20c155180 100644 --- a/examples/powertools-examples-core/cdk/infra/pom.xml +++ b/examples/powertools-examples-core/cdk/infra/pom.xml @@ -18,8 +18,8 @@ maven-compiler-plugin 3.8.1 - 1.8 - 1.8 + 11 + 11 diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 62b5506ea..4b401161e 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -14,8 +14,6 @@ import software.amazon.awscdk.services.s3.assets.AssetOptions; import software.constructs.Construct; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,7 +28,7 @@ public CdkStack(final Construct scope, final String id, final StackProps props) // The code that defines your stack goes here // CDK will use this command to package your Java Lambda - List functionPackageInstructions = Arrays.asList( + var functionPackageInstructions = List.of( "/bin/sh", "-c", "mvn package " + @@ -44,26 +42,24 @@ public CdkStack(final Construct scope, final String id, final StackProps props) .tracing(Tracing.ACTIVE) .code(Code.fromAsset("../app/", AssetOptions.builder() .bundling(BundlingOptions.builder() - .image(Runtime.JAVA_11.getBundlingImage()) + .image(Runtime.JAVA_11.getBundlingImage()) // Build image environment .command(functionPackageInstructions) .build()) .build())) .handler("helloworld.App") - .environment(new HashMap() {{ - put("POWERTOOLS_LOG_LEVEL", "0.1"); - put("POWERTOOLS_LOGGER_SAMPLE_RATE", "INFO"); - put("POWERTOOLS_LOGGER_LOG_EVENT", "true"); - put("POWERTOOLS_METRICS_NAMESPACE", "Coreutilities"); - }}) + .environment(Map.of("POWERTOOLS_LOG_LEVEL", "0.1", + "POWERTOOLS_LOGGER_SAMPLE_RATE", "INFO", + "POWERTOOLS_LOGGER_LOG_EVENT", "true", + "POWERTOOLS_METRICS_NAMESPACE", "Coreutilities" + )) .build(); - RestApi reastApi = RestApi.Builder.create(this, "HelloWorldApi") + RestApi restApi = RestApi.Builder.create(this, "HelloWorldApi") .description("API Gateway endpoint URL for Prod stage for Hello World function") .build(); - reastApi.getRoot().resourceForPath("/hello") + restApi.getRoot().resourceForPath("/hello") .addMethod("GET", LambdaIntegration.Builder.create(helloWorldFunction) .build()); - } } From 866a50d491d8b34e999ea61f135ef9cc13e54c3f Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 17:19:50 +0100 Subject: [PATCH 14/45] Refactor the code for clarity --- .../cdk/infra/src/main/java/cdk/CdkStack.java | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 4b401161e..25bb0c76a 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -1,6 +1,5 @@ package cdk; - import software.amazon.awscdk.BundlingOptions; import software.amazon.awscdk.Duration; import software.amazon.awscdk.Stack; @@ -17,7 +16,14 @@ import java.util.List; import java.util.Map; +/** + * Defines a stack that consists of a single Java Lambda function and an API Gateway + */ public class CdkStack extends Stack { + private static final String SHELL_COMMAND = "/bin/sh"; + private static final String MAVEN_PACKAGE = "mvn package"; + private static final String COPY_OUTPUT = "cp /asset-input/target/powertools-examples-core-cdk-1.16.1.jar /asset-output/"; + public CdkStack(final Construct scope, final String id) { this(scope, id, null); } @@ -25,24 +31,26 @@ public CdkStack(final Construct scope, final String id) { public CdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); - // The code that defines your stack goes here + Function helloWorldFunction = createHelloWorldFunction(); + RestApi restApi = createHelloWorldApi(); - // CDK will use this command to package your Java Lambda - var functionPackageInstructions = List.of( - "/bin/sh", - "-c", - "mvn package " + - "&& cp /asset-input/target/powertools-examples-core-cdk-1.16.1.jar /asset-output/" - ); + restApi.getRoot().resourceForPath("/hello") + .addMethod("GET", LambdaIntegration.Builder.create(helloWorldFunction) + .build()); + } - final Function helloWorldFunction = Function.Builder.create(this, "HelloWorldFunction") - .runtime(Runtime.JAVA_11) // execution environment + // Method to create the Lambda function + private Function createHelloWorldFunction() { + List functionPackageInstructions = createFunctionPackageInstructions(); + + return Function.Builder.create(this, "HelloWorldFunction") + .runtime(Runtime.JAVA_11) .memorySize(512) .timeout(Duration.seconds(20)) .tracing(Tracing.ACTIVE) .code(Code.fromAsset("../app/", AssetOptions.builder() .bundling(BundlingOptions.builder() - .image(Runtime.JAVA_11.getBundlingImage()) // Build image environment + .image(Runtime.JAVA_11.getBundlingImage()) .command(functionPackageInstructions) .build()) .build())) @@ -53,13 +61,22 @@ public CdkStack(final Construct scope, final String id, final StackProps props) "POWERTOOLS_METRICS_NAMESPACE", "Coreutilities" )) .build(); + } - RestApi restApi = RestApi.Builder.create(this, "HelloWorldApi") + // Method to create the REST API + private RestApi createHelloWorldApi() { + return RestApi.Builder.create(this, "HelloWorldApi") .description("API Gateway endpoint URL for Prod stage for Hello World function") .build(); + } - restApi.getRoot().resourceForPath("/hello") - .addMethod("GET", LambdaIntegration.Builder.create(helloWorldFunction) - .build()); + private static List createFunctionPackageInstructions() { + // CDK will use this command to package your Java Lambda + return List.of( + SHELL_COMMAND, + "-c", + MAVEN_PACKAGE + " && " + + COPY_OUTPUT + ); } } From 20cd14873e96c4ab077d3e712769e7cc9efcd282 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 17:28:16 +0100 Subject: [PATCH 15/45] Fix imports --- .../cdk/infra/src/main/java/cdk/CdkStack.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 25bb0c76a..9b309b034 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -1,9 +1,6 @@ package cdk; -import software.amazon.awscdk.BundlingOptions; -import software.amazon.awscdk.Duration; -import software.amazon.awscdk.Stack; -import software.amazon.awscdk.StackProps; +import software.amazon.awscdk.*; import software.amazon.awscdk.services.apigateway.LambdaIntegration; import software.amazon.awscdk.services.apigateway.RestApi; import software.amazon.awscdk.services.lambda.Code; From de3513a4d82895ec7f877efd6a2a1b98e5ccfb6f Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Tue, 1 Aug 2023 17:44:12 +0100 Subject: [PATCH 16/45] Add outputs example --- .../cdk/infra/src/main/java/cdk/CdkStack.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 9b309b034..10a81d6c1 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -34,6 +34,18 @@ public CdkStack(final Construct scope, final String id, final StackProps props) restApi.getRoot().resourceForPath("/hello") .addMethod("GET", LambdaIntegration.Builder.create(helloWorldFunction) .build()); + + outputApiUrl(restApi); + } + + /** + * Adds URL to the lambda to the outputs + * @param restApi + */ + private void outputApiUrl(RestApi restApi) { + CfnOutput.Builder.create(this, "HelloWorldApiUrl") + .description("API Gateway endpoint URL for Prod stage for Hello World function") + .value(restApi.getUrl() + "hello").build(); } // Method to create the Lambda function From 5218b86320d6ddb0ceb4ad550210145299900aa3 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:03:34 +0100 Subject: [PATCH 17/45] Add test for the stack --- .../src/test/java/cdk/InfraStackTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 examples/powertools-examples-core/cdk/infra/src/test/java/cdk/InfraStackTest.java diff --git a/examples/powertools-examples-core/cdk/infra/src/test/java/cdk/InfraStackTest.java b/examples/powertools-examples-core/cdk/infra/src/test/java/cdk/InfraStackTest.java new file mode 100644 index 000000000..c0a67d1fc --- /dev/null +++ b/examples/powertools-examples-core/cdk/infra/src/test/java/cdk/InfraStackTest.java @@ -0,0 +1,28 @@ +package cdk; + +import org.junit.jupiter.api.Test; +import software.amazon.awscdk.App; +import software.amazon.awscdk.assertions.Template; + +import java.io.IOException; +import java.util.Map; + +public class InfraStackTest { + + @Test + public void testStack() throws IOException { + App app = new App(); + CdkStack stack = new CdkStack(app, "test"); + + Template template = Template.fromStack(stack); + + // The Lambda function should exist + template.resourceCountIs("AWS::Lambda::Function", 1); + + // API Gateway should exist + template.resourceCountIs("AWS::ApiGateway::RestApi", 1); + + // API Gateway should have a path pointing to the Lambda + template.hasResourceProperties("AWS::ApiGateway::Resource", Map.of("PathPart", "hello")); + } +} From 68da97c62a9357ea7669c159dbb7f036a62463ef Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:06:18 +0100 Subject: [PATCH 18/45] Update examples/powertools-examples-core/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/powertools-examples-core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index db3a624f6..a436a032e 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -5,7 +5,7 @@ This project demonstrates the Lambda for Powertools Java module - including [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 architectures: +We provide examples for the following tools: * [SAM](sam/) * [CDK](cdk/) From 2dbb1908c6a3ab9e4d56114f27351f02b3de2dd3 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:07:01 +0100 Subject: [PATCH 19/45] Update examples/powertools-examples-core/cdk/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/powertools-examples-core/cdk/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index 7abebe515..be8d6831a 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -12,7 +12,7 @@ CDK uses the following project structure: - [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. -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. +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 From 3f76c046f6a4b4f42c37dc177c608d90b7ebebaa Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:07:52 +0100 Subject: [PATCH 20/45] Remove unnecessary .gitignore --- examples/powertools-examples-core/sam/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/powertools-examples-core/sam/.gitignore diff --git a/examples/powertools-examples-core/sam/.gitignore b/examples/powertools-examples-core/sam/.gitignore deleted file mode 100644 index e69de29bb..000000000 From 64f36718786e963926699bd36f79dd2fc21646c6 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:09:47 +0100 Subject: [PATCH 21/45] Mixed log level and sample rate --- examples/powertools-examples-core/cdk/app/.gitignore | 1 + .../cdk/infra/src/main/java/cdk/CdkStack.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/powertools-examples-core/cdk/app/.gitignore b/examples/powertools-examples-core/cdk/app/.gitignore index e69de29bb..c7b4aa400 100644 --- a/examples/powertools-examples-core/cdk/app/.gitignore +++ b/examples/powertools-examples-core/cdk/app/.gitignore @@ -0,0 +1 @@ +/?/ diff --git a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java index 10a81d6c1..2ec66f3e2 100644 --- a/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java +++ b/examples/powertools-examples-core/cdk/infra/src/main/java/cdk/CdkStack.java @@ -64,8 +64,8 @@ private Function createHelloWorldFunction() { .build()) .build())) .handler("helloworld.App") - .environment(Map.of("POWERTOOLS_LOG_LEVEL", "0.1", - "POWERTOOLS_LOGGER_SAMPLE_RATE", "INFO", + .environment(Map.of("POWERTOOLS_LOG_LEVEL", "INFO", + "POWERTOOLS_LOGGER_SAMPLE_RATE", "0.1", "POWERTOOLS_LOGGER_LOG_EVENT", "true", "POWERTOOLS_METRICS_NAMESPACE", "Coreutilities" )) From a9a3509522b713a2ee7749de4e5e13d530b505a2 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:17:38 +0100 Subject: [PATCH 22/45] Combine .gitignore files --- examples/.gitignore | 2 ++ .../powertools-examples-core/cdk/app/.gitignore | 1 - .../powertools-examples-core/cdk/infra/.gitignore | 13 ------------- 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 examples/powertools-examples-core/cdk/app/.gitignore delete mode 100644 examples/powertools-examples-core/cdk/infra/.gitignore diff --git a/examples/.gitignore b/examples/.gitignore index 79e044a40..478a1716d 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,2 +1,4 @@ dependency-reduced-pom.xml .aws-sam +/powertools-examples-core/cdk/infra/cdk.out/ +/powertools-examples-core/cdk/app/?/.m2/repository/ diff --git a/examples/powertools-examples-core/cdk/app/.gitignore b/examples/powertools-examples-core/cdk/app/.gitignore deleted file mode 100644 index c7b4aa400..000000000 --- a/examples/powertools-examples-core/cdk/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/?/ diff --git a/examples/powertools-examples-core/cdk/infra/.gitignore b/examples/powertools-examples-core/cdk/infra/.gitignore deleted file mode 100644 index 1db21f162..000000000 --- a/examples/powertools-examples-core/cdk/infra/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -.classpath.txt -target -.classpath -.project -.idea -.settings -.vscode -*.iml - -# CDK asset staging directory -.cdk.staging -cdk.out - From 9a401179ff81a41a0afe6578152f304c87f7b22f Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:20:14 +0100 Subject: [PATCH 23/45] Remove `cdk ls`, since there's just a single stack --- examples/powertools-examples-core/cdk/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index be8d6831a..0c5d1d70d 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -27,7 +27,6 @@ cdk bootstrap && cdk deploy ## Useful commands * `mvn package` compile and run tests -* `cdk ls` list all stacks in the app * `cdk synth` emits the synthesized CloudFormation template * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state From 65fb19c79ebd8156cc9fab613f490352aa159fef Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:22:51 +0100 Subject: [PATCH 24/45] Remove SAM mentions from the CDK readme --- examples/powertools-examples-core/cdk/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/powertools-examples-core/cdk/README.md b/examples/powertools-examples-core/cdk/README.md index 0c5d1d70d..cd654f8eb 100644 --- a/examples/powertools-examples-core/cdk/README.md +++ b/examples/powertools-examples-core/cdk/README.md @@ -12,16 +12,19 @@ CDK uses the following project structure: - [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. -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. +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 example, check out the instructions for getting -started with SAM in [the examples directory](../../README.md) The minimum to deploy the app should be ```bash -cdk bootstrap && cdk deploy +cdk deploy +``` + +If you're running CDK for the first time, you'll need to first run the bootstrap command: +```bash +cdk bootstrap ``` ## Useful commands From f9215a433ad366bc3c9867c832b298fafbfad2f6 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:24:09 +0100 Subject: [PATCH 25/45] Replace "architecture" with "tool" while talking about SAM/CDK --- examples/powertools-examples-core/README.md | 4 ++-- examples/powertools-examples-core/sam/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index a436a032e..df7d8e7c3 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -9,13 +9,13 @@ We provide examples for the following tools: * [SAM](sam/) * [CDK](cdk/) -For all the architectures, the example application is the same, and consists of the following files: +For all 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. - [AppTests.java](sam/src/test/java/helloworld/AppTest.java) - Unit tests for the application code. - [events](events) - Invocation events that you can use to invoke the function. -Configuration files and deployment process for each architecture are described in corresponding README files. +Configuration files and deployment process for each tool are described in corresponding README files. ## Test the application diff --git a/examples/powertools-examples-core/sam/README.md b/examples/powertools-examples-core/sam/README.md index fa1c455c7..aa7294f32 100644 --- a/examples/powertools-examples-core/sam/README.md +++ b/examples/powertools-examples-core/sam/README.md @@ -2,7 +2,7 @@ This project demonstrates the Lambda for Powertools Java module deployed using [Serverless Application Model](https://aws.amazon.com/serverless/sam/). -For general information on project structure similar to all architectures, you can refer to the parent [README](../README.md) +For general information on project structure similar to all tools, you can refer to the parent [README](../README.md) ## Configuration SAM uses [template.yaml](template.yaml) to define the application's AWS resources. From a4f60431d6fd9aa564fc2019e5a2aee714e332ec Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:31:43 +0100 Subject: [PATCH 26/45] Update examples/powertools-examples-core/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/powertools-examples-core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index df7d8e7c3..3da77fac5 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -6,7 +6,7 @@ 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 tools: -* [SAM](sam/) +* [AWS SAM](sam/) * [CDK](cdk/) For all the tools, the example application is the same, and consists of the following files: From 0405ce58f0d1763c3ca9019b7b24279a8c343cb2 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:31:54 +0100 Subject: [PATCH 27/45] Update examples/powertools-examples-core/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérôme Van Der Linden <117538+jeromevdl@users.noreply.github.com> --- examples/powertools-examples-core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index 3da77fac5..5991fef66 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -7,7 +7,7 @@ This project demonstrates the Lambda for Powertools Java module - including We provide examples for the following tools: * [AWS SAM](sam/) -* [CDK](cdk/) +* [AWS CDK](cdk/) For all the tools, the example application is the same, and consists of the following files: From 686448a13169ea5795c3a303da9e72008ad20ab8 Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:39:53 +0100 Subject: [PATCH 28/45] Reformat imports --- .../cdk/app/src/main/java/helloworld/App.java | 23 +++++++++---------- .../sam/src/main/java/helloworld/App.java | 23 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java b/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java index 9a679d338..fccc63b9a 100644 --- a/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core/cdk/app/src/main/java/helloworld/App.java @@ -14,10 +14,21 @@ 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; @@ -29,18 +40,6 @@ 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.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -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; - /** * Handler for requests to Lambda function. */ diff --git a/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java index 9a679d338..fccc63b9a 100644 --- a/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java +++ b/examples/powertools-examples-core/sam/src/main/java/helloworld/App.java @@ -14,10 +14,21 @@ 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; @@ -29,18 +40,6 @@ 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.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -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; - /** * Handler for requests to Lambda function. */ From 89c21ee54cf98e6b876410f5ec1f3cf2357c8cfb Mon Sep 17 00:00:00 2001 From: Alexey Soshin Date: Thu, 3 Aug 2023 13:52:05 +0100 Subject: [PATCH 29/45] Don't include version number in the HelloWorld jar --- .../powertools-examples-core/cdk/app/pom.xml | 139 +++++++++--------- .../cdk/infra/src/main/java/cdk/CdkApp.java | 3 - .../cdk/infra/src/main/java/cdk/CdkStack.java | 34 +++-- ...{InfraStackTest.java => CdkStackTest.java} | 2 +- .../src/main/java/helloworld/App.java | 3 +- 5 files changed, 92 insertions(+), 89 deletions(-) rename examples/powertools-examples-core/cdk/infra/src/test/java/cdk/{InfraStackTest.java => CdkStackTest.java} (96%) diff --git a/examples/powertools-examples-core/cdk/app/pom.xml b/examples/powertools-examples-core/cdk/app/pom.xml index a24d9d9d9..a4359e223 100644 --- a/examples/powertools-examples-core/cdk/app/pom.xml +++ b/examples/powertools-examples-core/cdk/app/pom.xml @@ -1,12 +1,12 @@ + 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.16.1 powertools-examples-core-cdk jar - + Powertools for AWS Lambda (Java) library Examples - Core @@ -38,9 +38,9 @@ 1.2.2 - com.amazonaws - aws-lambda-java-events - 3.11.2 + com.amazonaws + aws-lambda-java-events + 3.11.2 org.apache.logging.log4j @@ -54,74 +54,75 @@ - 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 - - - - - - - - - - - - com.github.edwgiz - maven-shade-plugin.log4j2-cachefile-transformer - 2.15 - - - - + 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 + + + +