Skip to content

Commit 7460c2a

Browse files
authored
Static HTTP client to prevent new connection pools each request (#219)
1 parent ea5f4d9 commit 7460c2a

File tree

14 files changed

+121
-213
lines changed

14 files changed

+121
-213
lines changed

pom.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>software.amazon.cloudformation</groupId>
55
<artifactId>aws-cloudformation-rpdk-java-plugin</artifactId>
6-
<version>1.0</version>
6+
<version>1.0.1</version>
77
<name>AWS CloudFormation RPDK Java Plugin</name>
88
<description>The CloudFormation Resource Provider Development Kit (RPDK) allows you to author your own resource providers that can be used by CloudFormation. This plugin library helps to provide runtime bindings for the execution of your providers by CloudFormation.
99
</description>
@@ -144,7 +144,10 @@
144144
<dependency>
145145
<groupId>software.amazon.awssdk</groupId>
146146
<artifactId>cloudwatchlogs</artifactId>
147-
<version>2.5.69</version>
147+
</dependency>
148+
<dependency>
149+
<groupId>software.amazon.awssdk</groupId>
150+
<artifactId>apache-client</artifactId>
148151
</dependency>
149152

150153
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->

python/rpdk/java/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import logging
22

3-
__version__ = "0.1.1"
3+
__version__ = "0.1.2"
44

55
logging.getLogger(__name__).addHandler(logging.NullHandler())

src/main/java/software/amazon/cloudformation/LambdaWrapper.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.io.InputStream;
2929
import java.io.OutputStream;
3030
import java.net.URI;
31-
import java.nio.charset.Charset;
31+
import java.nio.charset.StandardCharsets;
3232
import java.time.Instant;
3333
import java.util.Arrays;
3434
import java.util.Date;
@@ -44,6 +44,8 @@
4444
import org.json.JSONObject;
4545
import org.json.JSONTokener;
4646

47+
import software.amazon.awssdk.http.SdkHttpClient;
48+
import software.amazon.awssdk.http.apache.ApacheHttpClient;
4749
import software.amazon.awssdk.utils.StringUtils;
4850
import software.amazon.cloudformation.exceptions.BaseHandlerException;
4951
import software.amazon.cloudformation.exceptions.FileScrubberException;
@@ -80,6 +82,8 @@
8082

8183
public abstract class LambdaWrapper<ResourceT, CallbackT> implements RequestStreamHandler {
8284

85+
public static final SdkHttpClient HTTP_CLIENT = ApacheHttpClient.builder().build();
86+
8387
private static final List<Action> MUTATING_ACTIONS = Arrays.asList(Action.CREATE, Action.DELETE, Action.UPDATE);
8488
private static final int INVOCATION_TIMEOUT_MS = 60000;
8589

@@ -115,11 +119,11 @@ public abstract class LambdaWrapper<ResourceT, CallbackT> implements RequestStre
115119
protected LambdaWrapper() {
116120
this.platformCredentialsProvider = new SessionCredentialsProvider();
117121
this.providerCredentialsProvider = new SessionCredentialsProvider();
118-
this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider);
119-
this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider);
120-
this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider);
121-
this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider);
122-
this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider);
122+
this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider, HTTP_CLIENT);
123+
this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider, HTTP_CLIENT);
124+
this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider, HTTP_CLIENT);
125+
this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider, HTTP_CLIENT);
126+
this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider, HTTP_CLIENT);
123127
this.serializer = new Serializer();
124128
this.validator = new Validator();
125129
this.typeReference = getTypeReference();
@@ -137,16 +141,17 @@ public LambdaWrapper(final CallbackAdapter<ResourceT> callbackAdapter,
137141
final MetricsPublisher providerMetricsPublisher,
138142
final CloudWatchScheduler scheduler,
139143
final SchemaValidator validator,
140-
final Serializer serializer) {
144+
final Serializer serializer,
145+
final SdkHttpClient httpClient) {
141146

142147
this.callbackAdapter = callbackAdapter;
143148
this.platformCredentialsProvider = platformCredentialsProvider;
144149
this.providerCredentialsProvider = providerCredentialsProvider;
145-
this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider);
146-
this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider);
147-
this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider);
148-
this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider);
149-
this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider);
150+
this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider, httpClient);
151+
this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider, httpClient);
152+
this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider, httpClient);
153+
this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider, httpClient);
154+
this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider, httpClient);
150155
this.providerEventsLogger = providerEventsLogger;
151156
this.platformLambdaLogger = platformEventsLogger;
152157
this.platformMetricsPublisher = platformMetricsPublisher;
@@ -245,7 +250,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
245250
throw new TerminalException("No request object received");
246251
}
247252

