Skip to content

Commit

Permalink
Tagging Specific Error Code (#419)
Browse files Browse the repository at this point in the history
  • Loading branch information
ammokhov authored Apr 27, 2023
1 parent a8f97aa commit 95a88be
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 CfnUnauthorizedTaggingOperationException extends BaseHandlerException {

private static final long serialVersionUID = -1646136434112354328L;
private static final HandlerErrorCode ERROR_CODE = HandlerErrorCode.UnauthorizedTaggingOperation;

public CfnUnauthorizedTaggingOperationException() {
this(null);
}

public CfnUnauthorizedTaggingOperationException(final Throwable cause) {
super(ERROR_CODE.getMessage(), cause, ERROR_CODE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

final class ExceptionMessages {
static final String ACCESS_DENIED = "Access denied for operation '%s'.";
static final String UNAUTHORIZED_TAGGING_OPERATION = "Unauthorized tagging operation";
static final String ALREADY_EXISTS = "Resource of type '%s' with identifier '%s' already exists.";
static final String GENERAL_SERVICE_EXCEPTION = "Error occurred during operation '%s'.";
static final String INTERNAL_FAILURE = "Internal error occurred.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public enum HandlerErrorCode {
* the customer has insufficient permissions to perform this action (Terminal)
*/
AccessDenied(ExceptionMessages.ACCESS_DENIED),
/**
* the customer has insufficient permissions to perform tagging
* create/update/delete/read action (Terminal)
*/
UnauthorizedTaggingOperation(ExceptionMessages.UNAUTHORIZED_TAGGING_OPERATION),

/**
* the customer's provided credentials were invalid (Terminal)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
/*
* 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.proxy.delay;

import com.google.common.base.Preconditions;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

Expand All @@ -13,7 +26,10 @@ public class CappedExponential extends MinDelayAbstractBase {

final Duration maxDelay;

CappedExponential(Duration timeout, Duration minDelay, Double powerBy, Duration maxDelay) {
CappedExponential(Duration timeout,
Duration minDelay,
Double powerBy,
Duration maxDelay) {
super(timeout, minDelay);
Preconditions.checkArgument(powerBy >= 1.0, "powerBy >= 1.0");
Preconditions.checkArgument(maxDelay != null && maxDelay.toMillis() >= 0, "maxDelay must be > 0");
Expand All @@ -29,7 +45,7 @@ public static Builder of() {

public static final class Builder extends MinDelayBasedBuilder<CappedExponential, Builder> {
private double powerBy = 2;
private Duration maxDelay =Duration.ofSeconds(20);
private Duration maxDelay = Duration.ofSeconds(20);

public CappedExponential.Builder powerBy(Double powerBy) {
this.powerBy = powerBy;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.Test;
import software.amazon.cloudformation.proxy.HandlerErrorCode;

public class CfnUnauthorizedTaggingOperationExceptionTest {
@Test
public void cfnUnauthorizedTaggingOperation_isBaseHandlerException() {
assertThatExceptionOfType(BaseHandlerException.class).isThrownBy(() -> {
throw new CfnUnauthorizedTaggingOperationException(new RuntimeException());
});
}

@Test
public void cfnUnauthorizedTaggingOperationException_singleArgConstructorHasMessage() {
assertThatExceptionOfType(BaseHandlerException.class).isThrownBy(() -> {
throw new CfnUnauthorizedTaggingOperationException(new RuntimeException());
}).withCauseInstanceOf(RuntimeException.class).withMessageContaining("Unauthorized tagging operation");
}

@Test
public void cfnUnauthorizedTaggingOperationException_noCauseGiven() {
assertThatExceptionOfType(CfnUnauthorizedTaggingOperationException.class).isThrownBy(() -> {
throw new CfnUnauthorizedTaggingOperationException();
}).withNoCause().withMessageContaining("Unauthorized tagging operation");
}

@Test
public void cfnUnauthorizedTaggingOperationException_errorCodeIsAppropriate() {
assertThatExceptionOfType(CfnUnauthorizedTaggingOperationException.class).isThrownBy(() -> {
throw new CfnUnauthorizedTaggingOperationException(new RuntimeException());
}).satisfies(exception -> assertEquals(HandlerErrorCode.UnauthorizedTaggingOperation, exception.getErrorCode()));
}
}
23 changes: 8 additions & 15 deletions src/test/java/software/amazon/cloudformation/proxy/DelayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,9 @@ public void exponentialDelays() {
@Test
public void cappedExponentialDelays() {
Duration MAX_DELAY = Duration.ofSeconds(15);
final Delay cappedExponential = CappedExponential.of()
.timeout(Duration.ofMinutes(20))
.maxDelay(MAX_DELAY)
.powerBy(1.3)
.minDelay(Duration.ofSeconds(1))
.build();
int[] results = {1, 1, 1, 1, 2, 2, 3, 4, 6, 8, 10, 13, 15, 15, 15, 15};
final Delay cappedExponential = CappedExponential.of().timeout(Duration.ofMinutes(20)).maxDelay(MAX_DELAY).powerBy(1.3)
.minDelay(Duration.ofSeconds(1)).build();
int[] results = { 1, 1, 1, 1, 2, 2, 3, 4, 6, 8, 10, 13, 15, 15, 15, 15 };
for (int tries = 0; tries <= 15; tries++) {
Duration delay = cappedExponential.nextDelay(tries);
assertThat(results[tries]).isEqualTo((int) delay.getSeconds());
Expand All @@ -218,7 +214,7 @@ public void cappedExponentialDelays() {
}
}

//If minDelay is not set, the retry is without delay.
// If minDelay is not set, the retry is without delay.
final Delay cappedExponentialNoDelay = CappedExponential.of().timeout(Duration.ofSeconds(12)).build();
for (int tries = 0; tries <= 15; tries++) {
Duration delay = cappedExponentialNoDelay.nextDelay(tries);
Expand All @@ -228,14 +224,11 @@ public void cappedExponentialDelays() {
}
}

//If powerBy is not passed, it's set to default 2.
final Delay cappedExponentialNoPower = CappedExponential.of()
.timeout(Duration.ofMinutes(20))
.maxDelay(MAX_DELAY)
.minDelay(Duration.ofSeconds(1))
.build();
// If powerBy is not passed, it's set to default 2.
final Delay cappedExponentialNoPower = CappedExponential.of().timeout(Duration.ofMinutes(20)).maxDelay(MAX_DELAY)
.minDelay(Duration.ofSeconds(1)).build();

int[] resultsNoPower = {1, 1, 2, 4, 8, 15, 15, 15, 15, 15};
int[] resultsNoPower = { 1, 1, 2, 4, 8, 15, 15, 15, 15, 15 };
for (int tries = 0; tries <= 6; tries++) {
Duration delay = cappedExponentialNoPower.nextDelay(tries);
assertThat(resultsNoPower[tries]).isEqualTo((int) delay.getSeconds());
Expand Down

0 comments on commit 95a88be

Please sign in to comment.