1 /*
2  * Copyright 2011-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15 package com.amazonaws.retry;
16
17 import com.amazonaws.AmazonClientException;
18 import com.amazonaws.AmazonWebServiceRequest;
19 import com.amazonaws.ClientConfiguration;
20 import com.amazonaws.annotation.SdkInternalApi;
21 import com.amazonaws.retry.internal.MaxAttemptsResolver;
22 import com.amazonaws.retry.v2.RetryPolicyContext;
23
24 import static com.amazonaws.retry.PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY_STANDARD_MODE;
25 import static com.amazonaws.util.ValidationUtils.assertNotNull;
26
27 /**
28  * Adapts a legacy {@link RetryPolicy} to the new {@link com.amazonaws.retry.v2.RetryPolicy}. This class is intended for internal
29  * use by the SDK.
30  */

31 @SdkInternalApi
32 public class RetryPolicyAdapter implements com.amazonaws.retry.v2.RetryPolicy {
33     private final RetryPolicy legacyRetryPolicy;
34     private final ClientConfiguration clientConfiguration;
35     private final int maxErrorRetry;
36
37     public RetryPolicyAdapter(RetryPolicy legacyRetryPolicy, ClientConfiguration clientConfiguration) {
38         this.legacyRetryPolicy = assertNotNull(legacyRetryPolicy, "legacyRetryPolicy");
39         this.clientConfiguration = assertNotNull(clientConfiguration, "clientConfiguration");
40         this.maxErrorRetry = resolveMaxErrorRetry();
41     }
42
43     @Override
44     public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
45         return legacyRetryPolicy.getBackoffStrategy().delayBeforeNextRetry(
46                 (AmazonWebServiceRequest) context.originalRequest(),
47                 (AmazonClientException) context.exception(),
48                 context.retriesAttempted());
49     }
50
51     @Override
52     public boolean shouldRetry(RetryPolicyContext context) {
53         return !maxRetriesExceeded(context) && isRetryable(context);
54     }
55
56     public boolean isRetryable(RetryPolicyContext context) {
57         return legacyRetryPolicy.getRetryCondition().shouldRetry(
58             (AmazonWebServiceRequest) context.originalRequest(),
59             (AmazonClientException) context.exception(),
60             context.retriesAttempted());
61     }
62
63     public RetryPolicy getLegacyRetryPolicy() {
64         return this.legacyRetryPolicy;
65     }
66
67     private int resolveMaxErrorRetry() {
68         if(legacyRetryPolicy.isMaxErrorRetryInClientConfigHonored() && clientConfiguration.getMaxErrorRetry() >= 0) {
69             return clientConfiguration.getMaxErrorRetry();
70         }
71
72         Integer resolvedMaxAttempts = new MaxAttemptsResolver().maxAttempts();
73
74         if (resolvedMaxAttempts != null) {
75             return resolvedMaxAttempts - 1;
76         }
77
78         if (shouldUseStandardModeDefaultMaxRetry()) {
79             return DEFAULT_MAX_ERROR_RETRY_STANDARD_MODE;
80         }
81
82         // default to use legacyRetryPolicy.getMaxErrorRetry() because it's always present
83         return legacyRetryPolicy.getMaxErrorRetry();
84     }
85
86     /**
87      * We should use the default standard maxErrorRetry for standard mode if the maxErrorRetry is not from sdk
88      * default predefined retry policies.
89      */

90     private boolean shouldUseStandardModeDefaultMaxRetry() {
91         RetryMode retryMode = clientConfiguration.getRetryMode() == null ? legacyRetryPolicy.getRetryMode()
92                                                                          : clientConfiguration.getRetryMode();
93
94         return retryMode.equals(RetryMode.STANDARD) && legacyRetryPolicy.isDefaultMaxErrorRetryInRetryModeHonored();
95     }
96
97     public boolean maxRetriesExceeded(RetryPolicyContext context) {
98         return context.retriesAttempted() >= maxErrorRetry;
99     }
100
101     public int getMaxErrorRetry() {
102         return maxErrorRetry;
103     }
104 }
105