diff --git a/pom.xml b/pom.xml
index e678cb4a..6229071c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
software.amazon.cloudformation
aws-cloudformation-rpdk-java-plugin
- 1.0
+ 1.0.1
AWS CloudFormation RPDK Java Plugin
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.
@@ -144,7 +144,10 @@
software.amazon.awssdk
cloudwatchlogs
- 2.5.69
+
+
+ software.amazon.awssdk
+ apache-client
diff --git a/python/rpdk/java/__init__.py b/python/rpdk/java/__init__.py
index e6219d37..76b80cb6 100644
--- a/python/rpdk/java/__init__.py
+++ b/python/rpdk/java/__init__.py
@@ -1,5 +1,5 @@
import logging
-__version__ = "0.1.1"
+__version__ = "0.1.2"
logging.getLogger(__name__).addHandler(logging.NullHandler())
diff --git a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java
index 6d63297d..9b57dc24 100644
--- a/src/main/java/software/amazon/cloudformation/LambdaWrapper.java
+++ b/src/main/java/software/amazon/cloudformation/LambdaWrapper.java
@@ -28,7 +28,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
@@ -44,6 +44,8 @@
import org.json.JSONObject;
import org.json.JSONTokener;
+import software.amazon.awssdk.http.SdkHttpClient;
+import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.cloudformation.exceptions.BaseHandlerException;
import software.amazon.cloudformation.exceptions.FileScrubberException;
@@ -80,6 +82,8 @@
public abstract class LambdaWrapper implements RequestStreamHandler {
+ public static final SdkHttpClient HTTP_CLIENT = ApacheHttpClient.builder().build();
+
private static final List MUTATING_ACTIONS = Arrays.asList(Action.CREATE, Action.DELETE, Action.UPDATE);
private static final int INVOCATION_TIMEOUT_MS = 60000;
@@ -115,11 +119,11 @@ public abstract class LambdaWrapper implements RequestStre
protected LambdaWrapper() {
this.platformCredentialsProvider = new SessionCredentialsProvider();
this.providerCredentialsProvider = new SessionCredentialsProvider();
- this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider);
- this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider);
- this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider);
- this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider);
- this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider);
+ this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider, HTTP_CLIENT);
+ this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider, HTTP_CLIENT);
+ this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider, HTTP_CLIENT);
+ this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider, HTTP_CLIENT);
+ this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider, HTTP_CLIENT);
this.serializer = new Serializer();
this.validator = new Validator();
this.typeReference = getTypeReference();
@@ -137,16 +141,17 @@ public LambdaWrapper(final CallbackAdapter callbackAdapter,
final MetricsPublisher providerMetricsPublisher,
final CloudWatchScheduler scheduler,
final SchemaValidator validator,
- final Serializer serializer) {
+ final Serializer serializer,
+ final SdkHttpClient httpClient) {
this.callbackAdapter = callbackAdapter;
this.platformCredentialsProvider = platformCredentialsProvider;
this.providerCredentialsProvider = providerCredentialsProvider;
- this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider);
- this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider);
- this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider);
- this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider);
- this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider);
+ this.cloudFormationProvider = new CloudFormationProvider(this.platformCredentialsProvider, httpClient);
+ this.platformCloudWatchProvider = new CloudWatchProvider(this.platformCredentialsProvider, httpClient);
+ this.providerCloudWatchProvider = new CloudWatchProvider(this.providerCredentialsProvider, httpClient);
+ this.platformCloudWatchEventsProvider = new CloudWatchEventsProvider(this.platformCredentialsProvider, httpClient);
+ this.cloudWatchLogsProvider = new CloudWatchLogsProvider(this.providerCredentialsProvider, httpClient);
this.providerEventsLogger = providerEventsLogger;
this.platformLambdaLogger = platformEventsLogger;
this.platformMetricsPublisher = platformMetricsPublisher;
@@ -245,7 +250,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
throw new TerminalException("No request object received");
}
- String input = IOUtils.toString(inputStream, "UTF-8");
+ String input = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
JSONObject rawInput = new JSONObject(new JSONTokener(input));
// deserialize incoming payload to modelled request
@@ -483,7 +488,7 @@ private Response createProgressResponse(final ProgressEvent response) throws IOException {
String output = this.serializer.serialize(response);
- outputStream.write(output.getBytes(Charset.forName("UTF-8")));
+ outputStream.write(output.getBytes(StandardCharsets.UTF_8));
outputStream.close();
}
diff --git a/src/main/java/software/amazon/cloudformation/injection/AmazonWebServicesProvider.java b/src/main/java/software/amazon/cloudformation/injection/AmazonWebServicesProvider.java
index ff81801e..53465426 100644
--- a/src/main/java/software/amazon/cloudformation/injection/AmazonWebServicesProvider.java
+++ b/src/main/java/software/amazon/cloudformation/injection/AmazonWebServicesProvider.java
@@ -16,16 +16,33 @@
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.awscore.client.builder.AwsClientBuilder;
+import software.amazon.awssdk.awscore.client.builder.AwsSyncClientBuilder;
+import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
+import software.amazon.awssdk.core.retry.RetryPolicy;
+import software.amazon.awssdk.http.SdkHttpClient;
public abstract class AmazonWebServicesProvider {
+ protected static final ClientOverrideConfiguration CONFIGURATION = ClientOverrideConfiguration.builder()
+ .retryPolicy(RetryPolicy.defaultRetryPolicy()).build();
+
protected final CredentialsProvider credentialsProvider;
+ protected final SdkHttpClient httpClient;
- protected AmazonWebServicesProvider(final CredentialsProvider credentialsProvider) {
+ protected AmazonWebServicesProvider(final CredentialsProvider credentialsProvider,
+ final SdkHttpClient httpClient) {
this.credentialsProvider = credentialsProvider;
+ this.httpClient = httpClient;
}
protected AwsCredentialsProvider getCredentialsProvider() {
return StaticCredentialsProvider.create(this.credentialsProvider.get());
}
+
+ protected & AwsSyncClientBuilder,
+ ClientT> BuilderT defaultClient(final BuilderT builder) {
+ return builder.credentialsProvider(this.getCredentialsProvider()).overrideConfiguration(CONFIGURATION)
+ .httpClient(httpClient);
+ }
}
diff --git a/src/main/java/software/amazon/cloudformation/injection/CloudFormationProvider.java b/src/main/java/software/amazon/cloudformation/injection/CloudFormationProvider.java
index 4d64c00b..4f775602 100644
--- a/src/main/java/software/amazon/cloudformation/injection/CloudFormationProvider.java
+++ b/src/main/java/software/amazon/cloudformation/injection/CloudFormationProvider.java
@@ -16,14 +16,16 @@
import java.net.URI;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.services.cloudformation.CloudFormationClient;
public class CloudFormationProvider extends AmazonWebServicesProvider {
private URI callbackEndpoint;
- public CloudFormationProvider(final CredentialsProvider credentialsProvider) {
- super(credentialsProvider);
+ public CloudFormationProvider(final CredentialsProvider credentialsProvider,
+ final SdkHttpClient httpClient) {
+ super(credentialsProvider, httpClient);
}
public void setCallbackEndpoint(final URI callbackEndpoint) {
@@ -31,7 +33,7 @@ public void setCallbackEndpoint(final URI callbackEndpoint) {
}
public CloudFormationClient get() {
- return CloudFormationClient.builder().credentialsProvider(this.getCredentialsProvider())
+ return CloudFormationClient.builder().credentialsProvider(this.getCredentialsProvider()).httpClient(httpClient)
.endpointOverride(this.callbackEndpoint).build();
}
}
diff --git a/src/main/java/software/amazon/cloudformation/injection/CloudWatchEventsProvider.java b/src/main/java/software/amazon/cloudformation/injection/CloudWatchEventsProvider.java
index 15b2e349..6c364fd1 100644
--- a/src/main/java/software/amazon/cloudformation/injection/CloudWatchEventsProvider.java
+++ b/src/main/java/software/amazon/cloudformation/injection/CloudWatchEventsProvider.java
@@ -14,21 +14,17 @@
*/
package software.amazon.cloudformation.injection;
-import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
-import software.amazon.awssdk.core.retry.RetryPolicy;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
public class CloudWatchEventsProvider extends AmazonWebServicesProvider {
- public CloudWatchEventsProvider(final CredentialsProvider credentialsProvider) {
- super(credentialsProvider);
+ public CloudWatchEventsProvider(final CredentialsProvider credentialsProvider,
+ final SdkHttpClient httpClient) {
+ super(credentialsProvider, httpClient);
}
public CloudWatchEventsClient get() {
- return CloudWatchEventsClient.builder().overrideConfiguration(ClientOverrideConfiguration.builder()
- // Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
- // Exceptions
- .retryPolicy(RetryPolicy.builder().numRetries(16).build()).build()).credentialsProvider(this.getCredentialsProvider())
- .build();
+ return defaultClient(CloudWatchEventsClient.builder()).build();
}
}
diff --git a/src/main/java/software/amazon/cloudformation/injection/CloudWatchLogsProvider.java b/src/main/java/software/amazon/cloudformation/injection/CloudWatchLogsProvider.java
index b2834fbc..1fabaff6 100644
--- a/src/main/java/software/amazon/cloudformation/injection/CloudWatchLogsProvider.java
+++ b/src/main/java/software/amazon/cloudformation/injection/CloudWatchLogsProvider.java
@@ -14,22 +14,17 @@
*/
package software.amazon.cloudformation.injection;
-import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
-import software.amazon.awssdk.core.retry.RetryPolicy;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
public class CloudWatchLogsProvider extends AmazonWebServicesProvider {
- public CloudWatchLogsProvider(final CredentialsProvider credentialsProvider) {
- super(credentialsProvider);
+ public CloudWatchLogsProvider(final CredentialsProvider credentialsProvider,
+ final SdkHttpClient httpClient) {
+ super(credentialsProvider, httpClient);
}
public CloudWatchLogsClient get() {
- return CloudWatchLogsClient.builder().credentialsProvider(this.getCredentialsProvider())
- .overrideConfiguration(ClientOverrideConfiguration.builder()
- // Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
- // Exceptions
- .retryPolicy(RetryPolicy.builder().numRetries(16).build()).build())
- .build();
+ return defaultClient(CloudWatchLogsClient.builder()).build();
}
}
diff --git a/src/main/java/software/amazon/cloudformation/injection/CloudWatchProvider.java b/src/main/java/software/amazon/cloudformation/injection/CloudWatchProvider.java
index aecd8c6b..1d3eef0d 100644
--- a/src/main/java/software/amazon/cloudformation/injection/CloudWatchProvider.java
+++ b/src/main/java/software/amazon/cloudformation/injection/CloudWatchProvider.java
@@ -14,22 +14,17 @@
*/
package software.amazon.cloudformation.injection;
-import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
-import software.amazon.awssdk.core.retry.RetryPolicy;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
public class CloudWatchProvider extends AmazonWebServicesProvider {
- public CloudWatchProvider(final CredentialsProvider credentialsProvider) {
- super(credentialsProvider);
+ public CloudWatchProvider(final CredentialsProvider credentialsProvider,
+ final SdkHttpClient httpClient) {
+ super(credentialsProvider, httpClient);
}
public CloudWatchClient get() {
- return CloudWatchClient.builder().credentialsProvider(this.getCredentialsProvider())
- .overrideConfiguration(ClientOverrideConfiguration.builder()
- // Default Retry Condition of Retry Policy retries on Throttling and ClockSkew
- // Exceptions
- .retryPolicy(RetryPolicy.builder().numRetries(16).build()).build())
- .build();
+ return defaultClient(CloudWatchClient.builder()).build();
}
}
diff --git a/src/main/java/software/amazon/cloudformation/proxy/aws/AWSServiceSerdeModule.java b/src/main/java/software/amazon/cloudformation/proxy/aws/AWSServiceSerdeModule.java
index 0a518eae..73b4e9bc 100644
--- a/src/main/java/software/amazon/cloudformation/proxy/aws/AWSServiceSerdeModule.java
+++ b/src/main/java/software/amazon/cloudformation/proxy/aws/AWSServiceSerdeModule.java
@@ -29,6 +29,7 @@
import software.amazon.awssdk.core.SdkPojo;
import software.amazon.awssdk.utils.builder.SdkBuilder;
+@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
public class AWSServiceSerdeModule extends Module {
public static class AWSSerializers extends Serializers.Base {
diff --git a/src/main/resources/com/amazonaws/cloudformation/checkstyle.xml b/src/main/resources/com/amazonaws/cloudformation/checkstyle.xml
index 2fb471ef..b2ca4cd2 100644
--- a/src/main/resources/com/amazonaws/cloudformation/checkstyle.xml
+++ b/src/main/resources/com/amazonaws/cloudformation/checkstyle.xml
@@ -36,8 +36,11 @@
value="${checkstyle.suppressions.file}"
default="checkstyle-suppressions.xml"/>
-
+
+
+
+
diff --git a/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java b/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java
index 82ae22be..55c8a23a 100644
--- a/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java
+++ b/src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java
@@ -43,6 +43,7 @@
import java.util.Map;
import org.json.JSONObject;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
@@ -52,6 +53,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.services.cloudformation.model.OperationStatusCheckFailedException;
import software.amazon.cloudformation.exceptions.ResourceAlreadyExistsException;
import software.amazon.cloudformation.exceptions.ResourceNotFoundException;
@@ -113,6 +115,18 @@ public class LambdaWrapperTest {
@Mock
private ResourceHandlerRequest resourceHandlerRequest;
+ @Mock
+ private SdkHttpClient httpClient;
+
+ private WrapperOverride wrapper;
+
+ @BeforeEach
+ public void initWrapper() {
+ wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider, providerLoggingCredentialsProvider,
+ platformEventsLogger, providerEventsLogger, platformMetricsPublisher,
+ providerMetricsPublisher, scheduler, validator, httpClient);
+ }
+
public static InputStream loadRequestStream(final String fileName) {
final File file = new File(String.format(TEST_DATA_BASE_PATH, fileName));
@@ -161,11 +175,6 @@ private void verifyHandlerResponse(final OutputStream out, final HandlerResponse
public void invokeHandler_nullResponse_returnsFailure(final String requestDataPath, final String actionAsString)
throws IOException {
final Action action = Action.valueOf(actionAsString);
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = new TestModel();
// a null response is a terminal fault
@@ -225,10 +234,6 @@ public void invokeHandlerForCreate_without_customer_loggingCredentials() throws
private void invokeHandler_without_customerLoggingCredentials(final String requestDataPath, final Action action)
throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = new TestModel();
// a null response is a terminal fault
@@ -284,10 +289,6 @@ private void invokeHandler_without_customerLoggingCredentials(final String reque
public void invokeHandler_handlerFailed_returnsFailure(final String requestDataPath, final String actionAsString)
throws IOException {
final Action action = Action.valueOf(actionAsString);
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
// explicit fault response is treated as an unsuccessful synchronous completion
final ProgressEvent pe = ProgressEvent.builder()
@@ -333,11 +334,6 @@ public void invokeHandler_handlerFailed_returnsFailure(final String requestDataP
@Test
public void invokeHandler_withNullInput() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
// explicit fault response is treated as an unsuccessful synchronous completion
final ProgressEvent pe = ProgressEvent.builder()
.status(OperationStatus.FAILED).errorCode(HandlerErrorCode.InternalFailure).message("Custom Fault").build();
@@ -359,10 +355,6 @@ public void invokeHandler_withNullInput() throws IOException {
public void invokeHandler_CompleteSynchronously_returnsSuccess(final String requestDataPath, final String actionAsString)
throws IOException {
final Action action = Action.valueOf(actionAsString);
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = new TestModel();
// if the handler responds Complete, this is treated as a successful synchronous
@@ -456,10 +448,6 @@ public void invokeHandler_DependenciesInitialised_CompleteSynchronously_returnsS
public void invokeHandler_InProgress_returnsInProgress(final String requestDataPath, final String actionAsString)
throws IOException {
final Action action = Action.valueOf(actionAsString);
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = TestModel.builder().property1("abc").property2(123).build();
// an InProgress response is always re-scheduled.
@@ -530,10 +518,6 @@ public void invokeHandler_InProgress_returnsInProgress(final String requestDataP
public void reInvokeHandler_InProgress_returnsInProgress(final String requestDataPath, final String actionAsString)
throws IOException {
final Action action = Action.valueOf(actionAsString);
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = TestModel.builder().property1("abc").property2(123).build();
// an InProgress response is always re-scheduled.
@@ -596,10 +580,6 @@ public void invokeHandler_SchemaValidationFailure(final String requestDataPath,
throws IOException {
final Action action = Action.valueOf(actionAsString);
doThrow(ValidationException.class).when(validator).validateObject(any(JSONObject.class), any(JSONObject.class));
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
wrapper.setTransformResponse(resourceHandlerRequest);
@@ -654,7 +634,7 @@ public void invokeHandler_extraneousModelFields_causesSchemaValidationFailure()
providerLoggingCredentialsProvider, platformEventsLogger,
providerEventsLogger, platformMetricsPublisher,
providerMetricsPublisher, scheduler, new Validator() {
- });
+ }, httpClient);
wrapper.setTransformResponse(resourceHandlerRequest);
@@ -701,10 +681,6 @@ providerMetricsPublisher, scheduler, new Validator() {
@Test
public void invokeHandler_withMalformedRequest_causesSchemaValidationFailure() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = new TestModel();
// an InProgress response is always re-scheduled.
@@ -733,11 +709,6 @@ public void invokeHandler_withMalformedRequest_causesSchemaValidationFailure() t
@Test
public void invokeHandler_withoutPlatformCredentials_returnsFailure() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
// without platform credentials the handler is unable to do
// basic SDK initialization and any such request should fail fast
try (final InputStream in = loadRequestStream("create.request-without-platform-credentials.json");
@@ -756,11 +727,6 @@ public void invokeHandler_withoutPlatformCredentials_returnsFailure() throws IOE
@Test
public void invokeHandler_withoutCallerCredentials_passesNoAWSProxy() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = new TestModel();
model.setProperty1("abc");
model.setProperty2(123);
@@ -791,11 +757,6 @@ public void invokeHandler_withoutCallerCredentials_passesNoAWSProxy() throws IOE
@Test
public void invokeHandler_withDefaultInjection_returnsSuccess() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = new TestModel();
model.setProperty1("abc");
model.setProperty2(123);
@@ -826,11 +787,6 @@ public void invokeHandler_withDefaultInjection_returnsSuccess() throws IOExcepti
@Test
public void invokeHandler_withDefaultInjection_returnsInProgress() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = new TestModel();
model.setProperty1("abc");
model.setProperty2(123);
@@ -857,10 +813,6 @@ public void invokeHandler_withDefaultInjection_returnsInProgress() throws IOExce
@Test
public void invokeHandler_failToRescheduleInvocation() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final TestModel model = new TestModel();
model.setProperty1("abc");
model.setProperty2(123);
@@ -890,11 +842,6 @@ public void invokeHandler_failToRescheduleInvocation() throws IOException {
@Test
public void invokeHandler_clientsRefreshedOnEveryInvoke() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
Context context = getLambdaContext();
try (InputStream in = loadRequestStream("create.request.json"); OutputStream out = new ByteArrayOutputStream()) {
wrapper.handleRequest(in, out, context);
@@ -917,11 +864,6 @@ public void invokeHandler_clientsRefreshedOnEveryInvoke() throws IOException {
@Test
public void invokeHandler_platformCredentialsRefreshedOnEveryInvoke() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
Context context = getLambdaContext();
try (InputStream in = loadRequestStream("create.request.json"); OutputStream out = new ByteArrayOutputStream()) {
wrapper.handleRequest(in, out, context);
@@ -945,11 +887,6 @@ public void invokeHandler_platformCredentialsRefreshedOnEveryInvoke() throws IOE
@Test
public void invokeHandler_withNoResponseEndpoint_returnsFailure() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = new TestModel();
// an InProgress response is always re-scheduled.
@@ -983,11 +920,6 @@ public void invokeHandler_withNoResponseEndpoint_returnsFailure() throws IOExcep
@Test
public void invokeHandler_localReinvokeWithSufficientRemainingTime() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = TestModel.builder().property1("abc").property2(123).build();
// an InProgress response is always re-scheduled.
@@ -1073,11 +1005,6 @@ public void invokeHandler_localReinvokeWithSufficientRemainingTime() throws IOEx
@Test
public void invokeHandler_localReinvokeWithSufficientRemainingTimeForFirstIterationOnly_SchedulesViaCloudWatch()
throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final TestModel model = TestModel.builder().property1("abc").property2(123).build();
// an InProgress response is always re-scheduled.
@@ -1165,13 +1092,6 @@ public void invokeHandler_localReinvokeWithSufficientRemainingTimeForFirstIterat
@Test
public void invokeHandler_throwsAmazonServiceException_returnsServiceException() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
- final TestModel model = new TestModel();
-
// exceptions are caught consistently by LambdaWrapper
wrapper.setInvokeHandlerException(new AmazonServiceException("some error"));
@@ -1216,11 +1136,6 @@ public void invokeHandler_throwsAmazonServiceException_returnsServiceException()
@Test
public void invokeHandler_throwsResourceAlreadyExistsException_returnsAlreadyExists() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
// exceptions are caught consistently by LambdaWrapper
wrapper.setInvokeHandlerException(new ResourceAlreadyExistsException("AWS::Test::TestModel", "id-1234"));
@@ -1265,10 +1180,6 @@ public void invokeHandler_throwsResourceAlreadyExistsException_returnsAlreadyExi
@Test
public void invokeHandler_throwsResourceNotFoundException_returnsNotFound() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
// exceptions are caught consistently by LambdaWrapper
wrapper.setInvokeHandlerException(new ResourceNotFoundException("AWS::Test::TestModel", "id-1234"));
@@ -1313,11 +1224,6 @@ public void invokeHandler_throwsResourceNotFoundException_returnsNotFound() thro
@Test
public void invokeHandler_metricPublisherThrowable_returnsFailureResponse() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
// simulate runtime Errors in the metrics publisher (such as dependency
// resolution conflicts)
doThrow(new Error("not an Exception")).when(platformMetricsPublisher).publishInvocationMetric(any(), any());
@@ -1350,11 +1256,6 @@ public void invokeHandler_metricPublisherThrowable_returnsFailureResponse() thro
@Test
public void invokeHandler_withInvalidPayload_returnsFailureResponse() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
try (final InputStream in = new ByteArrayInputStream(new byte[0]); final OutputStream out = new ByteArrayOutputStream()) {
final Context context = getLambdaContext();
@@ -1373,11 +1274,6 @@ public void invokeHandler_withInvalidPayload_returnsFailureResponse() throws IOE
@Test
public void invokeHandler_withNullInputStream_returnsFailureResponse() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
try (final OutputStream out = new ByteArrayOutputStream()) {
final Context context = getLambdaContext();
@@ -1395,11 +1291,6 @@ public void invokeHandler_withNullInputStream_returnsFailureResponse() throws IO
@Test
public void invokeHandler_withEmptyPayload_returnsFailure() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
try (final InputStream in = loadRequestStream("empty.request.json");
final OutputStream out = new ByteArrayOutputStream()) {
final Context context = getLambdaContext();
@@ -1418,11 +1309,6 @@ public void invokeHandler_withEmptyPayload_returnsFailure() throws IOException {
@Test
public void invokeHandler_withEmptyResourceProperties_returnsFailure() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
try (final InputStream in = loadRequestStream("empty.resource.request.json");
final OutputStream out = new ByteArrayOutputStream()) {
final Context context = getLambdaContext();
@@ -1451,7 +1337,7 @@ public void stringifiedPayload_validation_successful() throws IOException {
final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
providerLoggingCredentialsProvider, platformEventsLogger,
providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
+ providerMetricsPublisher, scheduler, validator, httpClient);
// explicit fault response is treated as an unsuccessful synchronous completion
final ProgressEvent pe = ProgressEvent.builder()
@@ -1475,10 +1361,6 @@ public void stringifiedPayload_validation_successful() throws IOException {
@Test
public void handleRequest_apiThrowsOperationStatusException_returnsFailedStatus() throws IOException {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
final String errorMessage = "Unexpected status";
final OperationStatusCheckFailedException exception = OperationStatusCheckFailedException.builder().message(errorMessage)
.build();
@@ -1514,11 +1396,6 @@ public void handleRequest_apiThrowsOperationStatusException_returnsFailedStatus(
@Test
public void getDesiredResourceTags_oneStackTagAndOneResourceTag() {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final Map stackTags = new HashMap<>();
stackTags.put("Tag1", "Value1");
@@ -1541,11 +1418,6 @@ public void getDesiredResourceTags_oneStackTagAndOneResourceTag() {
@Test
public void getDesiredResourceTags_resourceTagOverridesStackTag() {
- final WrapperOverride wrapper = new WrapperOverride(callbackAdapter, platformCredentialsProvider,
- providerLoggingCredentialsProvider, platformEventsLogger,
- providerEventsLogger, platformMetricsPublisher,
- providerMetricsPublisher, scheduler, validator);
-
final Map stackTags = new HashMap<>();
stackTags.put("Tag1", "Value1");
diff --git a/src/test/java/software/amazon/cloudformation/WrapperOverride.java b/src/test/java/software/amazon/cloudformation/WrapperOverride.java
index 26f030c0..d7087e63 100644
--- a/src/test/java/software/amazon/cloudformation/WrapperOverride.java
+++ b/src/test/java/software/amazon/cloudformation/WrapperOverride.java
@@ -17,7 +17,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.ByteArrayInputStream;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -29,6 +29,7 @@
import org.json.JSONObject;
import org.json.JSONTokener;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.cloudformation.injection.CredentialsProvider;
import software.amazon.cloudformation.loggers.CloudWatchLogPublisher;
import software.amazon.cloudformation.loggers.LogPublisher;
@@ -66,15 +67,17 @@ public WrapperOverride(final CallbackAdapter callbackAdapter,
final MetricsPublisher platformMetricsPublisher,
final MetricsPublisher providerMetricsPublisher,
final CloudWatchScheduler scheduler,
- final SchemaValidator validator) {
+ final SchemaValidator validator,
+ final SdkHttpClient httpClient) {
super(callbackAdapter, platformCredentialsProvider, providerLoggingCredentialsProvider, providerEventsLogger,
- platformEventsLogger, platformMetricsPublisher, providerMetricsPublisher, scheduler, validator, new Serializer());
+ platformEventsLogger, platformMetricsPublisher, providerMetricsPublisher, scheduler, validator, new Serializer(),
+ httpClient);
}
@Override
protected JSONObject provideResourceSchemaJSONObject() {
return new JSONObject(new JSONTokener(new ByteArrayInputStream("{ \"properties\": { \"property1\": { \"type\": \"string\" }, \"property2\": { \"type\": \"integer\" } }, \"additionalProperties\": false }"
- .getBytes(Charset.forName("UTF8")))));
+ .getBytes(StandardCharsets.UTF_8))));
}
@Override
diff --git a/src/test/java/software/amazon/cloudformation/proxy/End2EndCallChainTest.java b/src/test/java/software/amazon/cloudformation/proxy/End2EndCallChainTest.java
index a2a5912b..11dec533 100644
--- a/src/test/java/software/amazon/cloudformation/proxy/End2EndCallChainTest.java
+++ b/src/test/java/software/amazon/cloudformation/proxy/End2EndCallChainTest.java
@@ -42,6 +42,7 @@
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.exception.AwsErrorDetails;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpResponse;
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
import software.amazon.awssdk.services.cloudwatchevents.model.PutRuleRequest;
@@ -227,18 +228,20 @@ public AwsErrorDetails awsErrorDetails() {
};
when(client.describeRepository(eq(describeRequest))).thenThrow(notFound);
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return mock(CloudWatchEventsClient.class);
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
wrapper.handleRequest(stream, output, cxt);
verify(client).describeRepository(eq(describeRequest));
@@ -284,18 +287,20 @@ public void createHandler() throws Exception {
.repoName(model.getRepoName()).repoArn("some-arn").build();
when(client.describeRepository(eq(describeRequest))).thenReturn(describeResponse);
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return mock(CloudWatchEventsClient.class);
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
wrapper.handleRequest(stream, output, cxt);
verify(client).createRepository(eq(createRequest));
@@ -349,18 +354,20 @@ public AwsErrorDetails awsErrorDetails() {
};
when(client.createRepository(eq(createRequest))).thenThrow(exists);
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return mock(CloudWatchEventsClient.class);
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
wrapper.handleRequest(stream, output, cxt);
verify(client).createRepository(eq(createRequest));
@@ -423,18 +430,20 @@ public AwsErrorDetails awsErrorDetails() {
return PutTargetsResponse.builder().build();
});
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return cloudWatchEventsClient;
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
// Bail early for the handshake. Expect cloudwatch events
wrapper.handleRequest(stream, output, cxt);
@@ -494,18 +503,20 @@ public AwsErrorDetails awsErrorDetails() {
};
when(client.describeRepository(eq(describeRequest))).thenThrow(throttleException);
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return mock(CloudWatchEventsClient.class);
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
wrapper.handleRequest(stream, output, cxt);
// only 1 call (1, 0s), the next attempt is at 3s which exceed 50 ms remaining
@@ -555,18 +566,20 @@ public AwsErrorDetails awsErrorDetails() {
};
when(client.describeRepository(eq(describeRequest))).thenThrow(accessDenied);
+ final SdkHttpClient httpClient = mock(SdkHttpClient.class);
final ServiceHandlerWrapper wrapper = new ServiceHandlerWrapper(adapter, platformCredentialsProvider,
providerLoggingCredentialsProvider,
mock(CloudWatchLogPublisher.class),
mock(LogPublisher.class), mock(MetricsPublisher.class),
mock(MetricsPublisher.class),
- new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider) {
+ new CloudWatchScheduler(new CloudWatchEventsProvider(platformCredentialsProvider,
+ httpClient) {
@Override
public CloudWatchEventsClient get() {
return mock(CloudWatchEventsClient.class);
}
}, loggerProxy, serializer), new Validator(), serializer,
- client);
+ client, httpClient);
wrapper.handleRequest(stream, output, cxt);
verify(client).describeRepository(eq(describeRequest));
diff --git a/src/test/java/software/amazon/cloudformation/proxy/handler/ServiceHandlerWrapper.java b/src/test/java/software/amazon/cloudformation/proxy/handler/ServiceHandlerWrapper.java
index d69fbee1..a5f27c67 100644
--- a/src/test/java/software/amazon/cloudformation/proxy/handler/ServiceHandlerWrapper.java
+++ b/src/test/java/software/amazon/cloudformation/proxy/handler/ServiceHandlerWrapper.java
@@ -22,6 +22,7 @@
import org.json.JSONTokener;
import org.mockito.Mockito;
+import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.cloudformation.Action;
import software.amazon.cloudformation.LambdaWrapper;
import software.amazon.cloudformation.injection.CredentialsProvider;
@@ -55,9 +56,11 @@ public ServiceHandlerWrapper(final CallbackAdapter callbackAdapter,
final CloudWatchScheduler scheduler,
final SchemaValidator validator,
final Serializer serializer,
- final ServiceClient client) {
+ final ServiceClient client,
+ final SdkHttpClient httpClient) {
super(callbackAdapter, platformCredentialsProvider, providerLoggingCredentialsProvider, providerEventsLogger,
- platformEventsLogger, platformMetricsPublisher, providerMetricsPublisher, scheduler, validator, serializer);
+ platformEventsLogger, platformMetricsPublisher, providerMetricsPublisher, scheduler, validator, serializer,
+ httpClient);
this.serviceClient = client;
}