diff --git a/src/main/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetException.java b/src/main/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetException.java new file mode 100644 index 00000000..b84e29bf --- /dev/null +++ b/src/main/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetException.java @@ -0,0 +1,38 @@ +/* +* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file 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 software.amazon.cloudformation.exceptions; + +import software.amazon.cloudformation.proxy.HandlerErrorCode; + +public class CfnUnsupportedTargetException extends BaseHandlerException { + + private static final long serialVersionUID = -1646136434112354328L; + private static final HandlerErrorCode ERROR_CODE = HandlerErrorCode.UnsupportedTarget; + + public CfnUnsupportedTargetException(final Throwable cause) { + super(cause, ERROR_CODE); + } + + public CfnUnsupportedTargetException(final String hookTypeName, + final String targetTypeName) { + this(hookTypeName, targetTypeName, null); + } + + public CfnUnsupportedTargetException(final String hookTypeName, + final String targetTypeName, + final Throwable cause) { + super(String.format(ERROR_CODE.getMessage(), hookTypeName, targetTypeName), cause, ERROR_CODE); + } +} diff --git a/src/main/java/software/amazon/cloudformation/exceptions/UnsupportedTargetException.java b/src/main/java/software/amazon/cloudformation/exceptions/UnsupportedTargetException.java index 9e53c604..c5bdf223 100644 --- a/src/main/java/software/amazon/cloudformation/exceptions/UnsupportedTargetException.java +++ b/src/main/java/software/amazon/cloudformation/exceptions/UnsupportedTargetException.java @@ -14,6 +14,12 @@ */ package software.amazon.cloudformation.exceptions; +/** + * Uses for this exception class should delegate instead to + * CfnUnsupportedTargetException as it maps to UnsupportedTarget error code. + * This deprecated exception maps to an InvalidRequest error code. Keeping the + * same for backwards-compatibility + */ public class UnsupportedTargetException extends CfnInvalidRequestException { private static final long serialVersionUID = -1646136434112354328L; diff --git a/src/main/java/software/amazon/cloudformation/proxy/ExceptionMessages.java b/src/main/java/software/amazon/cloudformation/proxy/ExceptionMessages.java index 5c6931d4..8de9d061 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/ExceptionMessages.java +++ b/src/main/java/software/amazon/cloudformation/proxy/ExceptionMessages.java @@ -32,6 +32,7 @@ final class ExceptionMessages { static final String INVALID_TYPECONFIGURATION = "Invalid TypeConfiguration provided for type '%s'. Reason: %s"; static final String HANDLER_INTERNAL_FAILURE = "Internal error occurred in the handler."; static final String NON_COMPLIANT = "Hook of type '%s' returned a Non-Complaint status. Reason %s"; + static final String UNSUPPORTED_TARGET = "Hook of type '%s' received request for unsupported target '%s'."; static final String UNKNOWN = "Unknown error occurred."; private ExceptionMessages() { diff --git a/src/main/java/software/amazon/cloudformation/proxy/HandlerErrorCode.java b/src/main/java/software/amazon/cloudformation/proxy/HandlerErrorCode.java index 1c4061b3..18337ca7 100644 --- a/src/main/java/software/amazon/cloudformation/proxy/HandlerErrorCode.java +++ b/src/main/java/software/amazon/cloudformation/proxy/HandlerErrorCode.java @@ -119,6 +119,13 @@ public enum HandlerErrorCode { */ NonCompliant(ExceptionMessages.NON_COMPLIANT), + /** + * The specified target in the hook request is not supported. Applicable when + * hook has wildcard targets. Hook wildcard may be matched to target that hook + * did not support at time of registration + */ + UnsupportedTarget(ExceptionMessages.UNSUPPORTED_TARGET), + /** * the Hook has returned a failure for an Unknown reason. Only applicable to * Hook type handlers (terminal) Hook Handlers can return this when a hook has diff --git a/src/test/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetExceptionTests.java b/src/test/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetExceptionTests.java new file mode 100644 index 00000000..608173b7 --- /dev/null +++ b/src/test/java/software/amazon/cloudformation/exceptions/CfnUnsupportedTargetExceptionTests.java @@ -0,0 +1,64 @@ +/* +* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the "license" file accompanying this file. This file 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 software.amazon.cloudformation.exceptions; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.cloudformation.proxy.HandlerErrorCode; + +public class CfnUnsupportedTargetExceptionTests { + private static final String HOOK_TYPE = "AWS::Hook::Type"; + private static final String UNSUPPORTED_TYPE = "AWS::Service::Resource"; + private static final String STATUS = "unsupported target"; + private static final String ERROR_MESSAGE = "something wrong"; + + @Test + public void cfnUnsupportedTargetException_isBaseHandlerException() { + assertThatExceptionOfType(BaseHandlerException.class).isThrownBy(() -> { + throw new CfnUnsupportedTargetException(HOOK_TYPE, UNSUPPORTED_TYPE, new RuntimeException()); + }).withCauseInstanceOf(RuntimeException.class).withMessageContaining(HOOK_TYPE).withMessageContaining(UNSUPPORTED_TYPE) + .withMessageContaining(STATUS); + } + + @Test + public void cfnUnsupportedTargetException_singleArgsConstructorHasNoMessage() { + assertThatExceptionOfType(CfnUnsupportedTargetException.class).isThrownBy(() -> { + throw new CfnUnsupportedTargetException(new RuntimeException()); + }).withCauseInstanceOf(RuntimeException.class).withMessage(null); + } + + @Test + public void cfnUnsupportedTargetException_noCauseGiven() { + assertThatExceptionOfType(CfnUnsupportedTargetException.class).isThrownBy(() -> { + throw new CfnUnsupportedTargetException(HOOK_TYPE, UNSUPPORTED_TYPE); + }).withNoCause().withMessageContaining(HOOK_TYPE).withMessageContaining(UNSUPPORTED_TYPE).withMessageContaining(STATUS); + } + + @Test + public void cfnUnsupportedTargetException_errorCodeIsAppropriate() { + assertThatExceptionOfType(CfnUnsupportedTargetException.class).isThrownBy(() -> { + throw new CfnUnsupportedTargetException(new RuntimeException()); + }).satisfies(exception -> Assertions.assertEquals(HandlerErrorCode.UnsupportedTarget, exception.getErrorCode())); + } + + @Test + public void cfnUnsupportedTargetException_errorMessage() { + assertThatExceptionOfType(CfnUnsupportedTargetException.class).isThrownBy(() -> { + throw new CfnUnsupportedTargetException(new RuntimeException(ERROR_MESSAGE)); + }).satisfies(exception -> Assertions.assertEquals(ERROR_MESSAGE, exception.getMessage())); + } + +}