Skip to content

Commit 02da4b7

Browse files
authored
Merge branch 'main' into gh-actions-hash
2 parents b05531e + 661100c commit 02da4b7

File tree

271 files changed

+6858
-3811
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

271 files changed

+6858
-3811
lines changed

CONTRIBUTING.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ To send us a pull request, please:
3131

3232
1. Fork the repository.
3333
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34-
3. Ensure local tests pass.
35-
4. Commit to your fork using clear commit messages.
36-
5. Send us a pull request, answering any default questions in the pull request interface.
37-
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
34+
3. Ensure local tests pass: `mvn clean test`
35+
4. Ensure your code is formatted with the provided [checkstyle.xml](https://github.com/aws-powertools/powertools-lambda-java/blob/main/checkstyle.xml): `mvn clean verify`
36+
5. Commit to your fork using clear commit messages.
37+
6. Send us a pull request, answering any default questions in the pull request interface.
38+
7. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
3839

3940
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
4041
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,15 @@ The following companies, among others, use Powertools:
197197
* [MkDocs](https://www.mkdocs.org/)
198198
* [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)
199199

200+
## Connect
201+
202+
* **Powertools for AWS Lambda on Discord**: `#java` - **[Invite link](https://discord.gg/B8zZKbbyET)**
203+
* **Email**: <[email protected]>
204+
205+
## Security disclosures
206+
207+
If you think you’ve found a potential security issue, please do not post it in the Issues. Instead, please follow the instructions [here](https://aws.amazon.com/security/vulnerability-reporting/) or [email AWS security directly](mailto:[email protected]).
208+
200209
## License
201210

202211
This library is licensed under the Apache License, Version 2.0. See the LICENSE file.

checkstyle.xml

+427
Large diffs are not rendered by default.

docs/core/logging.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ to customise what is logged.
239239
*/
240240
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
241241

242-
Logger log = LogManager.getLogger();
242+
Logger log = LogManager.getLogger(App.class);
243243

244244
@Logging
245245
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -256,7 +256,7 @@ to customise what is logged.
256256
*/
257257
public class AppLogEvent implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
258258

259-
Logger log = LogManager.getLogger();
259+
Logger log = LogManager.getLogger(AppLogEvent.class);
260260

261261
@Logging(logEvent = true)
262262
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -315,7 +315,7 @@ You can set a Correlation ID using `correlationIdPath` attribute by passing a [J
315315
*/
316316
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
317317

318-
Logger log = LogManager.getLogger();
318+
Logger log = LogManager.getLogger(App.class);
319319

320320
@Logging(correlationIdPath = "/headers/my_request_id_header")
321321
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -364,7 +364,7 @@ for known event sources, where either a request ID or X-Ray Trace ID are present
364364
*/
365365
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
366366

367-
Logger log = LogManager.getLogger();
367+
Logger log = LogManager.getLogger(App.class);
368368

369369
@Logging(correlationIdPath = CorrelationIdPathConstants.API_GATEWAY_REST)
370370
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -417,7 +417,7 @@ You can append your own keys to your existing logs via `appendKey`.
417417
*/
418418
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
419419

420-
Logger log = LogManager.getLogger();
420+
Logger log = LogManager.getLogger(App.class);
421421

422422
@Logging(logEvent = true)
423423
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -449,7 +449,7 @@ You can remove any additional key from entry using `LoggingUtils.removeKeys()`.
449449
*/
450450
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
451451

452-
Logger log = LogManager.getLogger();
452+
Logger log = LogManager.getLogger(App.class);
453453

454454
@Logging(logEvent = true)
455455
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -484,7 +484,7 @@ this means that custom keys can be persisted across invocations. If you want all
484484
*/
485485
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
486486

487-
Logger log = LogManager.getLogger();
487+
Logger log = LogManager.getLogger(App.class);
488488

489489
@Logging(clearState = true)
490490
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {
@@ -545,7 +545,7 @@ specific fields from received event due to security.
545545
*/
546546
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
547547

548-
Logger log = LogManager.getLogger();
548+
Logger log = LogManager.getLogger(App.class);
549549

550550
static {
551551
ObjectMapper objectMapper = new ObjectMapper();
@@ -575,7 +575,7 @@ via `samplingRate` attribute on annotation.
575575
*/
576576
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
577577

578-
Logger log = LogManager.getLogger();
578+
Logger log = LogManager.getLogger(App.class);
579579

580580
@Logging(samplingRate = 0.5)
581581
public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) {

examples/README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This directory holds example projects demoing different components of the Powertools for AWS Lambda (Java).
44
Each example can be copied from its subdirectory and used independently of the rest of this repository.
55

6-
## The Examples
6+
## Examples
77

88
* [powertools-examples-core](powertools-examples-core) - Demonstrates the core logging, tracing, and metrics modules
99
* [powertools-examples-idempotency](powertools-examples-idempotency) - An idempotent HTTP API
@@ -51,6 +51,17 @@ The first command will build the source of your application. The second command
5151

5252
You can find your API Gateway Endpoint URL in the output values displayed after deployment.
5353

54+
### External examples
55+
56+
You can find more examples in the https://github.com/aws/aws-sam-cli-app-templates project:
57+
58+
* [Java 8 + Maven](https://github.com/aws/aws-sam-cli-app-templates/tree/master/java8/hello-pt-maven)
59+
* [Java 8 on Amazon Linux 2 + Maven](https://github.com/aws/aws-sam-cli-app-templates/tree/master/java8.al2/hello-pt-maven)
60+
* [Java 11 + Maven](https://github.com/aws/aws-sam-cli-app-templates/tree/master/java11/hello-pt-maven)
61+
* [Java 17 + Maven](https://github.com/aws/aws-sam-cli-app-templates/tree/master/java17/hello-pt-maven)
62+
* [Java 17 + Gradle](https://github.com/aws/aws-sam-cli-app-templates/tree/master/java17/hello-pt-gradle)
63+
64+
5465
### SAM - Other Tools
5566

5667
If you prefer to use an integrated development environment (IDE) to build and test your application, you can use the AWS Toolkit.

examples/pom.xml

+14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2023 Amazon.com, Inc. or its affiliates.
4+
~ Licensed under the Apache License, Version 2.0 (the
5+
~ "License"); you may not use this file except in compliance
6+
~ with the License. You may obtain a copy of the License at
7+
~ http://www.apache.org/licenses/LICENSE-2.0
8+
~ Unless required by applicable law or agreed to in writing, software
9+
~ distributed under the License is distributed on an "AS IS" BASIS,
10+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
~ See the License for the specific language governing permissions and
12+
~ limitations under the License.
13+
~
14+
-->
15+
216
<project xmlns="http://maven.apache.org/POM/4.0.0"
317
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
418
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

examples/powertools-examples-cloudformation/infra/cdk/src/main/java/com/myorg/PowertoolsExamplesCloudformationCdkApp.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ public class PowertoolsExamplesCloudformationCdkApp {
77
public static void main(final String[] args) {
88
App app = new App();
99

10-
new PowertoolsExamplesCloudformationCdkStack(app, "PowertoolsExamplesCloudformationCdkStack", StackProps.builder()
11-
.build());
10+
new PowertoolsExamplesCloudformationCdkStack(app, "PowertoolsExamplesCloudformationCdkStack",
11+
StackProps.builder()
12+
.build());
1213

1314
app.synth();
1415
}

examples/powertools-examples-cloudformation/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<maven.deploy.skip>true</maven.deploy.skip>
1717
<lambda.core.version>1.2.2</lambda.core.version>
1818
<lambda.events.version>3.11.2</lambda.events.version>
19-
<aws.sdk.version>2.20.108</aws.sdk.version>
19+
<aws.sdk.version>2.20.111</aws.sdk.version>
2020
</properties>
2121
<dependencyManagement>
2222
<dependencies>

examples/powertools-examples-cloudformation/src/main/java/helloworld/App.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public App() {
4141
protected Response create(CloudFormationCustomResourceEvent cloudFormationCustomResourceEvent, Context context) {
4242
// Validate the CloudFormation Custom Resource event
4343
Objects.requireNonNull(cloudFormationCustomResourceEvent, "cloudFormationCustomResourceEvent cannot be null.");
44-
Objects.requireNonNull(cloudFormationCustomResourceEvent.getResourceProperties().get("BucketName"), "BucketName cannot be null.");
44+
Objects.requireNonNull(cloudFormationCustomResourceEvent.getResourceProperties().get("BucketName"),
45+
"BucketName cannot be null.");
4546

4647
log.info(cloudFormationCustomResourceEvent);
4748
String bucketName = (String) cloudFormationCustomResourceEvent.getResourceProperties().get("BucketName");
@@ -70,7 +71,8 @@ protected Response create(CloudFormationCustomResourceEvent cloudFormationCustom
7071
protected Response update(CloudFormationCustomResourceEvent cloudFormationCustomResourceEvent, Context context) {
7172
// Validate the CloudFormation Custom Resource event
7273
Objects.requireNonNull(cloudFormationCustomResourceEvent, "cloudFormationCustomResourceEvent cannot be null.");
73-
Objects.requireNonNull(cloudFormationCustomResourceEvent.getResourceProperties().get("BucketName"), "BucketName cannot be null.");
74+
Objects.requireNonNull(cloudFormationCustomResourceEvent.getResourceProperties().get("BucketName"),
75+
"BucketName cannot be null.");
7476

7577
log.info(cloudFormationCustomResourceEvent);
7678
// Get the physicalResourceId. physicalResourceId is the value returned to CloudFormation in the Create request, and passed in on subsequent requests (e.g. UPDATE or DELETE)
@@ -112,7 +114,8 @@ protected Response update(CloudFormationCustomResourceEvent cloudFormationCustom
112114
protected Response delete(CloudFormationCustomResourceEvent cloudFormationCustomResourceEvent, Context context) {
113115
// Validate the CloudFormation Custom Resource event
114116
Objects.requireNonNull(cloudFormationCustomResourceEvent, "cloudFormationCustomResourceEvent cannot be null.");
115-
Objects.requireNonNull(cloudFormationCustomResourceEvent.getPhysicalResourceId(), "PhysicalResourceId cannot be null.");
117+
Objects.requireNonNull(cloudFormationCustomResourceEvent.getPhysicalResourceId(),
118+
"PhysicalResourceId cannot be null.");
116119

117120
log.info(cloudFormationCustomResourceEvent);
118121
// Get the physicalResourceId. physicalResourceId is the value provided to CloudFormation in the Create request.
@@ -142,7 +145,8 @@ protected Response delete(CloudFormationCustomResourceEvent cloudFormationCustom
142145

143146
private boolean bucketExists(String bucketName) {
144147
try {
145-
HeadBucketResponse headBucketResponse = s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build());
148+
HeadBucketResponse headBucketResponse =
149+
s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build());
146150
if (headBucketResponse.sdkHttpResponse().isSuccessful()) {
147151
return true;
148152
}
@@ -157,7 +161,8 @@ private void createBucket(String bucketName) {
157161
S3Waiter waiter = s3Client.waiter();
158162
CreateBucketRequest createBucketRequest = CreateBucketRequest.builder().bucket(bucketName).build();
159163
s3Client.createBucket(createBucketRequest);
160-
WaiterResponse<HeadBucketResponse> waiterResponse = waiter.waitUntilBucketExists(HeadBucketRequest.builder().bucket(bucketName).build());
164+
WaiterResponse<HeadBucketResponse> waiterResponse =
165+
waiter.waitUntilBucketExists(HeadBucketRequest.builder().bucket(bucketName).build());
161166
waiterResponse.matched().response().ifPresent(log::info);
162167
log.info("Bucket Created {}", bucketName);
163168
}

examples/powertools-examples-core/src/main/java/helloworld/App.java

+43-27
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,47 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
115
package helloworld;
216

3-
import java.io.BufferedReader;
4-
import java.io.IOException;
5-
import java.io.InputStreamReader;
6-
import java.net.URL;
7-
import java.util.HashMap;
8-
import java.util.Map;
9-
import java.util.stream.Collectors;
17+
import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger;
18+
import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric;
19+
import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata;
20+
import static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment;
1021

1122
import com.amazonaws.services.lambda.runtime.Context;
1223
import com.amazonaws.services.lambda.runtime.RequestHandler;
1324
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
1425
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
1526
import com.amazonaws.xray.AWSXRay;
1627
import com.amazonaws.xray.entities.Entity;
28+
import java.io.BufferedReader;
29+
import java.io.IOException;
30+
import java.io.InputStreamReader;
31+
import java.net.URL;
32+
import java.util.HashMap;
33+
import java.util.Map;
34+
import java.util.stream.Collectors;
1735
import org.apache.logging.log4j.LogManager;
1836
import org.apache.logging.log4j.Logger;
1937
import software.amazon.cloudwatchlogs.emf.model.DimensionSet;
2038
import software.amazon.cloudwatchlogs.emf.model.Unit;
21-
import software.amazon.lambda.powertools.logging.LoggingUtils;
2239
import software.amazon.lambda.powertools.logging.Logging;
40+
import software.amazon.lambda.powertools.logging.LoggingUtils;
2341
import software.amazon.lambda.powertools.metrics.Metrics;
2442
import software.amazon.lambda.powertools.tracing.CaptureMode;
25-
import software.amazon.lambda.powertools.tracing.TracingUtils;
2643
import software.amazon.lambda.powertools.tracing.Tracing;
27-
28-
import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger;
29-
import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric;
30-
import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata;
31-
import static software.amazon.lambda.powertools.tracing.TracingUtils.withEntitySubsegment;
44+
import software.amazon.lambda.powertools.tracing.TracingUtils;
3245

3346
/**
3447
* Handler for requests to Lambda function.
@@ -47,10 +60,11 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
4760

4861
metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT);
4962

50-
withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> {
51-
metric.setDimensions(DimensionSet.of("AnotherService", "CustomService"));
52-
metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1"));
53-
});
63+
withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) ->
64+
{
65+
metric.setDimensions(DimensionSet.of("AnotherService", "CustomService"));
66+
metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1"));
67+
});
5468

5569
LoggingUtils.appendKey("test", "willBeLogged");
5670

@@ -62,11 +76,12 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
6276
TracingUtils.putAnnotation("Test", "New");
6377
String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents);
6478

65-
TracingUtils.withSubsegment("loggingResponse", subsegment -> {
66-
String sampled = "log something out";
67-
log.info(sampled);
68-
log.info(output);
69-
});
79+
TracingUtils.withSubsegment("loggingResponse", subsegment ->
80+
{
81+
String sampled = "log something out";
82+
log.info(sampled);
83+
log.info(output);
84+
});
7085

7186
threadOption1();
7287

@@ -91,10 +106,11 @@ private void threadOption1() throws InterruptedException {
91106

92107
private void threadOption2() throws InterruptedException {
93108
Entity traceEntity = AWSXRay.getTraceEntity();
94-
Thread anotherThread = new Thread(() -> withEntitySubsegment("inlineLog", traceEntity, subsegment -> {
95-
String var = "somethingToProcess";
96-
log.info("inside threaded logging inline {}", var);
97-
}));
109+
Thread anotherThread = new Thread(() -> withEntitySubsegment("inlineLog", traceEntity, subsegment ->
110+
{
111+
String var = "somethingToProcess";
112+
log.info("inside threaded logging inline {}", var);
113+
}));
98114
anotherThread.start();
99115
anotherThread.join();
100116
}

examples/powertools-examples-core/src/main/java/helloworld/AppStream.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1+
/*
2+
* Copyright 2023 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
115
package helloworld;
216

17+
import com.amazonaws.services.lambda.runtime.Context;
18+
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
19+
import com.fasterxml.jackson.databind.ObjectMapper;
320
import java.io.IOException;
421
import java.io.InputStream;
522
import java.io.OutputStream;
623
import java.util.Map;
7-
8-
import com.amazonaws.services.lambda.runtime.Context;
9-
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
10-
import com.fasterxml.jackson.databind.ObjectMapper;
1124
import software.amazon.lambda.powertools.logging.Logging;
1225
import software.amazon.lambda.powertools.metrics.Metrics;
1326

0 commit comments

Comments
 (0)