diff --git a/pom.xml b/pom.xml index 7b20ea8b..b3e087fa 100644 --- a/pom.xml +++ b/pom.xml @@ -295,7 +295,7 @@ - com,edu,java,lombok,javax,org,software + com,edu,java,javax,lombok,org,software diff --git a/src/main/java/software/amazon/cloudformation/AbstractWrapper.java b/src/main/java/software/amazon/cloudformation/AbstractWrapper.java index 8bedfad1..94bc2578 100644 --- a/src/main/java/software/amazon/cloudformation/AbstractWrapper.java +++ b/src/main/java/software/amazon/cloudformation/AbstractWrapper.java @@ -326,7 +326,8 @@ public void processRequest(final InputStream inputStream, final OutputStream out if (request.getRequestData().getCallerCredentials() != null) { awsClientProxy = new AmazonWebServicesClientProxy(this.loggerProxy, request.getRequestData().getCallerCredentials(), DelayFactory.CONSTANT_DEFAULT_DELAY_FACTORY, - WaitStrategy.scheduleForCallbackStrategy()); + WaitStrategy.scheduleForCallbackStrategy(), + request.getStackId() != null); } ProgressEvent handlerResponse = wrapInvocationAndHandleErrors(awsClientProxy, diff --git a/src/main/java/software/amazon/cloudformation/HookAbstractWrapper.java b/src/main/java/software/amazon/cloudformation/HookAbstractWrapper.java index cbe7b244..58218992 100644 --- a/src/main/java/software/amazon/cloudformation/HookAbstractWrapper.java +++ b/src/main/java/software/amazon/cloudformation/HookAbstractWrapper.java @@ -249,7 +249,7 @@ private ProgressEvent processInvocation(final JSONObject raw if (processedCallerCredentials != null) { awsClientProxy = new AmazonWebServicesClientProxy(this.loggerProxy, processedCallerCredentials, DelayFactory.CONSTANT_DEFAULT_DELAY_FACTORY, - WaitStrategy.scheduleForCallbackStrategy()); + WaitStrategy.scheduleForCallbackStrategy(), true); } diff --git a/src/main/java/software/amazon/cloudformation/proxy/AmazonWebServicesClientProxy.java b/src/main/java/software/amazon/cloudformation/proxy/AmazonWebServicesClientProxy.java index 420b1cbf..a33fb8bd 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/AmazonWebServicesClientProxy.java +++ b/src/main/java/software/amazon/cloudformation/proxy/AmazonWebServicesClientProxy.java @@ -31,6 +31,8 @@ import java.util.function.Function; import java.util.function.Supplier; import javax.annotation.Nonnull; +import lombok.Getter; +import lombok.Setter; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; @@ -66,6 +68,9 @@ public class AmazonWebServicesClientProxy implements CallChain { private final LoggerProxy loggerProxy; private final DelayFactory override; private final WaitStrategy waitStrategy; + @Getter + @Setter + private Boolean invokedByCfn; public AmazonWebServicesClientProxy(final LoggerProxy loggerProxy, final Credentials credentials, @@ -77,13 +82,14 @@ public AmazonWebServicesClientProxy(final LoggerProxy loggerProxy, final Credentials credentials, final Supplier remainingTimeToExecute, final DelayFactory override) { - this(loggerProxy, credentials, override, WaitStrategy.newLocalLoopAwaitStrategy(remainingTimeToExecute)); + this(loggerProxy, credentials, override, WaitStrategy.newLocalLoopAwaitStrategy(remainingTimeToExecute), null); } public AmazonWebServicesClientProxy(final LoggerProxy loggerProxy, final Credentials credentials, final DelayFactory override, - final WaitStrategy waitStrategy) { + final WaitStrategy waitStrategy, + final Boolean invokedByCfn) { this.loggerProxy = loggerProxy; BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), @@ -95,6 +101,7 @@ public AmazonWebServicesClientProxy(final LoggerProxy loggerProxy, this.v2CredentialsProvider = StaticCredentialsProvider.create(awsSessionCredentials); this.override = Objects.requireNonNull(override); this.waitStrategy = Objects.requireNonNull(waitStrategy); + this.invokedByCfn = invokedByCfn; } public ProxyClient newProxy(@Nonnull Supplier client) { @@ -331,6 +338,15 @@ public Completed handleError(Ex do { try { event = inner.invoke(request, ex, client_, model_, context_); + + // + // Ensure that we null out model for AlreadyExists to meet CFN IaC expectations + // + if (event.getErrorCode() == HandlerErrorCode.AlreadyExists + && AmazonWebServicesClientProxy.this.invokedByCfn) { + event.setResourceModel(null); + } + } catch (RetryableException e) { break; } catch (Exception e) { diff --git a/src/main/java/software/amazon/cloudformation/proxy/hook/targetmodel/HookTargetModel.java b/src/main/java/software/amazon/cloudformation/proxy/hook/targetmodel/HookTargetModel.java index 89b1a9d8..b5dfcafe 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/hook/targetmodel/HookTargetModel.java +++ b/src/main/java/software/amazon/cloudformation/proxy/hook/targetmodel/HookTargetModel.java @@ -25,11 +25,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import javax.annotation.CheckForNull; import lombok.AccessLevel; import lombok.Data; import lombok.NonNull; import lombok.Setter; -import javax.annotation.CheckForNull; import org.json.JSONObject; import software.amazon.cloudformation.resource.Serializer;