248-
String input = IOUtils.toString(inputStream, "UTF-8");
253+
String input = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
249254
JSONObject rawInput = new JSONObject(new JSONTokener(input));
250255

251256
// deserialize incoming payload to modelled request
@@ -483,7 +488,7 @@ private Response<ResourceT> createProgressResponse(final ProgressEvent<ResourceT
483488
private void writeResponse(final OutputStream outputStream, final Response<ResourceT> response) throws IOException {
484489

485490
String output = this.serializer.serialize(response);
486-
outputStream.write(output.getBytes(Charset.forName("UTF-8")));
491+
outputStream.write(output.getBytes(StandardCharsets.UTF_8));
487492
outputStream.close();
488493
}
489494

src/main/java/software/amazon/cloudformation/injection/AmazonWebServicesProvider.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,33 @@
1616

1717
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
1818
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
19+
import software.amazon.awssdk.awscore.client.builder.AwsClientBuilder;
20+
import software.amazon.awssdk.awscore.client.builder.AwsSyncClientBuilder;
21+
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
22+
import software.amazon.awssdk.core.retry.RetryPolicy;
23+
import software.amazon.awssdk.http.SdkHttpClient;
1924

2025
public abstract class AmazonWebServicesProvider {
2126

27+
protected static final ClientOverrideConfiguration CONFIGURATION = ClientOverrideConfiguration.builder()
28+
.retryPolicy(RetryPolicy.defaultRetryPolicy()).build();
29+
2230
protected final CredentialsProvider credentialsProvider;
31+
protected final SdkHttpClient httpClient;
2332

24-
protected AmazonWebServicesProvider(final CredentialsProvider credentialsProvider) {
33+
protected AmazonWebServicesProvider(final CredentialsProvider credentialsProvider,
34+
final SdkHttpClient httpClient) {
2535
this.credentialsProvider = credentialsProvider;
36+
this.httpClient = httpClient;
2637
}
2738

2839
protected AwsCredentialsProvider getCredentialsProvider() {
2940
return StaticCredentialsProvider.create(this.credentialsProvider.get());
3041
}
42+
43+
protected <BuilderT extends AwsClientBuilder<BuilderT, ClientT> & AwsSyncClientBuilder<BuilderT, ClientT>,
44+
ClientT> BuilderT defaultClient(final BuilderT builder) {
45+
return builder.credentialsProvider(this.getCredentialsProvider()).overrideConfiguration(CONFIGURATION)
46+
.httpClient(httpClient);
47+
}
3148
}

src/main/java/software/amazon/cloudformation/injection/CloudFormationProvider.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@
1616

1717
import java.net.URI;
1818

19+
import software.amazon.awssdk.http.SdkHttpClient;
1920
import software.amazon.awssdk.services.cloudformation.CloudFormationClient;
2021

2122
public class CloudFormationProvider extends AmazonWebServicesProvider {
2223

2324
private URI callbackEndpoint;
2425

25-
public CloudFormationProvider(final CredentialsProvider credentialsProvider) {
26-
super(credentialsProvider);
26+
public CloudFormationProvider(final CredentialsProvider credentialsProvider,
27+
final SdkHttpClient httpClient) {
28+
super(credentialsProvider, httpClient);
2729
}
2830

2931
public void setCallbackEndpoint(final URI callbackEndpoint) {
3032
this.callbackEndpoint = callbackEndpoint;
3133
}
3234

3335
public CloudFormationClient get() {
34-
return CloudFormationClient.builder().credentialsProvider(this.getCredentialsProvider())
36+
return CloudFormationClient.builder().credentialsProvider(this.getCredentialsProvider()).httpClient(httpClient)
3537
.endpointOverride(this.callbackEndpoint).build();
3638
}
3739
}

src/main/java/software/amazon/cloudformation/injection/CloudWatchEventsProvider.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,17 @@
1414
*/
1515
package software.amazon.cloudformation.injection;
1616

17-
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
18-
import software.amazon.awssdk.core.retry.RetryPolicy;
17+
import software.amazon.awssdk.http.SdkHttpClient;
1918
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
2019

2120
public class CloudWatchEventsProvider extends AmazonWebServicesProvider {
2221

23-
public CloudWatchEventsProvider(final CredentialsProvider credentialsProvider) {
24-
super(credentialsProvider);
22+
public CloudWatchEventsProvider(final CredentialsProvider credentialsProvider,
23+
final SdkHttpClient httpClient) {
24+
super(credentialsProvider, httpClient);
2525
}
2626

2727
public CloudWatchEventsClient get() {
28-
return CloudWatchEventsClient.builder().overrideConfiguration(ClientOverrideConfiguration.builder()
29-
// Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
30-
// Exceptions
31-
.retryPolicy(RetryPolicy.builder().numRetries(16).build()).build()).credentialsProvider(this.getCredentialsProvider())
32-
.build();
28+
return defaultClient(CloudWatchEventsClient.builder()).build();
3329
}
3430
}

src/main/java/software/amazon/cloudformation/injection/CloudWatchLogsProvider.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,17 @@
1414
*/
1515
package software.amazon.cloudformation.injection;
1616

17-
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
18-
import software.amazon.awssdk.core.retry.RetryPolicy;
17+
import software.amazon.awssdk.http.SdkHttpClient;
1918
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
2019

2120
public class CloudWatchLogsProvider extends AmazonWebServicesProvider {
2221

23-
public CloudWatchLogsProvider(final CredentialsProvider credentialsProvider) {
24-
super(credentialsProvider);
22+
public CloudWatchLogsProvider(final CredentialsProvider credentialsProvider,
23+
final SdkHttpClient httpClient) {
24+
super(credentialsProvider, httpClient);
2525
}
2626

2727
public CloudWatchLogsClient get() {
28-
return CloudWatchLogsClient.builder().credentialsProvider(this.getCredentialsProvider())
29-
.overrideConfiguration(ClientOverrideConfiguration.builder()
30-
// Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
31-
// Exceptions
32-
.retryPolicy(RetryPolicy.builder().numRetries(16).build()).build())
33-
.build();
28+
return defaultClient(CloudWatchLogsClient.builder()).build();
3429
}
3530
}

src/main/java/software/amazon/cloudformation/injection/CloudWatchProvider.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,17 @@
1414
*/
1515
package software.amazon.cloudformation.injection;
1616

17-
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
18-
import software.amazon.awssdk.core.retry.RetryPolicy;
17+
import software.amazon.awssdk.http.SdkHttpClient;
1918
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
2019

2120
public class CloudWatchProvider extends AmazonWebServicesProvider {
2221

23-
public CloudWatchProvider(final CredentialsProvider credentialsProvider) {
24-
super(credentialsProvider);
22+
public CloudWatchProvider(final CredentialsProvider credentialsProvider,
23+
final SdkHttpClient httpClient) {
24+
super(credentialsProvider, httpClient);
2525
}
2626

2727
public CloudWatchClient get() {
28-
return CloudWatchClient.builder().credentialsProvider(this.getCredentialsProvider())
29-
.overrideConfiguration(ClientOverrideConfiguration.builder()
30-
// Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
31-
// Exceptions
32-
.retryPolicy(RetryPolicy.builder().numRetries(16).build()).build())
33-
.build();
28+
return defaultClient(CloudWatchClient.builder()).build();
3429
}
3530
}

src/main/java/software/amazon/cloudformation/proxy/aws/AWSServiceSerdeModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import software.amazon.awssdk.core.SdkPojo;
3030
import software.amazon.awssdk.utils.builder.SdkBuilder;
3131

32+
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
3233
public class AWSServiceSerdeModule extends Module {
3334

3435
public static class AWSSerializers extends Serializers.Base {

src/main/resources/com/amazonaws/cloudformation/checkstyle.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@
3636
value="${checkstyle.suppressions.file}"
3737
default="checkstyle-suppressions.xml"/>
3838
</module>
39-
39+
<!-- Enable @SuppressWarnings annotation -->
40+
<module name="SuppressWarningsFilter" />
4041
<module name="TreeWalker">
42+
<!-- Enable @SuppressWarnings annotation -->
43+
<module name="SuppressWarningsHolder" />
4144

4245
<!-- Allow suppressing rules via comments. -->
4346
<module name="SuppressionCommentFilter"/>

0 commit comments

Comments
 (0)