From a095cb66db0f5696e67122578e5daa4850ce3feb Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Mon, 26 Apr 2021 17:55:05 -0400 Subject: [PATCH 01/12] Add client configuration resources --- .../ClientConfiguration.java | 28 ++++ ...ClientConfigurationDirectiveProcessor.java | 94 ++++++++++++ .../ClientConfigurationInterface.java | 6 + .../ClientConfigurationSettings.java | 23 +++ .../ClientConfigurationUtils.java | 34 +++++ .../ClientOverrideConfiguration.java | 47 ++++++ .../HttpClientConfiguration.java | 144 ++++++++++++++++++ .../retrypolicy/RetryPolicy.java | 103 +++++++++++++ .../backoffstrategies/BackoffStrategy.java | 58 +++++++ .../BackoffStrategyInterface.java | 8 + .../backoffstrategies/EqualJitter.java | 42 +++++ .../backoffstrategies/FixedDelay.java | 29 ++++ .../backoffstrategies/FullJitter.java | 42 +++++ .../ThrottlingBackoffStrategy.java | 58 +++++++ .../retryconditions/AndRetryCondition.java | 62 ++++++++ .../CapacityRetryCondition.java | 106 +++++++++++++ .../MaxNumberOfRetryCondition.java | 31 ++++ .../retryconditions/OrRetryCondition.java | 62 ++++++++ .../retryconditions/RetryCondition.java | 106 +++++++++++++ .../RetryConditionInterface.java | 8 + .../RetryOnErrorCodesCondition.java | 34 +++++ .../RetryOnStatusCodesCondition.java | 35 +++++ .../RetryOnThrottlingCondition.java | 17 +++ 23 files changed, 1177 insertions(+) create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java new file mode 100644 index 000000000..6b18de2ae --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java @@ -0,0 +1,28 @@ +package gyro.aws.clientconfiguration; + +public class ClientConfiguration implements ClientConfigurationInterface { + + private ClientOverrideConfiguration overrideConfiguration; + private HttpClientConfiguration httpClientConfiguration; + + public ClientOverrideConfiguration getOverrideConfiguration() { + return overrideConfiguration; + } + + public void setOverrideConfiguration(ClientOverrideConfiguration overrideConfiguration) { + this.overrideConfiguration = overrideConfiguration; + } + + public HttpClientConfiguration getHttpClientConfiguration() { + return httpClientConfiguration; + } + + public void setHttpClientConfiguration(HttpClientConfiguration httpClientConfiguration) { + this.httpClientConfiguration = httpClientConfiguration; + } + + @Override + public void validate() { + + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java new file mode 100644 index 000000000..aae5c1e4e --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -0,0 +1,94 @@ +package gyro.aws.clientconfiguration; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import com.google.common.base.CaseFormat; +import com.psddev.dari.util.ObjectUtils; +import gyro.core.Reflections; +import gyro.core.Type; +import gyro.core.directive.DirectiveProcessor; +import gyro.core.scope.RootScope; +import gyro.core.scope.Scope; +import gyro.lang.ast.block.DirectiveNode; +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +@Type("client-configuration") +public class ClientConfigurationDirectiveProcessor extends DirectiveProcessor { + + @Override + public void process(RootScope scope, DirectiveNode node) throws Exception { + validateArguments(node, 0, 1); + + String name = getArgument(scope, node, String.class, 0); + + if (ObjectUtils.isBlank(name)) { + name = "default"; + } + + Scope bodyScope = evaluateBody(scope, node); + + ClientConfigurationSettings settings = scope.getSettings(ClientConfigurationSettings.class); + + ClientConfiguration clientConfiguration = (ClientConfiguration) process( + ClientConfiguration.class, + scope, + bodyScope); + + settings.getClientConfigurations().put(name, clientConfiguration); + } + + private Object process(Class configClass, RootScope scope, Scope bodyScope) { + Object configClassObj = Reflections.newInstance(configClass); + if (bodyScope != null) { + for (PropertyDescriptor property : Reflections.getBeanInfo(configClass).getPropertyDescriptors()) { + Method setter = property.getWriteMethod(); + if (setter != null) { + java.lang.reflect.Type genericParameterType = setter.getGenericParameterTypes()[0]; + Object configVal = bodyScope.get(CaseFormat.LOWER_CAMEL.to( + CaseFormat.LOWER_HYPHEN, + property.getName())); + + if (genericParameterType.getTypeName().contains("gyro")) { + if (configVal instanceof List) { + if (genericParameterType.getTypeName().contains("java.util.List")) { + if (genericParameterType instanceof ParameterizedTypeImpl) { + List configVals = (List) configVal; + List processedConfigs = new ArrayList<>(); + for (Object obj : configVals) { + if (obj instanceof Scope) { + processedConfigs.add(process( + (Class) ((ParameterizedTypeImpl) genericParameterType).getActualTypeArguments()[0], + scope, + (Scope) obj)); + } + } + configVal = processedConfigs; + } + } else if (((List) configVal).size() > 0) { + Object obj = ((List) configVal).get(0); + if (obj instanceof Scope) { + configVal = process(setter.getParameterTypes()[0], scope, (Scope) obj); + } + } + } + } + + if (configVal != null) { + Reflections.invoke(setter, configClassObj, scope.convertValue( + setter.getGenericParameterTypes()[0], + configVal)); + } + } + } + } + + if (ClientConfigurationInterface.class.isAssignableFrom(configClass)) { + ((ClientConfigurationInterface) configClassObj).validate(); + } + + return configClassObj; + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java new file mode 100644 index 000000000..c4713f62c --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java @@ -0,0 +1,6 @@ +package gyro.aws.clientconfiguration; + +public interface ClientConfigurationInterface { + + void validate(); +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java new file mode 100644 index 000000000..aec582b95 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java @@ -0,0 +1,23 @@ +package gyro.aws.clientconfiguration; + +import java.util.HashMap; +import java.util.Map; + +import gyro.core.scope.Settings; + +public class ClientConfigurationSettings extends Settings { + + private Map clientConfigurations; + + public Map getClientConfigurations() { + if (clientConfigurations == null) { + clientConfigurations = new HashMap<>(); + } + + return clientConfigurations; + } + + public void setClientConfigurations(Map clientConfigurations) { + this.clientConfigurations = clientConfigurations; + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java new file mode 100644 index 000000000..b15d14810 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java @@ -0,0 +1,34 @@ +package gyro.aws.clientconfiguration; + +import java.time.Duration; +import java.time.format.DateTimeParseException; + +import com.google.common.base.Preconditions; +import com.psddev.dari.util.ObjectUtils; +import gyro.core.GyroException; + +public class ClientConfigurationUtils { + + private static long parse(String duration) { + Preconditions.checkNotNull(duration); + + duration = (duration.startsWith("PT") ? duration : "PT" + duration).toUpperCase(); + + return Duration.parse(duration).getSeconds(); + } + + public static Duration getDuration(String duration) { + return Duration.ofSeconds(parse(duration)); + } + + public static void validate(String duration, String fieldName, String parent) { + try { + parse(duration); + } catch (DateTimeParseException ex) { + throw new GyroException(String.format( + "%s'%s's time format '" + duration + "' is invalid.", + (ObjectUtils.isBlank(parent) ? "" : String.format("%s: ", parent)), + fieldName)); + } + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java new file mode 100644 index 000000000..e79135a1a --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java @@ -0,0 +1,47 @@ +package gyro.aws.clientconfiguration; + +import gyro.aws.clientconfiguration.retrypolicy.RetryPolicy; + +public class ClientOverrideConfiguration implements ClientConfigurationInterface { + + private String apiCallTimeout; + private RetryPolicy retryPolicy; + + public String getApiCallTimeout() { + return apiCallTimeout; + } + + public void setApiCallTimeout(String apiCallTimeout) { + this.apiCallTimeout = apiCallTimeout; + } + + public RetryPolicy getRetryPolicy() { + return retryPolicy; + } + + public void setRetryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + } + + @Override + public void validate() { + if (getApiCallTimeout() != null) { + ClientConfigurationUtils.validate(getApiCallTimeout(), "api-call-timeout", "client-override-configuration"); + } + } + + public software.amazon.awssdk.core.client.config.ClientOverrideConfiguration toClientOverrideConfiguration() { + software.amazon.awssdk.core.client.config.ClientOverrideConfiguration.Builder builder = software.amazon.awssdk.core.client.config.ClientOverrideConfiguration + .builder(); + + if (getApiCallTimeout() != null) { + builder.apiCallTimeout(ClientConfigurationUtils.getDuration(getApiCallTimeout())); + } + + if (getRetryPolicy() != null) { + builder.retryPolicy(getRetryPolicy().toRetryPolicy()); + } + + return builder.build(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java new file mode 100644 index 000000000..b39d98028 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java @@ -0,0 +1,144 @@ +package gyro.aws.clientconfiguration; + +import gyro.core.GyroException; +import software.amazon.awssdk.http.apache.ApacheHttpClient; + +public class HttpClientConfiguration implements ClientConfigurationInterface { + + private String connectionAcquisitionTimeout; + private String connectionTimeout; + private String connectionTimeToLive; + private String connectionMaxIdleTime; + private Boolean expectContinueEnabled; + private Integer maxConnections; + private String socketTimeout; + + public String getConnectionAcquisitionTimeout() { + return connectionAcquisitionTimeout; + } + + public void setConnectionAcquisitionTimeout(String connectionAcquisitionTimeout) { + this.connectionAcquisitionTimeout = connectionAcquisitionTimeout; + } + + public String getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(String connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public String getConnectionTimeToLive() { + return connectionTimeToLive; + } + + public void setConnectionTimeToLive(String connectionTimeToLive) { + this.connectionTimeToLive = connectionTimeToLive; + } + + public String getConnectionMaxIdleTime() { + return connectionMaxIdleTime; + } + + public void setConnectionMaxIdleTime(String connectionMaxIdleTime) { + this.connectionMaxIdleTime = connectionMaxIdleTime; + } + + public Boolean getExpectContinueEnabled() { + return expectContinueEnabled; + } + + public void setExpectContinueEnabled(Boolean expectContinueEnabled) { + this.expectContinueEnabled = expectContinueEnabled; + } + + public Integer getMaxConnections() { + return maxConnections; + } + + public void setMaxConnections(Integer maxConnections) { + this.maxConnections = maxConnections; + } + + public String getSocketTimeout() { + return socketTimeout; + } + + public void setSocketTimeout(String socketTimeout) { + this.socketTimeout = socketTimeout; + } + + @Override + public void validate() { + if (getConnectionAcquisitionTimeout() != null) { + ClientConfigurationUtils.validate( + getConnectionAcquisitionTimeout(), + "connection-acquisition-timeout", + "http-client-configuration"); + } + + if (getConnectionTimeout() != null) { + ClientConfigurationUtils.validate( + getConnectionTimeout(), + "connection-timeout", + "http-client-configuration"); + } + + if (getConnectionTimeToLive() != null) { + ClientConfigurationUtils.validate( + getConnectionTimeToLive(), + "connection-time-to-live", + "http-client-configuration"); + } + + if (getConnectionMaxIdleTime() != null) { + ClientConfigurationUtils.validate( + getConnectionMaxIdleTime(), + "connection-max-idle-time", + "http-client-configuration"); + } + + if (getSocketTimeout() != null) { + ClientConfigurationUtils.validate(getSocketTimeout(), "socket-timeout", "http-client-configuration"); + } + + if (getMaxConnections() != null && getMaxConnections() < 1) { + throw new GyroException("'max-connections' if specified cannot be less than 1."); + } + } + + public ApacheHttpClient.Builder toApacheHttpClient() { + ApacheHttpClient.Builder builder = ApacheHttpClient.builder(); + + if (getConnectionAcquisitionTimeout() != null) { + builder.connectionAcquisitionTimeout(ClientConfigurationUtils.getDuration(getConnectionAcquisitionTimeout())); + } + + if (getConnectionTimeout() != null) { + builder.connectionTimeout(ClientConfigurationUtils.getDuration(getConnectionTimeout())); + } + + if (getConnectionTimeToLive() != null) { + builder = builder.connectionMaxIdleTime(ClientConfigurationUtils.getDuration(getConnectionTimeToLive())); + } + + if (getConnectionMaxIdleTime() != null) { + builder = builder.connectionMaxIdleTime(ClientConfigurationUtils.getDuration(getConnectionMaxIdleTime())); + } + + if (getSocketTimeout() != null) { + builder = builder.socketTimeout(ClientConfigurationUtils.getDuration(getSocketTimeout())); + } + + if (getExpectContinueEnabled() != null) { + builder = builder.expectContinueEnabled(getExpectContinueEnabled()); + } + + if (getMaxConnections() != null) { + builder = builder.maxConnections(getMaxConnections()); + } + + return builder; + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java new file mode 100644 index 000000000..01c1bb1f7 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java @@ -0,0 +1,103 @@ +package gyro.aws.clientconfiguration.retrypolicy; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.aws.clientconfiguration.retrypolicy.backoffstrategies.BackoffStrategy; +import gyro.aws.clientconfiguration.retrypolicy.backoffstrategies.ThrottlingBackoffStrategy; +import gyro.aws.clientconfiguration.retrypolicy.retryconditions.CapacityRetryCondition; +import gyro.aws.clientconfiguration.retrypolicy.retryconditions.RetryCondition; +import gyro.core.GyroException; + +public class RetryPolicy implements ClientConfigurationInterface { + + private Integer retryCount; + private Boolean additionalRetryConditionsAllowed; + private BackoffStrategy backoffStrategy; + private ThrottlingBackoffStrategy throttlingBackoffStrategy; + private RetryCondition retryCondition; + private CapacityRetryCondition capacityRetryCondition; + + public Integer getRetryCount() { + return retryCount; + } + + public void setRetryCount(Integer retryCount) { + this.retryCount = retryCount; + } + + public Boolean getAdditionalRetryConditionsAllowed() { + return additionalRetryConditionsAllowed; + } + + public void setAdditionalRetryConditionsAllowed(Boolean additionalRetryConditionsAllowed) { + this.additionalRetryConditionsAllowed = additionalRetryConditionsAllowed; + } + + public BackoffStrategy getBackoffStrategy() { + return backoffStrategy; + } + + public void setBackoffStrategy(BackoffStrategy backoffStrategy) { + this.backoffStrategy = backoffStrategy; + } + + public ThrottlingBackoffStrategy getThrottlingBackoffStrategy() { + return throttlingBackoffStrategy; + } + + public void setThrottlingBackoffStrategy(ThrottlingBackoffStrategy throttlingBackoffStrategy) { + this.throttlingBackoffStrategy = throttlingBackoffStrategy; + } + + public RetryCondition getRetryCondition() { + return retryCondition; + } + + public void setRetryCondition(RetryCondition retryCondition) { + this.retryCondition = retryCondition; + } + + public CapacityRetryCondition getCapacityRetryCondition() { + return capacityRetryCondition; + } + + public void setCapacityRetryCondition(CapacityRetryCondition capacityRetryCondition) { + this.capacityRetryCondition = capacityRetryCondition; + } + + @Override + public void validate() { + if (getRetryCount() != null && getRetryCount() < 0) { + throw new GyroException("'retry-count' cannot be less than 1."); + } + } + + public software.amazon.awssdk.core.retry.RetryPolicy toRetryPolicy() { + software.amazon.awssdk.core.retry.RetryPolicy.Builder builder = software.amazon.awssdk.core.retry.RetryPolicy.builder(); + + if (getRetryCount() != null) { + builder = builder.numRetries(getRetryCount()); + } + + if (getAdditionalRetryConditionsAllowed() != null) { + builder = builder.additionalRetryConditionsAllowed(getAdditionalRetryConditionsAllowed()); + } + + if (getBackoffStrategy() != null) { + builder = builder.backoffStrategy(getBackoffStrategy().toBackoffStrategy()); + } + + if (getThrottlingBackoffStrategy() != null) { + builder = builder.throttlingBackoffStrategy(getThrottlingBackoffStrategy().toBackoffStrategy()); + } + + if (getRetryCondition() != null) { + builder = builder.retryCondition(getRetryCondition().toRetryCondition()); + } + + if (getCapacityRetryCondition() != null) { + builder = builder.retryCapacityCondition(getCapacityRetryCondition().toRetryCondition()); + } + + return builder.build(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java new file mode 100644 index 000000000..1a265ffa6 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java @@ -0,0 +1,58 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; + +public class BackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { + + private FixedDelay fixedDelay; + private FullJitter fullJitter; + private EqualJitter equalJitter; + + public FixedDelay getFixedDelay() { + return fixedDelay; + } + + public void setFixedDelay(FixedDelay fixedDelay) { + this.fixedDelay = fixedDelay; + } + + public FullJitter getFullJitter() { + return fullJitter; + } + + public void setFullJitter(FullJitter fullJitter) { + this.fullJitter = fullJitter; + } + + public EqualJitter getEqualJitter() { + return equalJitter; + } + + public void setEqualJitter(EqualJitter equalJitter) { + this.equalJitter = equalJitter; + } + + @Override + public void validate() { + long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); + + if (count > 1) { + throw new GyroException("Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); + } else if (count == 0) { + throw new GyroException("One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); + } + } + + @Override + public software.amazon.awssdk.core.retry.backoff.BackoffStrategy toBackoffStrategy() { + return Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()) + .filter(Objects::nonNull) + .findFirst() + .get() + .toBackoffStrategy(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java new file mode 100644 index 000000000..0413af9e2 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java @@ -0,0 +1,8 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import software.amazon.awssdk.core.retry.backoff.BackoffStrategy; + +public interface BackoffStrategyInterface { + + BackoffStrategy toBackoffStrategy(); +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java new file mode 100644 index 000000000..3a7435340 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java @@ -0,0 +1,42 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.aws.clientconfiguration.ClientConfigurationUtils; +import software.amazon.awssdk.core.retry.backoff.BackoffStrategy; +import software.amazon.awssdk.core.retry.backoff.EqualJitterBackoffStrategy; + +public class EqualJitter implements BackoffStrategyInterface, ClientConfigurationInterface { + + private String baseDelay; + private String maxBackoffTime; + + public String getBaseDelay() { + return baseDelay; + } + + public void setBaseDelay(String baseDelay) { + this.baseDelay = baseDelay; + } + + public String getMaxBackoffTime() { + return maxBackoffTime; + } + + public void setMaxBackoffTime(String maxBackoffTime) { + this.maxBackoffTime = maxBackoffTime; + } + + @Override + public void validate() { + ClientConfigurationUtils.validate(getBaseDelay(), "base-delay", "equal-jitter"); + ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time", "equal-jitter"); + } + + @Override + public BackoffStrategy toBackoffStrategy() { + return EqualJitterBackoffStrategy.builder() + .maxBackoffTime(ClientConfigurationUtils.getDuration(getMaxBackoffTime())) + .baseDelay(ClientConfigurationUtils.getDuration(getBaseDelay())) + .build(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java new file mode 100644 index 000000000..8da35d707 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java @@ -0,0 +1,29 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.aws.clientconfiguration.ClientConfigurationUtils; +import software.amazon.awssdk.core.retry.backoff.BackoffStrategy; +import software.amazon.awssdk.core.retry.backoff.FixedDelayBackoffStrategy; + +public class FixedDelay implements BackoffStrategyInterface, ClientConfigurationInterface { + + private String delay; + + public String getDelay() { + return delay; + } + + public void setDelay(String delay) { + this.delay = delay; + } + + @Override + public void validate() { + ClientConfigurationUtils.validate(getDelay(), "delay", "fixed-delay"); + } + + @Override + public BackoffStrategy toBackoffStrategy() { + return FixedDelayBackoffStrategy.create(ClientConfigurationUtils.getDuration(getDelay())); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java new file mode 100644 index 000000000..f65e93e48 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java @@ -0,0 +1,42 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.aws.clientconfiguration.ClientConfigurationUtils; +import software.amazon.awssdk.core.retry.backoff.BackoffStrategy; +import software.amazon.awssdk.core.retry.backoff.FullJitterBackoffStrategy; + +public class FullJitter implements BackoffStrategyInterface, ClientConfigurationInterface { + + private String baseDelay; + private String maxBackoffTime; + + public String getBaseDelay() { + return baseDelay; + } + + public void setBaseDelay(String baseDelay) { + this.baseDelay = baseDelay; + } + + public String getMaxBackoffTime() { + return maxBackoffTime; + } + + public void setMaxBackoffTime(String maxBackoffTime) { + this.maxBackoffTime = maxBackoffTime; + } + + @Override + public void validate() { + ClientConfigurationUtils.validate(getBaseDelay(), "base-delay", "full-jitter"); + ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time", "full-jitter"); + } + + @Override + public BackoffStrategy toBackoffStrategy() { + return FullJitterBackoffStrategy.builder() + .maxBackoffTime(ClientConfigurationUtils.getDuration(getMaxBackoffTime())) + .baseDelay(ClientConfigurationUtils.getDuration(getBaseDelay())) + .build(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java new file mode 100644 index 000000000..65d2e50d9 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java @@ -0,0 +1,58 @@ +package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; + +public class ThrottlingBackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { + + private FixedDelay fixedDelay; + private FullJitter fullJitter; + private EqualJitter equalJitter; + + public FixedDelay getFixedDelay() { + return fixedDelay; + } + + public void setFixedDelay(FixedDelay fixedDelay) { + this.fixedDelay = fixedDelay; + } + + public FullJitter getFullJitter() { + return fullJitter; + } + + public void setFullJitter(FullJitter fullJitter) { + this.fullJitter = fullJitter; + } + + public EqualJitter getEqualJitter() { + return equalJitter; + } + + public void setEqualJitter(EqualJitter equalJitter) { + this.equalJitter = equalJitter; + } + + @Override + public void validate() { + long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); + + if (count > 1) { + throw new GyroException("Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); + } else if (count == 0) { + throw new GyroException("One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); + } + } + + @Override + public software.amazon.awssdk.core.retry.backoff.BackoffStrategy toBackoffStrategy() { + return Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()) + .filter(Objects::nonNull) + .findFirst() + .get() + .toBackoffStrategy(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java new file mode 100644 index 000000000..6e8840b7f --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java @@ -0,0 +1,62 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class AndRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private List retryCondition; + + public List getRetryCondition() { + if (retryCondition == null) { + retryCondition = new ArrayList<>(); + } + + return retryCondition; + } + + public void setAndRetryCondition(List andRetryConditions) { + getRetryCondition().addAll(andRetryConditions); + } + + public void setOrRetryCondition(List orRetryConditions) { + getRetryCondition().addAll(orRetryConditions); + } + + public void setMaxNumberOfRetryCondition(List maxNumberOfRetryConditions) { + getRetryCondition().addAll(maxNumberOfRetryConditions); + } + + public void setRetryOnErrorCodesCondition(List retryOnErrorCodesConditions) { + getRetryCondition().addAll(retryOnErrorCodesConditions); + } + + public void setRetryOnStatusCodesCondition(List retryOnStatusCodesConditions) { + getRetryCondition().addAll(retryOnStatusCodesConditions); + } + + public void setRetryOnThrottlingCondition(List retryOnThrottlingConditions) { + getRetryCondition().addAll(retryOnThrottlingConditions); + } + + @Override + public void validate() { + if (getRetryCondition().isEmpty()) { + throw new GyroException("'and-retry-condition' cannot be empty."); + } + } + + @Override + public RetryCondition toRetryCondition() { + return software.amazon.awssdk.core.retry.conditions.AndRetryCondition.create(getRetryCondition().stream() + .map(o -> toRetryCondition()) + .collect( + Collectors.toList()) + .toArray(new RetryCondition[getRetryCondition().size()])); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java new file mode 100644 index 000000000..88f7cbca7 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java @@ -0,0 +1,106 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; + +public class CapacityRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private AndRetryCondition andRetryCondition; + private OrRetryCondition orRetryCondition; + private MaxNumberOfRetryCondition maxNumberOfRetryCondition; + private RetryOnErrorCodesCondition retryOnErrorCodesCondition; + private RetryOnStatusCodesCondition retryOnStatusCodesCondition; + private RetryOnThrottlingCondition retryOnThrottlingCondition; + + public AndRetryCondition getAndRetryCondition() { + return andRetryCondition; + } + + public void setAndRetryCondition(AndRetryCondition andRetryCondition) { + this.andRetryCondition = andRetryCondition; + } + + public OrRetryCondition getOrRetryCondition() { + return orRetryCondition; + } + + public void setOrRetryCondition(OrRetryCondition orRetryCondition) { + this.orRetryCondition = orRetryCondition; + } + + public MaxNumberOfRetryCondition getMaxNumberOfRetryCondition() { + return maxNumberOfRetryCondition; + } + + public void setMaxNumberOfRetryCondition(MaxNumberOfRetryCondition maxNumberOfRetryCondition) { + this.maxNumberOfRetryCondition = maxNumberOfRetryCondition; + } + + public RetryOnErrorCodesCondition getRetryOnErrorCodesCondition() { + return retryOnErrorCodesCondition; + } + + public void setRetryOnErrorCodesCondition(RetryOnErrorCodesCondition retryOnErrorCodesCondition) { + this.retryOnErrorCodesCondition = retryOnErrorCodesCondition; + } + + public RetryOnStatusCodesCondition getRetryOnStatusCodesCondition() { + return retryOnStatusCodesCondition; + } + + public void setRetryOnStatusCodesCondition(RetryOnStatusCodesCondition retryOnStatusCodesCondition) { + this.retryOnStatusCodesCondition = retryOnStatusCodesCondition; + } + + public RetryOnThrottlingCondition getRetryOnThrottlingCondition() { + return retryOnThrottlingCondition; + } + + public void setRetryOnThrottlingCondition(RetryOnThrottlingCondition retryOnThrottlingCondition) { + this.retryOnThrottlingCondition = retryOnThrottlingCondition; + } + + @Override + public void validate() { + long count = Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition()) + .filter(Objects::nonNull).count(); + + if (count > 1) { + throw new GyroException( + "Only one of 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " or 'retry-on-throttling-condition' is allowed."); + } else if (count == 0) { + throw new GyroException( + "One of 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " or 'retry-on-throttling-condition' is required."); + } + } + + @Override + public software.amazon.awssdk.core.retry.conditions.RetryCondition toRetryCondition() { + return Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition()).filter(Objects::nonNull).findFirst().get().toRetryCondition(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java new file mode 100644 index 000000000..d1ade5f9a --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java @@ -0,0 +1,31 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; +import software.amazon.awssdk.core.retry.conditions.MaxNumberOfRetriesCondition; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class MaxNumberOfRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private Integer retryCount; + + public Integer getRetryCount() { + return retryCount; + } + + public void setRetryCount(Integer retryCount) { + this.retryCount = retryCount; + } + + @Override + public void validate() { + if (getRetryCount() == null || getRetryCount() < 0) { + throw new GyroException("retry-count cannot be empty or less than 1."); + } + } + + @Override + public RetryCondition toRetryCondition() { + return MaxNumberOfRetriesCondition.create(getRetryCount()); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java new file mode 100644 index 000000000..877296f69 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java @@ -0,0 +1,62 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class OrRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private List retryCondition; + + public List getRetryCondition() { + if (retryCondition == null) { + retryCondition = new ArrayList<>(); + } + + return retryCondition; + } + + public void setAndRetryCondition(List andRetryConditions) { + getRetryCondition().addAll(andRetryConditions); + } + + public void setOrRetryCondition(List orRetryConditions) { + getRetryCondition().addAll(orRetryConditions); + } + + public void setMaxNumberOfRetryCondition(List maxNumberOfRetryConditions) { + getRetryCondition().addAll(maxNumberOfRetryConditions); + } + + public void setRetryOnErrorCodesCondition(List retryOnErrorCodesConditions) { + getRetryCondition().addAll(retryOnErrorCodesConditions); + } + + public void setRetryOnStatusCodesCondition(List retryOnStatusCodesConditions) { + getRetryCondition().addAll(retryOnStatusCodesConditions); + } + + public void setRetryOnThrottlingCondition(List retryOnThrottlingConditions) { + getRetryCondition().addAll(retryOnThrottlingConditions); + } + + @Override + public void validate() { + if (getRetryCondition().isEmpty()) { + throw new GyroException("'or-retry-condition' cannot be empty."); + } + } + + @Override + public RetryCondition toRetryCondition() { + return software.amazon.awssdk.core.retry.conditions.OrRetryCondition.create(getRetryCondition().stream() + .map(o -> toRetryCondition()) + .collect( + Collectors.toList()) + .toArray(new RetryCondition[getRetryCondition().size()])); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java new file mode 100644 index 000000000..e357ca7cf --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java @@ -0,0 +1,106 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; + +public class RetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private AndRetryCondition andRetryCondition; + private OrRetryCondition orRetryCondition; + private MaxNumberOfRetryCondition maxNumberOfRetryCondition; + private RetryOnErrorCodesCondition retryOnErrorCodesCondition; + private RetryOnStatusCodesCondition retryOnStatusCodesCondition; + private RetryOnThrottlingCondition retryOnThrottlingCondition; + + public AndRetryCondition getAndRetryCondition() { + return andRetryCondition; + } + + public void setAndRetryCondition(AndRetryCondition andRetryCondition) { + this.andRetryCondition = andRetryCondition; + } + + public OrRetryCondition getOrRetryCondition() { + return orRetryCondition; + } + + public void setOrRetryCondition(OrRetryCondition orRetryCondition) { + this.orRetryCondition = orRetryCondition; + } + + public MaxNumberOfRetryCondition getMaxNumberOfRetryCondition() { + return maxNumberOfRetryCondition; + } + + public void setMaxNumberOfRetryCondition(MaxNumberOfRetryCondition maxNumberOfRetryCondition) { + this.maxNumberOfRetryCondition = maxNumberOfRetryCondition; + } + + public RetryOnErrorCodesCondition getRetryOnErrorCodesCondition() { + return retryOnErrorCodesCondition; + } + + public void setRetryOnErrorCodesCondition(RetryOnErrorCodesCondition retryOnErrorCodesCondition) { + this.retryOnErrorCodesCondition = retryOnErrorCodesCondition; + } + + public RetryOnStatusCodesCondition getRetryOnStatusCodesCondition() { + return retryOnStatusCodesCondition; + } + + public void setRetryOnStatusCodesCondition(RetryOnStatusCodesCondition retryOnStatusCodesCondition) { + this.retryOnStatusCodesCondition = retryOnStatusCodesCondition; + } + + public RetryOnThrottlingCondition getRetryOnThrottlingCondition() { + return retryOnThrottlingCondition; + } + + public void setRetryOnThrottlingCondition(RetryOnThrottlingCondition retryOnThrottlingCondition) { + this.retryOnThrottlingCondition = retryOnThrottlingCondition; + } + + @Override + public void validate() { + long count = Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition()) + .filter(Objects::nonNull).count(); + + if (count > 1) { + throw new GyroException( + "Only one of 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " or 'retry-on-throttling-condition' is allowed."); + } else if (count == 0) { + throw new GyroException( + "One of 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " or 'retry-on-throttling-condition' is required."); + } + } + + @Override + public software.amazon.awssdk.core.retry.conditions.RetryCondition toRetryCondition() { + return Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition()).filter(Objects::nonNull).findFirst().get().toRetryCondition(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java new file mode 100644 index 000000000..5e092e77e --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java @@ -0,0 +1,8 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public interface RetryConditionInterface { + + RetryCondition toRetryCondition(); +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java new file mode 100644 index 000000000..4ad0c7c8d --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java @@ -0,0 +1,34 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.HashSet; +import java.util.List; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; +import software.amazon.awssdk.awscore.retry.conditions.RetryOnErrorCodeCondition; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class RetryOnErrorCodesCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private List retryableErrorCodes; + + public List getRetryableErrorCodes() { + return retryableErrorCodes; + } + + public void setRetryableErrorCodes(List retryableErrorCodes) { + this.retryableErrorCodes = retryableErrorCodes; + } + + @Override + public void validate() { + if (getRetryableErrorCodes().isEmpty()) { + throw new GyroException("'retryable-error-codes' cannot be empty."); + } + } + + @Override + public RetryCondition toRetryCondition() { + return RetryOnErrorCodeCondition.create(new HashSet<>(getRetryableErrorCodes())); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java new file mode 100644 index 000000000..217e7b9fb --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java @@ -0,0 +1,35 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.HashSet; +import java.util.List; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import gyro.core.GyroException; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; +import software.amazon.awssdk.core.retry.conditions.RetryOnStatusCodeCondition; + +public class RetryOnStatusCodesCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private List retryableStatusCodes; + + public List getRetryableStatusCodes() { + return retryableStatusCodes; + } + + public void setRetryableStatusCodes(List retryableStatusCodes) { + this.retryableStatusCodes = retryableStatusCodes; + } + + @Override + public void validate() { + if (getRetryableStatusCodes().isEmpty()) { + throw new GyroException("'retryable-status-codes' cannot be empty."); + } + + } + + @Override + public RetryCondition toRetryCondition() { + return RetryOnStatusCodeCondition.create(new HashSet<>(getRetryableStatusCodes())); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java new file mode 100644 index 000000000..621584678 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java @@ -0,0 +1,17 @@ +package gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class RetryOnThrottlingCondition implements RetryConditionInterface, ClientConfigurationInterface { + + @Override + public void validate() { + + } + + @Override + public RetryCondition toRetryCondition() { + return software.amazon.awssdk.core.retry.conditions.RetryOnThrottlingCondition.create(); + } +} From 3f35154ef5a9621d1eacac441a6ace8d1455ef51 Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Mon, 26 Apr 2021 17:57:06 -0400 Subject: [PATCH 02/12] Add client config to aws credentials - This will let aws credentials be associated with client configs. - Will enable to use client configs when using @uses-credentials --- src/main/java/gyro/aws/AwsCredentials.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/gyro/aws/AwsCredentials.java b/src/main/java/gyro/aws/AwsCredentials.java index 4d261ec16..f88e2f062 100644 --- a/src/main/java/gyro/aws/AwsCredentials.java +++ b/src/main/java/gyro/aws/AwsCredentials.java @@ -27,6 +27,7 @@ public class AwsCredentials extends Credentials { private String profileName; private String region; private AwsCredentialsProvider provider; + private String clientConfig; public AwsCredentials() { this.provider = AwsCredentialsProviderChain.builder() @@ -61,6 +62,14 @@ public AwsCredentialsProvider provider() { return provider; } + public String getClientConfig() { + return clientConfig; + } + + public void setClientConfig(String clientConfig) { + this.clientConfig = clientConfig; + } + @Override public void refresh() { provider().resolveCredentials(); From cb389bd7a8b07d5b5cba895ef994a43544a0cb23 Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Mon, 26 Apr 2021 17:57:37 -0400 Subject: [PATCH 03/12] Refactor AwsResource to use custom client configs --- src/main/java/gyro/aws/AwsFinder.java | 2 +- src/main/java/gyro/aws/AwsResource.java | 54 +++++++++++++++---- .../java/gyro/aws/DynamoDbLockBackend.java | 2 +- src/main/java/gyro/aws/S3FileBackend.java | 2 +- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/main/java/gyro/aws/AwsFinder.java b/src/main/java/gyro/aws/AwsFinder.java index 9f71b6f5d..1ef76b9bc 100644 --- a/src/main/java/gyro/aws/AwsFinder.java +++ b/src/main/java/gyro/aws/AwsFinder.java @@ -45,7 +45,7 @@ protected C newClient() { Class clientClass = (Class) TypeDefinition.getInstance(getClass()) .getInferredGenericTypeArgumentClass(AwsFinder.class, 0); - return AwsResource.createClient(clientClass, credentials(AwsCredentials.class), getRegion(), getEndpoint()); + return AwsResource.createClient(clientClass, credentials(AwsCredentials.class), getRegion(), getEndpoint(), null); } protected String getRegion() { diff --git a/src/main/java/gyro/aws/AwsResource.java b/src/main/java/gyro/aws/AwsResource.java index 1059406ee..c5d3b5d4b 100644 --- a/src/main/java/gyro/aws/AwsResource.java +++ b/src/main/java/gyro/aws/AwsResource.java @@ -21,9 +21,15 @@ import java.util.HashMap; import java.util.Map; +import com.psddev.dari.util.ObjectUtils; +import gyro.aws.clientconfiguration.ClientConfiguration; +import gyro.aws.clientconfiguration.ClientConfigurationSettings; import gyro.core.GyroException; import gyro.core.resource.Diffable; +import gyro.core.resource.DiffableInternals; import gyro.core.resource.Resource; +import gyro.core.scope.DiffableScope; +import gyro.core.scope.Scope; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder; import software.amazon.awssdk.core.SdkClient; @@ -44,7 +50,7 @@ protected T createClient(Class clientClass) { return ((AwsResource) parent).createClient(clientClass); } - return createClient(clientClass, null, null); + return createClient(clientClass, null, ""); } @SuppressWarnings("unchecked") @@ -55,15 +61,16 @@ protected T createClient(Class clientClass, String regi } AwsCredentials credentials = credentials(AwsCredentials.class); - client = createClient(clientClass, credentials, region, endpoint); + DiffableScope scope = DiffableInternals.getScope(this); + client = createClient(clientClass, credentials, region, endpoint, scope); return (T) client; } - public static synchronized T createClient(Class clientClass, AwsCredentials credentials) { - return createClient(clientClass, credentials, null, null); + public static synchronized T createClient(Class clientClass, AwsCredentials credentials, Scope scope) { + return createClient(clientClass, credentials, null, null, scope); } - public static synchronized T createClient(Class clientClass, AwsCredentials credentials, String region, String endpoint) { + public static synchronized T createClient(Class clientClass, AwsCredentials credentials, String region, String endpoint, Scope scope) { if (credentials == null) { throw new GyroException(String.format( "Unable to create %s, no credentials specified!", @@ -81,22 +88,47 @@ public static synchronized T createClient(Class clientC if (clients.get(key) == null) { try { - AwsCredentialsProvider provider = credentials.provider(); - ClientOverrideConfiguration.Builder retryPolicy = ClientOverrideConfiguration.builder() + ClientOverrideConfiguration overrideConfiguration = ClientOverrideConfiguration.builder() .retryPolicy(RetryPolicy.builder() .numRetries(20) .retryCapacityCondition(RetryOnThrottlingCondition.create()) - .build()); + .build()).build(); + + ApacheHttpClient.Builder httpClientBuilder = ApacheHttpClient.builder(); + + String clientConfig = credentials.getClientConfig(); + if (ObjectUtils.isBlank(clientConfig)) { + clientConfig = "default"; + } + + if (scope != null) { + ClientConfiguration clientConfiguration = scope.getRootScope().getSettings(ClientConfigurationSettings.class) + .getClientConfigurations() + .get(clientConfig); + + if (clientConfiguration != null) { + if (clientConfiguration.getHttpClientConfiguration() != null) { + httpClientBuilder = clientConfiguration.getHttpClientConfiguration().toApacheHttpClient(); + } + + if (clientConfiguration.getOverrideConfiguration() != null) { + overrideConfiguration = clientConfiguration.getOverrideConfiguration() + .toClientOverrideConfiguration(); + } + } + } + + AwsCredentialsProvider provider = credentials.provider(); Method method = clientClass.getMethod("builder"); AwsDefaultClientBuilder builder = (AwsDefaultClientBuilder) method.invoke(null); builder.credentialsProvider(provider); builder.region(Region.of(region != null ? region : credentials.getRegion())); - builder.httpClientBuilder(ApacheHttpClient.builder()); - builder.overrideConfiguration(retryPolicy.build()); + builder.httpClientBuilder(httpClientBuilder); + builder.overrideConfiguration(overrideConfiguration); - if (endpoint != null) { + if (!ObjectUtils.isBlank(endpoint)) { builder.endpointOverride(URI.create(endpoint)); } diff --git a/src/main/java/gyro/aws/DynamoDbLockBackend.java b/src/main/java/gyro/aws/DynamoDbLockBackend.java index 8b77f0f35..2758d6283 100644 --- a/src/main/java/gyro/aws/DynamoDbLockBackend.java +++ b/src/main/java/gyro/aws/DynamoDbLockBackend.java @@ -155,7 +155,7 @@ private Optional> getCurrentLock() { } private DynamoDbClient client() { - return AwsResource.createClient(DynamoDbClient.class, credentials()); + return AwsResource.createClient(DynamoDbClient.class, credentials(), getRootScope()); } private AwsCredentials credentials() { diff --git a/src/main/java/gyro/aws/S3FileBackend.java b/src/main/java/gyro/aws/S3FileBackend.java index f3c560d23..0499a4c78 100644 --- a/src/main/java/gyro/aws/S3FileBackend.java +++ b/src/main/java/gyro/aws/S3FileBackend.java @@ -146,7 +146,7 @@ private S3Client client() { .get(String.format("%s::%s", "aws", credentialName)); } - return AwsResource.createClient(S3Client.class, (AwsCredentials) credentials); + return AwsResource.createClient(S3Client.class, (AwsCredentials) credentials, getRootScope()); } private String prefixed(String file) { From 48f37e685f32f49827fa2e270e0cbf59bf4f002a Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Mon, 26 Apr 2021 18:01:01 -0400 Subject: [PATCH 04/12] Add license --- .../clientconfiguration/ClientConfiguration.java | 16 ++++++++++++++++ .../ClientConfigurationDirectiveProcessor.java | 16 ++++++++++++++++ .../ClientConfigurationInterface.java | 16 ++++++++++++++++ .../ClientConfigurationSettings.java | 16 ++++++++++++++++ .../ClientConfigurationUtils.java | 16 ++++++++++++++++ .../ClientOverrideConfiguration.java | 16 ++++++++++++++++ .../HttpClientConfiguration.java | 16 ++++++++++++++++ .../retrypolicy/RetryPolicy.java | 16 ++++++++++++++++ .../backoffstrategies/BackoffStrategy.java | 16 ++++++++++++++++ .../BackoffStrategyInterface.java | 16 ++++++++++++++++ .../backoffstrategies/EqualJitter.java | 16 ++++++++++++++++ .../backoffstrategies/FixedDelay.java | 16 ++++++++++++++++ .../backoffstrategies/FullJitter.java | 16 ++++++++++++++++ .../ThrottlingBackoffStrategy.java | 16 ++++++++++++++++ .../retryconditions/AndRetryCondition.java | 16 ++++++++++++++++ .../retryconditions/CapacityRetryCondition.java | 16 ++++++++++++++++ .../MaxNumberOfRetryCondition.java | 16 ++++++++++++++++ .../retryconditions/OrRetryCondition.java | 16 ++++++++++++++++ .../retryconditions/RetryCondition.java | 16 ++++++++++++++++ .../retryconditions/RetryConditionInterface.java | 16 ++++++++++++++++ .../RetryOnErrorCodesCondition.java | 16 ++++++++++++++++ .../RetryOnStatusCodesCondition.java | 16 ++++++++++++++++ .../RetryOnThrottlingCondition.java | 16 ++++++++++++++++ 23 files changed, 368 insertions(+) diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java index 6b18de2ae..031b8364d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; public class ClientConfiguration implements ClientConfigurationInterface { diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java index aae5c1e4e..7a9c7cdbc 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; import java.beans.PropertyDescriptor; diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java index c4713f62c..f9cbd0bb9 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; public interface ClientConfigurationInterface { diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java index aec582b95..d3e8dac8c 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; import java.util.HashMap; diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java index b15d14810..25af5a308 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; import java.time.Duration; diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java index e79135a1a..72cf9e111 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; import gyro.aws.clientconfiguration.retrypolicy.RetryPolicy; diff --git a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java index b39d98028..daa859afc 100644 --- a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; import gyro.core.GyroException; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java index 01c1bb1f7..8920e2a02 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy; import gyro.aws.clientconfiguration.ClientConfigurationInterface; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java index 1a265ffa6..bfed530ce 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import java.util.Objects; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java index 0413af9e2..a65272cf4 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import software.amazon.awssdk.core.retry.backoff.BackoffStrategy; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java index 3a7435340..1d474caee 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import gyro.aws.clientconfiguration.ClientConfigurationInterface; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java index 8da35d707..a59644bb6 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import gyro.aws.clientconfiguration.ClientConfigurationInterface; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java index f65e93e48..9e7eb1f96 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import gyro.aws.clientconfiguration.ClientConfigurationInterface; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java index 65d2e50d9..4cc1ea64e 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; import java.util.Objects; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java index 6e8840b7f..70d223081 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.ArrayList; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java index 88f7cbca7..b84621d15 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.Objects; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java index d1ade5f9a..2534685d8 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import gyro.aws.clientconfiguration.ClientConfigurationInterface; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java index 877296f69..26c20d2d4 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.ArrayList; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java index e357ca7cf..eda9d4179 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.Objects; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java index 5e092e77e..17004ac4e 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import software.amazon.awssdk.core.retry.conditions.RetryCondition; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java index 4ad0c7c8d..8380e90e2 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.HashSet; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java index 217e7b9fb..19458e7bc 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import java.util.HashSet; diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java index 621584678..4203bd3c0 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; import gyro.aws.clientconfiguration.ClientConfigurationInterface; From 3cbbe86405a477fbeebeb88cec425cfe7886d70b Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 08:19:24 -0400 Subject: [PATCH 05/12] Update license to 2021 --- .../java/gyro/aws/clientconfiguration/ClientConfiguration.java | 2 +- .../ClientConfigurationDirectiveProcessor.java | 2 +- .../aws/clientconfiguration/ClientConfigurationInterface.java | 2 +- .../aws/clientconfiguration/ClientConfigurationSettings.java | 2 +- .../gyro/aws/clientconfiguration/ClientConfigurationUtils.java | 2 +- .../aws/clientconfiguration/ClientOverrideConfiguration.java | 2 +- .../gyro/aws/clientconfiguration/HttpClientConfiguration.java | 2 +- .../gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java | 2 +- .../retrypolicy/backoffstrategies/BackoffStrategy.java | 2 +- .../retrypolicy/backoffstrategies/BackoffStrategyInterface.java | 2 +- .../retrypolicy/backoffstrategies/EqualJitter.java | 2 +- .../retrypolicy/backoffstrategies/FixedDelay.java | 2 +- .../retrypolicy/backoffstrategies/FullJitter.java | 2 +- .../backoffstrategies/ThrottlingBackoffStrategy.java | 2 +- .../retrypolicy/retryconditions/AndRetryCondition.java | 2 +- .../retrypolicy/retryconditions/CapacityRetryCondition.java | 2 +- .../retrypolicy/retryconditions/MaxNumberOfRetryCondition.java | 2 +- .../retrypolicy/retryconditions/OrRetryCondition.java | 2 +- .../retrypolicy/retryconditions/RetryCondition.java | 2 +- .../retrypolicy/retryconditions/RetryConditionInterface.java | 2 +- .../retrypolicy/retryconditions/RetryOnErrorCodesCondition.java | 2 +- .../retryconditions/RetryOnStatusCodesCondition.java | 2 +- .../retrypolicy/retryconditions/RetryOnThrottlingCondition.java | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java index 031b8364d..d7703a2c1 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java index 7a9c7cdbc..a4f34f5ef 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java index f9cbd0bb9..91a226566 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationInterface.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java index d3e8dac8c..b49778064 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java index 25af5a308..e1450da69 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java index 72cf9e111..ef94e4078 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java index daa859afc..e2a074d82 100644 --- a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java index 8920e2a02..dac6bae24 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java index bfed530ce..781a98a75 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java index a65272cf4..31f2346f0 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategyInterface.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java index 1d474caee..e74d8597f 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java index a59644bb6..d8f8e047d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java index 9e7eb1f96..a346a58e2 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java index 4cc1ea64e..2106afc1d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java index 70d223081..e89066508 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java index b84621d15..b5576d13f 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java index 2534685d8..c1735e3c3 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java index 26c20d2d4..7566e6d89 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java index eda9d4179..cab375264 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java index 17004ac4e..9e2434370 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryConditionInterface.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java index 8380e90e2..26078661d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java index 19458e7bc..06e196a3c 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java index 4203bd3c0..c170df80d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnThrottlingCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2020, Brightspot, Inc. + * Copyright 2021, Brightspot, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 48f6819d9cce1f0523aef5adce010b39daf87cdf Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 08:26:10 -0400 Subject: [PATCH 06/12] Minor comments on some methods and setters --- .../ClientConfigurationDirectiveProcessor.java | 2 ++ .../retrypolicy/retryconditions/AndRetryCondition.java | 3 +++ .../retrypolicy/retryconditions/OrRetryCondition.java | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java index a4f34f5ef..25fea707d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -56,6 +56,7 @@ public void process(RootScope scope, DirectiveNode node) throws Exception { settings.getClientConfigurations().put(name, clientConfiguration); } + // Automate config consumption mapping fields to class parameters private Object process(Class configClass, RootScope scope, Scope bodyScope) { Object configClassObj = Reflections.newInstance(configClass); if (bodyScope != null) { @@ -67,6 +68,7 @@ private Object process(Class configClass, RootScope scope, Scope bodyScope) { CaseFormat.LOWER_HYPHEN, property.getName())); + // Recursively assign values for complex gyro types if (genericParameterType.getTypeName().contains("gyro")) { if (configVal instanceof List) { if (genericParameterType.getTypeName().contains("java.util.List")) { diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java index e89066508..b71dbd02a 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java @@ -36,6 +36,9 @@ public List getRetryCondition() { return retryCondition; } + // Pseudo setters. + // Configs point to one or more of the below variables based on the setter names + public void setAndRetryCondition(List andRetryConditions) { getRetryCondition().addAll(andRetryConditions); } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java index 7566e6d89..1cf5333a1 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java @@ -36,6 +36,9 @@ public List getRetryCondition() { return retryCondition; } + // Pseudo setters. + // Configs point to one or more of the below variables based on the setter names + public void setAndRetryCondition(List andRetryConditions) { getRetryCondition().addAll(andRetryConditions); } From 74dab4cc999a7561c91849fe92ea1e00111e06f0 Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 12:18:35 -0400 Subject: [PATCH 07/12] Update validation handling Validation can now point to particular location of error --- ...ClientConfigurationDirectiveProcessor.java | 11 +++++- .../ClientConfigurationException.java | 39 +++++++++++++++++++ .../ClientConfigurationUtils.java | 9 +---- .../ClientOverrideConfiguration.java | 2 +- .../HttpClientConfiguration.java | 14 +++---- .../retrypolicy/RetryPolicy.java | 6 +-- .../backoffstrategies/BackoffStrategy.java | 10 +++-- .../backoffstrategies/EqualJitter.java | 4 +- .../backoffstrategies/FixedDelay.java | 2 +- .../backoffstrategies/FullJitter.java | 4 +- .../ThrottlingBackoffStrategy.java | 10 +++-- .../retryconditions/AndRetryCondition.java | 12 +++++- .../CapacityRetryCondition.java | 8 ++-- .../MaxNumberOfRetryCondition.java | 6 +-- .../retryconditions/OrRetryCondition.java | 12 +++++- .../retryconditions/RetryCondition.java | 8 ++-- .../RetryOnErrorCodesCondition.java | 4 +- .../RetryOnStatusCodesCondition.java | 4 +- 18 files changed, 116 insertions(+), 49 deletions(-) create mode 100644 src/main/java/gyro/aws/clientconfiguration/ClientConfigurationException.java diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java index 25fea707d..4479de430 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -23,6 +23,7 @@ import com.google.common.base.CaseFormat; import com.psddev.dari.util.ObjectUtils; +import gyro.core.GyroException; import gyro.core.Reflections; import gyro.core.Type; import gyro.core.directive.DirectiveProcessor; @@ -104,7 +105,15 @@ private Object process(Class configClass, RootScope scope, Scope bodyScope) { } if (ClientConfigurationInterface.class.isAssignableFrom(configClass)) { - ((ClientConfigurationInterface) configClassObj).validate(); + try { + ((ClientConfigurationInterface) configClassObj).validate(); + } catch (ClientConfigurationException ex) { + if (ex.getField() != null) { + throw new GyroException(bodyScope.getLocation(ex.getField()), ex.getFormattedMessage()); + } else { + throw new GyroException(ex.getFormattedMessage()); + } + } } return configClassObj; diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationException.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationException.java new file mode 100644 index 000000000..da17090bc --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationException.java @@ -0,0 +1,39 @@ +/* + * Copyright 2021, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration; + +public class ClientConfigurationException extends RuntimeException { + + private final String field; + + public ClientConfigurationException(String field, String message, Throwable cause) { + super(message, cause); + this.field = field; + } + + public ClientConfigurationException(String field, String message) { + this(field, message, null); + } + + public String getField() { + return field; + } + + public String getFormattedMessage() { + return String.format("%s%s", (getField() != null ? String.format("%s: ", getField()) : ""), getMessage()); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java index e1450da69..45c6bdf07 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java @@ -20,8 +20,6 @@ import java.time.format.DateTimeParseException; import com.google.common.base.Preconditions; -import com.psddev.dari.util.ObjectUtils; -import gyro.core.GyroException; public class ClientConfigurationUtils { @@ -37,14 +35,11 @@ public static Duration getDuration(String duration) { return Duration.ofSeconds(parse(duration)); } - public static void validate(String duration, String fieldName, String parent) { + public static void validate(String duration, String fieldName) { try { parse(duration); } catch (DateTimeParseException ex) { - throw new GyroException(String.format( - "%s'%s's time format '" + duration + "' is invalid.", - (ObjectUtils.isBlank(parent) ? "" : String.format("%s: ", parent)), - fieldName)); + throw new ClientConfigurationException(fieldName, String.format("Time format '%s' is invalid.", duration)); } } } diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java index ef94e4078..82fc86cf4 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientOverrideConfiguration.java @@ -42,7 +42,7 @@ public void setRetryPolicy(RetryPolicy retryPolicy) { @Override public void validate() { if (getApiCallTimeout() != null) { - ClientConfigurationUtils.validate(getApiCallTimeout(), "api-call-timeout", "client-override-configuration"); + ClientConfigurationUtils.validate(getApiCallTimeout(), "api-call-timeout"); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java index e2a074d82..fcbb52ba4 100644 --- a/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java +++ b/src/main/java/gyro/aws/clientconfiguration/HttpClientConfiguration.java @@ -90,33 +90,29 @@ public void validate() { if (getConnectionAcquisitionTimeout() != null) { ClientConfigurationUtils.validate( getConnectionAcquisitionTimeout(), - "connection-acquisition-timeout", - "http-client-configuration"); + "connection-acquisition-timeout"); } if (getConnectionTimeout() != null) { ClientConfigurationUtils.validate( getConnectionTimeout(), - "connection-timeout", - "http-client-configuration"); + "connection-timeout"); } if (getConnectionTimeToLive() != null) { ClientConfigurationUtils.validate( getConnectionTimeToLive(), - "connection-time-to-live", - "http-client-configuration"); + "connection-time-to-live"); } if (getConnectionMaxIdleTime() != null) { ClientConfigurationUtils.validate( getConnectionMaxIdleTime(), - "connection-max-idle-time", - "http-client-configuration"); + "connection-max-idle-time"); } if (getSocketTimeout() != null) { - ClientConfigurationUtils.validate(getSocketTimeout(), "socket-timeout", "http-client-configuration"); + ClientConfigurationUtils.validate(getSocketTimeout(), "socket-timeout"); } if (getMaxConnections() != null && getMaxConnections() < 1) { diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java index dac6bae24..1b8d4a96d 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/RetryPolicy.java @@ -16,12 +16,12 @@ package gyro.aws.clientconfiguration.retrypolicy; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; import gyro.aws.clientconfiguration.retrypolicy.backoffstrategies.BackoffStrategy; import gyro.aws.clientconfiguration.retrypolicy.backoffstrategies.ThrottlingBackoffStrategy; import gyro.aws.clientconfiguration.retrypolicy.retryconditions.CapacityRetryCondition; import gyro.aws.clientconfiguration.retrypolicy.retryconditions.RetryCondition; -import gyro.core.GyroException; public class RetryPolicy implements ClientConfigurationInterface { @@ -82,8 +82,8 @@ public void setCapacityRetryCondition(CapacityRetryCondition capacityRetryCondit @Override public void validate() { - if (getRetryCount() != null && getRetryCount() < 0) { - throw new GyroException("'retry-count' cannot be less than 1."); + if (getRetryCount() != null && getRetryCount() < 1) { + throw new ClientConfigurationException("retry-count", "Cannot be less than 1."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java index 781a98a75..99d1c74a5 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java @@ -19,8 +19,8 @@ import java.util.Objects; import java.util.stream.Stream; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; public class BackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { @@ -57,9 +57,13 @@ public void validate() { long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); if (count > 1) { - throw new GyroException("Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); + throw new ClientConfigurationException( + "backoff-strategy", + "Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); } else if (count == 0) { - throw new GyroException("One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); + throw new ClientConfigurationException( + "backoff-strategy", + "One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java index e74d8597f..68a4b6b1e 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/EqualJitter.java @@ -44,8 +44,8 @@ public void setMaxBackoffTime(String maxBackoffTime) { @Override public void validate() { - ClientConfigurationUtils.validate(getBaseDelay(), "base-delay", "equal-jitter"); - ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time", "equal-jitter"); + ClientConfigurationUtils.validate(getBaseDelay(), "base-delay"); + ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time"); } @Override diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java index d8f8e047d..d571ec55f 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FixedDelay.java @@ -35,7 +35,7 @@ public void setDelay(String delay) { @Override public void validate() { - ClientConfigurationUtils.validate(getDelay(), "delay", "fixed-delay"); + ClientConfigurationUtils.validate(getDelay(), "delay"); } @Override diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java index a346a58e2..31a4fde85 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/FullJitter.java @@ -44,8 +44,8 @@ public void setMaxBackoffTime(String maxBackoffTime) { @Override public void validate() { - ClientConfigurationUtils.validate(getBaseDelay(), "base-delay", "full-jitter"); - ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time", "full-jitter"); + ClientConfigurationUtils.validate(getBaseDelay(), "base-delay"); + ClientConfigurationUtils.validate(getMaxBackoffTime(), "max-backoff-time"); } @Override diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java index 2106afc1d..c96138f01 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java @@ -19,8 +19,8 @@ import java.util.Objects; import java.util.stream.Stream; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; public class ThrottlingBackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { @@ -57,9 +57,13 @@ public void validate() { long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); if (count > 1) { - throw new GyroException("Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); + throw new ClientConfigurationException( + "throttling-backoff-strategy", + "Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); } else if (count == 0) { - throw new GyroException("One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); + throw new ClientConfigurationException( + "throttling-backoff-strategy", + "One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java index b71dbd02a..49df36674 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AndRetryCondition.java @@ -20,8 +20,8 @@ import java.util.List; import java.util.stream.Collectors; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; import software.amazon.awssdk.core.retry.conditions.RetryCondition; public class AndRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { @@ -38,6 +38,14 @@ public List getRetryCondition() { // Pseudo setters. // Configs point to one or more of the below variables based on the setter names + // + // Ex: + // .. + // and-retry-condition + // retry-on-throttling-condition # <-- triggers setRetryOnThrottlingCondition() + // end + // end + // public void setAndRetryCondition(List andRetryConditions) { getRetryCondition().addAll(andRetryConditions); @@ -66,7 +74,7 @@ public void setRetryOnThrottlingCondition(List retry @Override public void validate() { if (getRetryCondition().isEmpty()) { - throw new GyroException("'and-retry-condition' cannot be empty."); + throw new ClientConfigurationException("and-retry-condition", "Cannot be empty."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java index b5576d13f..f62cccfda 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java @@ -19,8 +19,8 @@ import java.util.Objects; import java.util.stream.Stream; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; public class CapacityRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { @@ -91,7 +91,8 @@ public void validate() { .filter(Objects::nonNull).count(); if (count > 1) { - throw new GyroException( + throw new ClientConfigurationException( + "retry-condition", "Only one of 'and-retry-condition'," + " 'or-retry-condition'," + " 'max-number-of-retry-condition'," @@ -99,7 +100,8 @@ public void validate() { + " 'retry-on-status-codes-condition'" + " or 'retry-on-throttling-condition' is allowed."); } else if (count == 0) { - throw new GyroException( + throw new ClientConfigurationException( + "retry-condition", "One of 'and-retry-condition'," + " 'or-retry-condition'," + " 'max-number-of-retry-condition'," diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java index c1735e3c3..e12bb0628 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/MaxNumberOfRetryCondition.java @@ -16,8 +16,8 @@ package gyro.aws.clientconfiguration.retrypolicy.retryconditions; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; import software.amazon.awssdk.core.retry.conditions.MaxNumberOfRetriesCondition; import software.amazon.awssdk.core.retry.conditions.RetryCondition; @@ -35,8 +35,8 @@ public void setRetryCount(Integer retryCount) { @Override public void validate() { - if (getRetryCount() == null || getRetryCount() < 0) { - throw new GyroException("retry-count cannot be empty or less than 1."); + if (getRetryCount() == null || getRetryCount() < 1) { + throw new ClientConfigurationException("retry-count", "Cannot be empty or less than 1."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java index 1cf5333a1..cc30a6cc2 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/OrRetryCondition.java @@ -20,8 +20,8 @@ import java.util.List; import java.util.stream.Collectors; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; import software.amazon.awssdk.core.retry.conditions.RetryCondition; public class OrRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { @@ -38,6 +38,14 @@ public List getRetryCondition() { // Pseudo setters. // Configs point to one or more of the below variables based on the setter names + // + // Ex: + // .. + // or-retry-condition + // retry-on-throttling-condition # <-- triggers setRetryOnThrottlingCondition() + // end + // end + // public void setAndRetryCondition(List andRetryConditions) { getRetryCondition().addAll(andRetryConditions); @@ -66,7 +74,7 @@ public void setRetryOnThrottlingCondition(List retry @Override public void validate() { if (getRetryCondition().isEmpty()) { - throw new GyroException("'or-retry-condition' cannot be empty."); + throw new ClientConfigurationException("or-retry-condition", "Cannot be empty."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java index cab375264..5d7a73d5c 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java @@ -19,8 +19,8 @@ import java.util.Objects; import java.util.stream.Stream; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; public class RetryCondition implements RetryConditionInterface, ClientConfigurationInterface { @@ -91,7 +91,8 @@ public void validate() { .filter(Objects::nonNull).count(); if (count > 1) { - throw new GyroException( + throw new ClientConfigurationException( + "retry-condition", "Only one of 'and-retry-condition'," + " 'or-retry-condition'," + " 'max-number-of-retry-condition'," @@ -99,7 +100,8 @@ public void validate() { + " 'retry-on-status-codes-condition'" + " or 'retry-on-throttling-condition' is allowed."); } else if (count == 0) { - throw new GyroException( + throw new ClientConfigurationException( + "retry-condition", "One of 'and-retry-condition'," + " 'or-retry-condition'," + " 'max-number-of-retry-condition'," diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java index 26078661d..3d247c2dd 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnErrorCodesCondition.java @@ -19,8 +19,8 @@ import java.util.HashSet; import java.util.List; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; import software.amazon.awssdk.awscore.retry.conditions.RetryOnErrorCodeCondition; import software.amazon.awssdk.core.retry.conditions.RetryCondition; @@ -39,7 +39,7 @@ public void setRetryableErrorCodes(List retryableErrorCodes) { @Override public void validate() { if (getRetryableErrorCodes().isEmpty()) { - throw new GyroException("'retryable-error-codes' cannot be empty."); + throw new ClientConfigurationException("retryable-error-codes", "Cannot be empty."); } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java index 06e196a3c..bfbf00b4e 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnStatusCodesCondition.java @@ -19,8 +19,8 @@ import java.util.HashSet; import java.util.List; +import gyro.aws.clientconfiguration.ClientConfigurationException; import gyro.aws.clientconfiguration.ClientConfigurationInterface; -import gyro.core.GyroException; import software.amazon.awssdk.core.retry.conditions.RetryCondition; import software.amazon.awssdk.core.retry.conditions.RetryOnStatusCodeCondition; @@ -39,7 +39,7 @@ public void setRetryableStatusCodes(List retryableStatusCodes) { @Override public void validate() { if (getRetryableStatusCodes().isEmpty()) { - throw new GyroException("'retryable-status-codes' cannot be empty."); + throw new ClientConfigurationException("retryable-status-codes", "Cannot be empty."); } } From 521d36ebb268525ee38585fad9bd30f4faa51e6c Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 16:20:35 -0400 Subject: [PATCH 08/12] Create README.MD --- src/main/java/gyro/aws/clientconfiguration/README.MD | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/java/gyro/aws/clientconfiguration/README.MD diff --git a/src/main/java/gyro/aws/clientconfiguration/README.MD b/src/main/java/gyro/aws/clientconfiguration/README.MD new file mode 100644 index 000000000..e69de29bb From e15f76852f88bad486745306e001ea92622a02ff Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 17:27:05 -0400 Subject: [PATCH 09/12] Update README.MD --- .../gyro/aws/clientconfiguration/README.MD | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/main/java/gyro/aws/clientconfiguration/README.MD b/src/main/java/gyro/aws/clientconfiguration/README.MD index e69de29bb..ea9c64633 100644 --- a/src/main/java/gyro/aws/clientconfiguration/README.MD +++ b/src/main/java/gyro/aws/clientconfiguration/README.MD @@ -0,0 +1,126 @@ +# AWS Client override configuration +The AWS **client-configuration** allows you to override the default client creation options. + +You define the `client-configuration` directive in your `.init.gyro` file. + +``` +@aws::client-configuration + +@end +``` + +If no config name is given, it is treated as `default` and is used as the default override for all client creations. + +``` +@aws::client-configuration # default configuration + override-configuration + retry-policy + count: 20 + + capacity-retry-condition + retry-on-throttling-condition + + end + end + end + end +@end +``` + +Multiple client-configuration directives can be defined using different names. These can be associated with individual credential directives. In doing so all assets using that credential will create the aws client with overrides as defined by the mentioned client configuration. + +``` +@credentials 'enterprise::aws-credentials' 'east-2' + enterprise-url: "https://beam-enterprise.psdops.com" + project: $(project) + account: $(account) + region: "us-east-2" + client-config: "us-east-2-config" +@end + +@aws::client-configuration 'us-east-2-config' + override-configuration + retry-policy + count: 30 + + capacity-retry-condition + retry-on-throttling-condition + + end + end + end + end +@end + +@aws::client-configuration 'us-west-2-config' + http-client-configuration + socket-timeout: "120S" + max-connections: 20 + end + + override-configuration + retry-policy + count: 10 + + capacity-retry-condition + retry-on-throttling-condition + + end + end + end + end +@end +``` +In this case, all assets using the `east-2` credentials will create there respective aws clients using the overrides defined in the client-configuration named `east-2-config`. + +## Configuration Details + +The client-configuration has the following options: +- **http-client-configuration** - Http configuration for the client. [See options](#Http-Client-Configuration) +- **override-client-configuration** - Override configuration for the client. [See options](#Override-Client-Configuration) + +### Http Client Configuration +- **socket-timeout** - The amount of [time](#Time) to wait for data to be transferred over an established, open connection before the connection is timed out. A duration of `0` means infinity, and is not recommended. +- **connection-timeout** - The amount of [time](#Time) to wait when initially establishing a connection before giving up and timing out. A duration of `0` means infinity, and is not recommended. +- **connection-acquisition-timeout** - The amount of [time](#Time) to wait when acquiring a connection from the pool before giving up and timing out. +- **max-connections** - The maximum number of connections allowed in the connection pool. +- **expect-continue-enabled** - Configure whether the client should send an HTTP expect-continue handshake before each request. +- **connection-time-to-live** - The maximum amount of [time](#Time) that a connection should be allowed to remain open, regardless of usage frequency. +- **connection-max-idle-time** - Configure the maximum amount of [time](#Time) that a connection should be allowed to remain open while idle. + +### Override Client Configuration +- **api-call-timeout** - Specify the amount of [time](#Time) to allow the client to complete the execution of an API call. This timeout covers the entire client execution except for marshalling. This includes request handler execution, all HTTP requests including retries, unmarshalling, etc. This value should always be positive, if present. +- **retry-policy** - Configure the retry policy that should be used when handling failure cases. + - **retry-count** - Specify the maximum number of times that a single request should be retried, assuming it fails for a retryable error + - **additional-retry-conditions-allowed** - Specify whether further conditions can be added to this policy after it is created. + - **backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry attempts. If the retry is because of throttling reasons, the `throttling-backoff-strategy` is used instead. [See available Backoff Strategies](#Backoff-Strategies) + - **throttling-backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry attempts after a throttling error is encountered. If the retry is not because of throttling reasons, the `backoff-strategy` is used instead. [See available Backoff Strategies](#Backoff-Strategies) + - **retry-condition** - Specify the retry condition under which the request should be retried. [See available Retry Conditions](#Retry-Conditions) + - **retry-capacity-condition** - Specify the retry condition that should be used to throttle the number of retries attempted by the SDK client as a whole. [See available Retry Conditions](#Retry-Conditions) + +### Backoff Strategies +- **equal-jitter** - Backoff strategy that uses equal jitter for computing the delay before the next retry. + - **base-delay** - The base delay to be used for the jitter calculation. + - **max-backoff-time** - The max-backoff [time](#Time) to be used for the jitter calculation. +- **full-jitter** - Backoff strategy that uses a full jitter strategy for computing the next backoff delay. + - **base-delay** - The base delay to be used for the jitter calculation. + - **max-backoff-time** - The max-backoff [time](#Time) to be used for the jitter calculation. +- **fixed-backoff** - Simple backoff strategy that always uses a fixed delay for the delay before the next retry attempt. + - **delay** - The delay between the retry attempts. + +### Retry Conditions +- **and-retry-condition** - Composite retry condition that evaluates to true when all contained retry conditions evaluate to true. + - A list of retry conditions that are checked for all to be true to satisfy the retry condition. +- **or-retry-condition** - Composite retry condition that evaluates to true if any containing condition evaluates to true. + - A list of retry condition that are checked for any one of them to be true to satisfy teh condition. +- **retry-on-error-codes-condition** - Retry condition implementation that retries if the exception, or the cause of the exception matches the error codes defined. + - **retryable-error-codes** - A list of string specifying the error codes to match for retrying. +- **retry-on-status-codes-condition** - Retry condition implementation that retries if the HTTP status code matches one of the provided status codes. + - **retryable-status-codes** - A list of integers specifying the error codes to match for retrying. +- **max-number-of-retry-condition** - Simple retry condition that allows retries up to a certain max number of retries. + - **retry-count** - An integer specifying the max number of retries allowed. +- **retry-on-throttling-condition** - A retry condition that will return `true` if the provided exception seems to be due to a throttling error from the service to the client. + +#### Time +Time is specified as a string with formats based on the ISO-8601 duration format `PnDTnHnMn.nS` with days considered to be exactly 24 hours. +[See here for more details.](https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-) From d591f3827af4567821750995be4e3700e8a68f8f Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 18:59:49 -0400 Subject: [PATCH 10/12] Refactor code - Remove duplication by introducing abstract classes with common code. - Update error handling to handle error which are parent specific. --- ...ClientConfigurationDirectiveProcessor.java | 14 +- .../ClientConfigurationUtils.java | 2 + .../AbstractBackoffStrategy.java | 84 ++++++++++ .../backoffstrategies/BackoffStrategy.java | 59 +------ .../ThrottlingBackoffStrategy.java | 59 +------ .../AbstractRetryCondition.java | 156 ++++++++++++++++++ .../CapacityRetryCondition.java | 105 +----------- .../retryconditions/RetryCondition.java | 105 +----------- 8 files changed, 266 insertions(+), 318 deletions(-) create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/AbstractBackoffStrategy.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AbstractRetryCondition.java diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java index 4479de430..b6679bfed 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationDirectiveProcessor.java @@ -29,6 +29,7 @@ import gyro.core.directive.DirectiveProcessor; import gyro.core.scope.RootScope; import gyro.core.scope.Scope; +import gyro.lang.ast.Node; import gyro.lang.ast.block.DirectiveNode; import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; @@ -108,8 +109,17 @@ private Object process(Class configClass, RootScope scope, Scope bodyScope) { try { ((ClientConfigurationInterface) configClassObj).validate(); } catch (ClientConfigurationException ex) { - if (ex.getField() != null) { - throw new GyroException(bodyScope.getLocation(ex.getField()), ex.getFormattedMessage()); + if (!ObjectUtils.isBlank(ex.getField())) { + Node node = bodyScope.getLocation(ex.getField()); + if (node != null) { + throw new GyroException(bodyScope.getLocation(ex.getField()), ex.getFormattedMessage()); + } + } + + Node parent = bodyScope.getParent() + .getLocation(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, configClass.getSimpleName())); + if (parent != null) { + throw new GyroException(parent, ex.getFormattedMessage()); } else { throw new GyroException(ex.getFormattedMessage()); } diff --git a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java index 45c6bdf07..b59b452e7 100644 --- a/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java +++ b/src/main/java/gyro/aws/clientconfiguration/ClientConfigurationUtils.java @@ -40,6 +40,8 @@ public static void validate(String duration, String fieldName) { parse(duration); } catch (DateTimeParseException ex) { throw new ClientConfigurationException(fieldName, String.format("Time format '%s' is invalid.", duration)); + } catch (NullPointerException npe) { + throw new ClientConfigurationException(fieldName, "Is required."); } } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/AbstractBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/AbstractBackoffStrategy.java new file mode 100644 index 000000000..e4e2a8a3e --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/AbstractBackoffStrategy.java @@ -0,0 +1,84 @@ +/* + * Copyright 2021, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationException; +import gyro.aws.clientconfiguration.ClientConfigurationInterface; + +public abstract class AbstractBackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { + + private FixedDelay fixedDelay; + private FullJitter fullJitter; + private EqualJitter equalJitter; + + abstract String getBackoffStrategyType(); + + public FixedDelay getFixedDelay() { + return fixedDelay; + } + + public void setFixedDelay(FixedDelay fixedDelay) { + this.fixedDelay = fixedDelay; + } + + public FullJitter getFullJitter() { + return fullJitter; + } + + public void setFullJitter(FullJitter fullJitter) { + this.fullJitter = fullJitter; + } + + public EqualJitter getEqualJitter() { + return equalJitter; + } + + public void setEqualJitter(EqualJitter equalJitter) { + this.equalJitter = equalJitter; + } + + @Override + public void validate() { + long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); + + if (count > 1) { + throw new ClientConfigurationException( + null, + String.format( + "Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed for '%s'.", + getBackoffStrategyType())); + } else if (count == 0) { + throw new ClientConfigurationException( + null, + String.format( + "One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required for '%s'.", + getBackoffStrategyType())); + } + } + + @Override + public software.amazon.awssdk.core.retry.backoff.BackoffStrategy toBackoffStrategy() { + return Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()) + .filter(Objects::nonNull) + .findFirst() + .get() + .toBackoffStrategy(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java index 99d1c74a5..2c879cb34 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/BackoffStrategy.java @@ -16,63 +16,10 @@ package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; -import java.util.Objects; -import java.util.stream.Stream; - -import gyro.aws.clientconfiguration.ClientConfigurationException; -import gyro.aws.clientconfiguration.ClientConfigurationInterface; - -public class BackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { - - private FixedDelay fixedDelay; - private FullJitter fullJitter; - private EqualJitter equalJitter; - - public FixedDelay getFixedDelay() { - return fixedDelay; - } - - public void setFixedDelay(FixedDelay fixedDelay) { - this.fixedDelay = fixedDelay; - } - - public FullJitter getFullJitter() { - return fullJitter; - } - - public void setFullJitter(FullJitter fullJitter) { - this.fullJitter = fullJitter; - } - - public EqualJitter getEqualJitter() { - return equalJitter; - } - - public void setEqualJitter(EqualJitter equalJitter) { - this.equalJitter = equalJitter; - } - - @Override - public void validate() { - long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); - - if (count > 1) { - throw new ClientConfigurationException( - "backoff-strategy", - "Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); - } else if (count == 0) { - throw new ClientConfigurationException( - "backoff-strategy", - "One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); - } - } +public class BackoffStrategy extends AbstractBackoffStrategy { @Override - public software.amazon.awssdk.core.retry.backoff.BackoffStrategy toBackoffStrategy() { - return Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()) - .filter(Objects::nonNull) - .findFirst() - .get() - .toBackoffStrategy(); + String getBackoffStrategyType() { + return "backoff-strategy"; } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java index c96138f01..0a2a33d29 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/backoffstrategies/ThrottlingBackoffStrategy.java @@ -16,63 +16,10 @@ package gyro.aws.clientconfiguration.retrypolicy.backoffstrategies; -import java.util.Objects; -import java.util.stream.Stream; - -import gyro.aws.clientconfiguration.ClientConfigurationException; -import gyro.aws.clientconfiguration.ClientConfigurationInterface; - -public class ThrottlingBackoffStrategy implements BackoffStrategyInterface, ClientConfigurationInterface { - - private FixedDelay fixedDelay; - private FullJitter fullJitter; - private EqualJitter equalJitter; - - public FixedDelay getFixedDelay() { - return fixedDelay; - } - - public void setFixedDelay(FixedDelay fixedDelay) { - this.fixedDelay = fixedDelay; - } - - public FullJitter getFullJitter() { - return fullJitter; - } - - public void setFullJitter(FullJitter fullJitter) { - this.fullJitter = fullJitter; - } - - public EqualJitter getEqualJitter() { - return equalJitter; - } - - public void setEqualJitter(EqualJitter equalJitter) { - this.equalJitter = equalJitter; - } - - @Override - public void validate() { - long count = Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()).filter(Objects::nonNull).count(); - - if (count > 1) { - throw new ClientConfigurationException( - "throttling-backoff-strategy", - "Only one of 'fixed-delay', 'full-jitter' or 'equal-jitter' is allowed."); - } else if (count == 0) { - throw new ClientConfigurationException( - "throttling-backoff-strategy", - "One of 'fixed-delay', 'full-jitter' or 'equal-jitter' is required."); - } - } +public class ThrottlingBackoffStrategy extends AbstractBackoffStrategy { @Override - public software.amazon.awssdk.core.retry.backoff.BackoffStrategy toBackoffStrategy() { - return Stream.of(getEqualJitter(), getFullJitter(), getFixedDelay()) - .filter(Objects::nonNull) - .findFirst() - .get() - .toBackoffStrategy(); + String getBackoffStrategyType() { + return "throttling-backoff-strategy"; } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AbstractRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AbstractRetryCondition.java new file mode 100644 index 000000000..57cd4d4ce --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/AbstractRetryCondition.java @@ -0,0 +1,156 @@ +/* + * Copyright 2021, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationException; +import gyro.aws.clientconfiguration.ClientConfigurationInterface; + +public abstract class AbstractRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private AndRetryCondition andRetryCondition; + private OrRetryCondition orRetryCondition; + private MaxNumberOfRetryCondition maxNumberOfRetryCondition; + private RetryOnErrorCodesCondition retryOnErrorCodesCondition; + private RetryOnStatusCodesCondition retryOnStatusCodesCondition; + private RetryOnThrottlingCondition retryOnThrottlingCondition; + private RetryOnClockSkewCondition retryOnClockSkewCondition; + private TokenBucketRetryCondition tokenBucketRetryCondition; + + abstract String getRetryConditionType(); + + public AndRetryCondition getAndRetryCondition() { + return andRetryCondition; + } + + public void setAndRetryCondition(AndRetryCondition andRetryCondition) { + this.andRetryCondition = andRetryCondition; + } + + public OrRetryCondition getOrRetryCondition() { + return orRetryCondition; + } + + public void setOrRetryCondition(OrRetryCondition orRetryCondition) { + this.orRetryCondition = orRetryCondition; + } + + public MaxNumberOfRetryCondition getMaxNumberOfRetryCondition() { + return maxNumberOfRetryCondition; + } + + public void setMaxNumberOfRetryCondition(MaxNumberOfRetryCondition maxNumberOfRetryCondition) { + this.maxNumberOfRetryCondition = maxNumberOfRetryCondition; + } + + public RetryOnErrorCodesCondition getRetryOnErrorCodesCondition() { + return retryOnErrorCodesCondition; + } + + public void setRetryOnErrorCodesCondition(RetryOnErrorCodesCondition retryOnErrorCodesCondition) { + this.retryOnErrorCodesCondition = retryOnErrorCodesCondition; + } + + public RetryOnStatusCodesCondition getRetryOnStatusCodesCondition() { + return retryOnStatusCodesCondition; + } + + public void setRetryOnStatusCodesCondition(RetryOnStatusCodesCondition retryOnStatusCodesCondition) { + this.retryOnStatusCodesCondition = retryOnStatusCodesCondition; + } + + public RetryOnThrottlingCondition getRetryOnThrottlingCondition() { + return retryOnThrottlingCondition; + } + + public void setRetryOnThrottlingCondition(RetryOnThrottlingCondition retryOnThrottlingCondition) { + this.retryOnThrottlingCondition = retryOnThrottlingCondition; + } + + public RetryOnClockSkewCondition getRetryOnClockSkewCondition() { + return retryOnClockSkewCondition; + } + + public void setRetryOnClockSkewCondition(RetryOnClockSkewCondition retryOnClockSkewCondition) { + this.retryOnClockSkewCondition = retryOnClockSkewCondition; + } + + public TokenBucketRetryCondition getTokenBucketRetryCondition() { + return tokenBucketRetryCondition; + } + + public void setTokenBucketRetryCondition(TokenBucketRetryCondition tokenBucketRetryCondition) { + this.tokenBucketRetryCondition = tokenBucketRetryCondition; + } + + @Override + public void validate() { + long count = Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition(), + getRetryOnClockSkewCondition(), + getTokenBucketRetryCondition()) + .filter(Objects::nonNull).count(); + + if (count > 1) { + throw new ClientConfigurationException( + null, + String.format("Only one of" + + " 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " 'retry-on-throttling-condition'" + + " 'retry-on-clock-screw-condition'" + + " or 'token-bucket-retry-condition'" + + " is allowed for '%s'.", getRetryConditionType())); + } else if (count == 0) { + throw new ClientConfigurationException( + null, + String.format("One of" + + " 'and-retry-condition'," + + " 'or-retry-condition'," + + " 'max-number-of-retry-condition'," + + " 'retry-on-error-codes-condition'," + + " 'retry-on-status-codes-condition'" + + " 'retry-on-throttling-condition'" + + " 'retry-on-clock-screw-condition'" + + " or 'token-bucket-retry-condition'" + + " is required for '%s'.", getRetryConditionType())); + } + } + + @Override + public software.amazon.awssdk.core.retry.conditions.RetryCondition toRetryCondition() { + return Stream.of( + getAndRetryCondition(), + getOrRetryCondition(), + getMaxNumberOfRetryCondition(), + getRetryOnErrorCodesCondition(), + getRetryOnStatusCodesCondition(), + getRetryOnThrottlingCondition(), + getRetryOnClockSkewCondition(), + getTokenBucketRetryCondition()).filter(Objects::nonNull).findFirst().get().toRetryCondition(); + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java index f62cccfda..21ac777a6 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/CapacityRetryCondition.java @@ -16,109 +16,10 @@ package gyro.aws.clientconfiguration.retrypolicy.retryconditions; -import java.util.Objects; -import java.util.stream.Stream; - -import gyro.aws.clientconfiguration.ClientConfigurationException; -import gyro.aws.clientconfiguration.ClientConfigurationInterface; - -public class CapacityRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { - - private AndRetryCondition andRetryCondition; - private OrRetryCondition orRetryCondition; - private MaxNumberOfRetryCondition maxNumberOfRetryCondition; - private RetryOnErrorCodesCondition retryOnErrorCodesCondition; - private RetryOnStatusCodesCondition retryOnStatusCodesCondition; - private RetryOnThrottlingCondition retryOnThrottlingCondition; - - public AndRetryCondition getAndRetryCondition() { - return andRetryCondition; - } - - public void setAndRetryCondition(AndRetryCondition andRetryCondition) { - this.andRetryCondition = andRetryCondition; - } - - public OrRetryCondition getOrRetryCondition() { - return orRetryCondition; - } - - public void setOrRetryCondition(OrRetryCondition orRetryCondition) { - this.orRetryCondition = orRetryCondition; - } - - public MaxNumberOfRetryCondition getMaxNumberOfRetryCondition() { - return maxNumberOfRetryCondition; - } - - public void setMaxNumberOfRetryCondition(MaxNumberOfRetryCondition maxNumberOfRetryCondition) { - this.maxNumberOfRetryCondition = maxNumberOfRetryCondition; - } - - public RetryOnErrorCodesCondition getRetryOnErrorCodesCondition() { - return retryOnErrorCodesCondition; - } - - public void setRetryOnErrorCodesCondition(RetryOnErrorCodesCondition retryOnErrorCodesCondition) { - this.retryOnErrorCodesCondition = retryOnErrorCodesCondition; - } - - public RetryOnStatusCodesCondition getRetryOnStatusCodesCondition() { - return retryOnStatusCodesCondition; - } - - public void setRetryOnStatusCodesCondition(RetryOnStatusCodesCondition retryOnStatusCodesCondition) { - this.retryOnStatusCodesCondition = retryOnStatusCodesCondition; - } - - public RetryOnThrottlingCondition getRetryOnThrottlingCondition() { - return retryOnThrottlingCondition; - } - - public void setRetryOnThrottlingCondition(RetryOnThrottlingCondition retryOnThrottlingCondition) { - this.retryOnThrottlingCondition = retryOnThrottlingCondition; - } - - @Override - public void validate() { - long count = Stream.of( - getAndRetryCondition(), - getOrRetryCondition(), - getMaxNumberOfRetryCondition(), - getRetryOnErrorCodesCondition(), - getRetryOnStatusCodesCondition(), - getRetryOnThrottlingCondition()) - .filter(Objects::nonNull).count(); - - if (count > 1) { - throw new ClientConfigurationException( - "retry-condition", - "Only one of 'and-retry-condition'," - + " 'or-retry-condition'," - + " 'max-number-of-retry-condition'," - + " 'retry-on-error-codes-condition'," - + " 'retry-on-status-codes-condition'" - + " or 'retry-on-throttling-condition' is allowed."); - } else if (count == 0) { - throw new ClientConfigurationException( - "retry-condition", - "One of 'and-retry-condition'," - + " 'or-retry-condition'," - + " 'max-number-of-retry-condition'," - + " 'retry-on-error-codes-condition'," - + " 'retry-on-status-codes-condition'" - + " or 'retry-on-throttling-condition' is required."); - } - } +public class CapacityRetryCondition extends AbstractRetryCondition { @Override - public software.amazon.awssdk.core.retry.conditions.RetryCondition toRetryCondition() { - return Stream.of( - getAndRetryCondition(), - getOrRetryCondition(), - getMaxNumberOfRetryCondition(), - getRetryOnErrorCodesCondition(), - getRetryOnStatusCodesCondition(), - getRetryOnThrottlingCondition()).filter(Objects::nonNull).findFirst().get().toRetryCondition(); + String getRetryConditionType() { + return "capacity-retry-condition"; } } diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java index 5d7a73d5c..a5db9bc3c 100644 --- a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryCondition.java @@ -16,109 +16,10 @@ package gyro.aws.clientconfiguration.retrypolicy.retryconditions; -import java.util.Objects; -import java.util.stream.Stream; - -import gyro.aws.clientconfiguration.ClientConfigurationException; -import gyro.aws.clientconfiguration.ClientConfigurationInterface; - -public class RetryCondition implements RetryConditionInterface, ClientConfigurationInterface { - - private AndRetryCondition andRetryCondition; - private OrRetryCondition orRetryCondition; - private MaxNumberOfRetryCondition maxNumberOfRetryCondition; - private RetryOnErrorCodesCondition retryOnErrorCodesCondition; - private RetryOnStatusCodesCondition retryOnStatusCodesCondition; - private RetryOnThrottlingCondition retryOnThrottlingCondition; - - public AndRetryCondition getAndRetryCondition() { - return andRetryCondition; - } - - public void setAndRetryCondition(AndRetryCondition andRetryCondition) { - this.andRetryCondition = andRetryCondition; - } - - public OrRetryCondition getOrRetryCondition() { - return orRetryCondition; - } - - public void setOrRetryCondition(OrRetryCondition orRetryCondition) { - this.orRetryCondition = orRetryCondition; - } - - public MaxNumberOfRetryCondition getMaxNumberOfRetryCondition() { - return maxNumberOfRetryCondition; - } - - public void setMaxNumberOfRetryCondition(MaxNumberOfRetryCondition maxNumberOfRetryCondition) { - this.maxNumberOfRetryCondition = maxNumberOfRetryCondition; - } - - public RetryOnErrorCodesCondition getRetryOnErrorCodesCondition() { - return retryOnErrorCodesCondition; - } - - public void setRetryOnErrorCodesCondition(RetryOnErrorCodesCondition retryOnErrorCodesCondition) { - this.retryOnErrorCodesCondition = retryOnErrorCodesCondition; - } - - public RetryOnStatusCodesCondition getRetryOnStatusCodesCondition() { - return retryOnStatusCodesCondition; - } - - public void setRetryOnStatusCodesCondition(RetryOnStatusCodesCondition retryOnStatusCodesCondition) { - this.retryOnStatusCodesCondition = retryOnStatusCodesCondition; - } - - public RetryOnThrottlingCondition getRetryOnThrottlingCondition() { - return retryOnThrottlingCondition; - } - - public void setRetryOnThrottlingCondition(RetryOnThrottlingCondition retryOnThrottlingCondition) { - this.retryOnThrottlingCondition = retryOnThrottlingCondition; - } - - @Override - public void validate() { - long count = Stream.of( - getAndRetryCondition(), - getOrRetryCondition(), - getMaxNumberOfRetryCondition(), - getRetryOnErrorCodesCondition(), - getRetryOnStatusCodesCondition(), - getRetryOnThrottlingCondition()) - .filter(Objects::nonNull).count(); - - if (count > 1) { - throw new ClientConfigurationException( - "retry-condition", - "Only one of 'and-retry-condition'," - + " 'or-retry-condition'," - + " 'max-number-of-retry-condition'," - + " 'retry-on-error-codes-condition'," - + " 'retry-on-status-codes-condition'" - + " or 'retry-on-throttling-condition' is allowed."); - } else if (count == 0) { - throw new ClientConfigurationException( - "retry-condition", - "One of 'and-retry-condition'," - + " 'or-retry-condition'," - + " 'max-number-of-retry-condition'," - + " 'retry-on-error-codes-condition'," - + " 'retry-on-status-codes-condition'" - + " or 'retry-on-throttling-condition' is required."); - } - } +public class RetryCondition extends AbstractRetryCondition { @Override - public software.amazon.awssdk.core.retry.conditions.RetryCondition toRetryCondition() { - return Stream.of( - getAndRetryCondition(), - getOrRetryCondition(), - getMaxNumberOfRetryCondition(), - getRetryOnErrorCodesCondition(), - getRetryOnStatusCodesCondition(), - getRetryOnThrottlingCondition()).filter(Objects::nonNull).findFirst().get().toRetryCondition(); + String getRetryConditionType() { + return "retry-condition"; } } From ce215c462fb5ee70b14356a224aabd02a255d9b2 Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 19:00:46 -0400 Subject: [PATCH 11/12] Add two more retry condition - TokenBucketRetryCondition - RetryOnClockSkewCondition --- .../RetryOnClockSkewCondition.java | 33 +++++++ .../TokenBucketRetryCondition.java | 93 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnClockSkewCondition.java create mode 100644 src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/TokenBucketRetryCondition.java diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnClockSkewCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnClockSkewCondition.java new file mode 100644 index 000000000..42272bd27 --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/RetryOnClockSkewCondition.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; + +public class RetryOnClockSkewCondition implements RetryConditionInterface, ClientConfigurationInterface { + + @Override + public RetryCondition toRetryCondition() { + return software.amazon.awssdk.core.retry.conditions.RetryOnClockSkewCondition.create(); + } + + @Override + public void validate() { + + } +} diff --git a/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/TokenBucketRetryCondition.java b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/TokenBucketRetryCondition.java new file mode 100644 index 000000000..750f9daca --- /dev/null +++ b/src/main/java/gyro/aws/clientconfiguration/retrypolicy/retryconditions/TokenBucketRetryCondition.java @@ -0,0 +1,93 @@ +/* + * Copyright 2021, Brightspot, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License 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 gyro.aws.clientconfiguration.retrypolicy.retryconditions; + +import java.util.Objects; +import java.util.stream.Stream; + +import gyro.aws.clientconfiguration.ClientConfigurationException; +import gyro.aws.clientconfiguration.ClientConfigurationInterface; +import software.amazon.awssdk.core.retry.conditions.RetryCondition; +import software.amazon.awssdk.core.retry.conditions.TokenBucketExceptionCostFunction; + +public class TokenBucketRetryCondition implements RetryConditionInterface, ClientConfigurationInterface { + + private Integer bucketSize; + private Integer exceptionCost; + private Integer throttlingExceptionCost; + + public Integer getBucketSize() { + return bucketSize; + } + + public void setBucketSize(Integer bucketSize) { + this.bucketSize = bucketSize; + } + + public Integer getExceptionCost() { + return exceptionCost; + } + + public void setExceptionCost(Integer exceptionCost) { + this.exceptionCost = exceptionCost; + } + + public Integer getThrottlingExceptionCost() { + return throttlingExceptionCost; + } + + public void setThrottlingExceptionCost(Integer throttlingExceptionCost) { + this.throttlingExceptionCost = throttlingExceptionCost; + } + + @Override + public void validate() { + if (getBucketSize() == null || getBucketSize() < 1) { + throw new ClientConfigurationException("bucket-size", "Is required and cannot be less that 1."); + } + + long count = Stream.of(getExceptionCost(), getThrottlingExceptionCost()).filter(Objects::nonNull).count(); + if (count != 1) { + throw new ClientConfigurationException( + null, + "Either both of 'exception-cost' or 'throttling-exception-cost' is allowed or none."); + } else if (getExceptionCost() != null && getExceptionCost() < 1) { + throw new ClientConfigurationException("exception-cost", "Cannot be less that 1."); + } else if (getThrottlingExceptionCost() != null && getExceptionCost() < 1) { + throw new ClientConfigurationException("throttling-exception-cost", "Cannot be less that 1."); + } + } + + @Override + public RetryCondition toRetryCondition() { + software.amazon.awssdk.core.retry.conditions.TokenBucketRetryCondition.Builder builder = software.amazon.awssdk.core.retry.conditions.TokenBucketRetryCondition + .builder(); + + builder.tokenBucketSize(getBucketSize()); + if (getExceptionCost() != null) { + builder.exceptionCostFunction(TokenBucketExceptionCostFunction.builder() + .defaultExceptionCost(getExceptionCost()) + .throttlingExceptionCost(getThrottlingExceptionCost()) + .build()); + + } else { + builder.exceptionCostFunction(TokenBucketExceptionCostFunction.builder().build()); + } + + return builder.build(); + } +} From 688e3e8b69cce4fd2083c98cc5ae72d2970eff15 Mon Sep 17 00:00:00 2001 From: Deepanjan Bhattacharyya Date: Wed, 28 Apr 2021 19:00:52 -0400 Subject: [PATCH 12/12] Update README.MD --- .../gyro/aws/clientconfiguration/README.MD | 91 ++++++++++++++----- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/src/main/java/gyro/aws/clientconfiguration/README.MD b/src/main/java/gyro/aws/clientconfiguration/README.MD index ea9c64633..97a006b86 100644 --- a/src/main/java/gyro/aws/clientconfiguration/README.MD +++ b/src/main/java/gyro/aws/clientconfiguration/README.MD @@ -1,4 +1,5 @@ # AWS Client override configuration + The AWS **client-configuration** allows you to override the default client creation options. You define the `client-configuration` directive in your `.init.gyro` file. @@ -27,7 +28,9 @@ If no config name is given, it is treated as `default` and is used as the defaul @end ``` -Multiple client-configuration directives can be defined using different names. These can be associated with individual credential directives. In doing so all assets using that credential will create the aws client with overrides as defined by the mentioned client configuration. +Multiple client-configuration directives can be defined using different names. These can be associated with individual +credential directives. In doing so all assets using that credential will create the aws client with overrides as defined +by the mentioned client configuration. ``` @credentials 'enterprise::aws-credentials' 'east-2' @@ -71,56 +74,98 @@ Multiple client-configuration directives can be defined using different names. T end @end ``` -In this case, all assets using the `east-2` credentials will create there respective aws clients using the overrides defined in the client-configuration named `east-2-config`. + +In this case, all assets using the `east-2` credentials will create there respective aws clients using the overrides +defined in the client-configuration named `east-2-config`. ## Configuration Details The client-configuration has the following options: + - **http-client-configuration** - Http configuration for the client. [See options](#Http-Client-Configuration) -- **override-client-configuration** - Override configuration for the client. [See options](#Override-Client-Configuration) +- **override-client-configuration** - Override configuration for the + client. [See options](#Override-Client-Configuration) ### Http Client Configuration -- **socket-timeout** - The amount of [time](#Time) to wait for data to be transferred over an established, open connection before the connection is timed out. A duration of `0` means infinity, and is not recommended. -- **connection-timeout** - The amount of [time](#Time) to wait when initially establishing a connection before giving up and timing out. A duration of `0` means infinity, and is not recommended. -- **connection-acquisition-timeout** - The amount of [time](#Time) to wait when acquiring a connection from the pool before giving up and timing out. + +- **socket-timeout** - The amount of [time](#Time) to wait for data to be transferred over an established, open + connection before the connection is timed out. A duration of `0` means infinity, and is not recommended. +- **connection-timeout** - The amount of [time](#Time) to wait when initially establishing a connection before giving up + and timing out. A duration of `0` means infinity, and is not recommended. +- **connection-acquisition-timeout** - The amount of [time](#Time) to wait when acquiring a connection from the pool + before giving up and timing out. - **max-connections** - The maximum number of connections allowed in the connection pool. -- **expect-continue-enabled** - Configure whether the client should send an HTTP expect-continue handshake before each request. -- **connection-time-to-live** - The maximum amount of [time](#Time) that a connection should be allowed to remain open, regardless of usage frequency. -- **connection-max-idle-time** - Configure the maximum amount of [time](#Time) that a connection should be allowed to remain open while idle. +- **expect-continue-enabled** - Configure whether the client should send an HTTP expect-continue handshake before each + request. +- **connection-time-to-live** - The maximum amount of [time](#Time) that a connection should be allowed to remain open, + regardless of usage frequency. +- **connection-max-idle-time** - Configure the maximum amount of [time](#Time) that a connection should be allowed to + remain open while idle. ### Override Client Configuration -- **api-call-timeout** - Specify the amount of [time](#Time) to allow the client to complete the execution of an API call. This timeout covers the entire client execution except for marshalling. This includes request handler execution, all HTTP requests including retries, unmarshalling, etc. This value should always be positive, if present. + +- **api-call-timeout** - Specify the amount of [time](#Time) to allow the client to complete the execution of an API + call. This timeout covers the entire client execution except for marshalling. This includes request handler execution, + all HTTP requests including retries, unmarshalling, etc. This value should always be positive, if present. - **retry-policy** - Configure the retry policy that should be used when handling failure cases. - - **retry-count** - Specify the maximum number of times that a single request should be retried, assuming it fails for a retryable error - - **additional-retry-conditions-allowed** - Specify whether further conditions can be added to this policy after it is created. - - **backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry attempts. If the retry is because of throttling reasons, the `throttling-backoff-strategy` is used instead. [See available Backoff Strategies](#Backoff-Strategies) - - **throttling-backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry attempts after a throttling error is encountered. If the retry is not because of throttling reasons, the `backoff-strategy` is used instead. [See available Backoff Strategies](#Backoff-Strategies) - - **retry-condition** - Specify the retry condition under which the request should be retried. [See available Retry Conditions](#Retry-Conditions) - - **retry-capacity-condition** - Specify the retry condition that should be used to throttle the number of retries attempted by the SDK client as a whole. [See available Retry Conditions](#Retry-Conditions) + - **retry-count** - Specify the maximum number of times that a single request should be retried, assuming it fails + for a retryable error + - **additional-retry-conditions-allowed** - Specify whether further conditions can be added to this policy after it + is created. + - **backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry attempts. If + the retry is because of throttling reasons, the `throttling-backoff-strategy` is used + instead. [See available Backoff Strategies](#Backoff-Strategies) + - **throttling-backoff-strategy** - Specify the backoff strategy that should be used for waiting in between retry + attempts after a throttling error is encountered. If the retry is not because of throttling reasons, + the `backoff-strategy` is used instead. [See available Backoff Strategies](#Backoff-Strategies) + - **retry-condition** - Specify the retry condition under which the request should be + retried. [See available Retry Conditions](#Retry-Conditions) + - **retry-capacity-condition** - Specify the retry condition that should be used to throttle the number of retries + attempted by the SDK client as a whole. [See available Retry Conditions](#Retry-Conditions) ### Backoff Strategies + - **equal-jitter** - Backoff strategy that uses equal jitter for computing the delay before the next retry. - **base-delay** - The base delay to be used for the jitter calculation. - **max-backoff-time** - The max-backoff [time](#Time) to be used for the jitter calculation. - **full-jitter** - Backoff strategy that uses a full jitter strategy for computing the next backoff delay. - **base-delay** - The base delay to be used for the jitter calculation. - **max-backoff-time** - The max-backoff [time](#Time) to be used for the jitter calculation. -- **fixed-backoff** - Simple backoff strategy that always uses a fixed delay for the delay before the next retry attempt. +- **fixed-backoff** - Simple backoff strategy that always uses a fixed delay for the delay before the next retry + attempt. - **delay** - The delay between the retry attempts. ### Retry Conditions -- **and-retry-condition** - Composite retry condition that evaluates to true when all contained retry conditions evaluate to true. + +- **and-retry-condition** - Composite retry condition that evaluates to true when all contained retry conditions + evaluate to true. - A list of retry conditions that are checked for all to be true to satisfy the retry condition. -- **or-retry-condition** - Composite retry condition that evaluates to true if any containing condition evaluates to true. +- **or-retry-condition** - Composite retry condition that evaluates to true if any containing condition evaluates to + true. - A list of retry condition that are checked for any one of them to be true to satisfy teh condition. -- **retry-on-error-codes-condition** - Retry condition implementation that retries if the exception, or the cause of the exception matches the error codes defined. +- **retry-on-error-codes-condition** - Retry condition implementation that retries if the exception, or the cause of the + exception matches the error codes defined. - **retryable-error-codes** - A list of string specifying the error codes to match for retrying. -- **retry-on-status-codes-condition** - Retry condition implementation that retries if the HTTP status code matches one of the provided status codes. +- **retry-on-status-codes-condition** - Retry condition implementation that retries if the HTTP status code matches one + of the provided status codes. - **retryable-status-codes** - A list of integers specifying the error codes to match for retrying. - **max-number-of-retry-condition** - Simple retry condition that allows retries up to a certain max number of retries. - **retry-count** - An integer specifying the max number of retries allowed. -- **retry-on-throttling-condition** - A retry condition that will return `true` if the provided exception seems to be due to a throttling error from the service to the client. +- **token-bucket-retry-condition** - A retry condition that limits the number of retries made by the SDK using a token + bucket algorithm. + - **bucket-size** - An integer specifying the maximum number of tokens in the token bucket. This is also used as the + initial value for the number of tokens in the bucket. + - **exception-cost** - An integer specifying the number of tokens that should be removed from the token bucket when + no other exception type in this function is matched. + - **throttling-exception-cost** - An integer specifying the number of tokens that should be removed from the token + bucket when throttling exceptions. +- **retry-on-throttling-condition** - A retry condition that will return `true` if the provided exception seems to be + due to a throttling error from the service to the client. +- **retry-on-clock-screw-condition** - A retry condition that will return true if the provided exception seems to be due + to a clock skew between the client and service. #### Time -Time is specified as a string with formats based on the ISO-8601 duration format `PnDTnHnMn.nS` with days considered to be exactly 24 hours. + +Time is specified as a string with formats based on the ISO-8601 duration format `PnDTnHnMn.nS` with days considered to +be exactly 24 hours. [See here for more details.](https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-)