1
15
16 package software.amazon.awssdk.core.retry;
17
18 import software.amazon.awssdk.annotations.Immutable;
19 import software.amazon.awssdk.annotations.SdkPublicApi;
20 import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
21 import software.amazon.awssdk.core.internal.retry.SdkDefaultRetrySetting;
22 import software.amazon.awssdk.core.retry.backoff.BackoffStrategy;
23 import software.amazon.awssdk.core.retry.conditions.AndRetryCondition;
24 import software.amazon.awssdk.core.retry.conditions.MaxNumberOfRetriesCondition;
25 import software.amazon.awssdk.core.retry.conditions.RetryCondition;
26 import software.amazon.awssdk.core.retry.conditions.TokenBucketRetryCondition;
27 import software.amazon.awssdk.utils.ToString;
28 import software.amazon.awssdk.utils.builder.CopyableBuilder;
29 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
30
31
43 @Immutable
44 @SdkPublicApi
45 public final class RetryPolicy implements ToCopyableBuilder<RetryPolicy.Builder, RetryPolicy> {
46 private final boolean additionalRetryConditionsAllowed;
47 private final RetryMode retryMode;
48 private final BackoffStrategy backoffStrategy;
49 private final BackoffStrategy throttlingBackoffStrategy;
50 private final Integer numRetries;
51 private final RetryCondition retryCondition;
52 private final RetryCondition retryCapacityCondition;
53
54 private final RetryCondition aggregateRetryCondition;
55
56 private RetryPolicy(BuilderImpl builder) {
57 this.additionalRetryConditionsAllowed = builder.additionalRetryConditionsAllowed;
58 this.retryMode = builder.retryMode;
59 this.backoffStrategy = builder.backoffStrategy;
60 this.throttlingBackoffStrategy = builder.throttlingBackoffStrategy;
61 this.numRetries = builder.numRetries;
62 this.retryCondition = builder.retryCondition;
63 this.retryCapacityCondition = builder.retryCapacityCondition;
64
65 this.aggregateRetryCondition = generateAggregateRetryCondition();
66 }
67
68
71 public static RetryPolicy defaultRetryPolicy() {
72 return forRetryMode(RetryMode.defaultRetryMode());
73 }
74
75
78 public static RetryPolicy forRetryMode(RetryMode retryMode) {
79 return RetryPolicy.builder(retryMode).build();
80 }
81
82
85 public static RetryPolicy none() {
86 return RetryPolicy.builder()
87 .numRetries(0)
88 .backoffStrategy(BackoffStrategy.none())
89 .throttlingBackoffStrategy(BackoffStrategy.none())
90 .retryCondition(RetryCondition.none())
91 .additionalRetryConditionsAllowed(false)
92 .build();
93 }
94
95
98 public static Builder builder() {
99 return new BuilderImpl(RetryMode.defaultRetryMode());
100 }
101
102
105 public static Builder builder(RetryMode retryMode) {
106 return new BuilderImpl(retryMode);
107 }
108
109
112 public RetryMode retryMode() {
113 return retryMode;
114 }
115
116
120 public boolean additionalRetryConditionsAllowed() {
121 return additionalRetryConditionsAllowed;
122 }
123
124
128 public RetryCondition aggregateRetryCondition() {
129 return aggregateRetryCondition;
130 }
131
132
135 public RetryCondition retryCondition() {
136 return retryCondition;
137 }
138
139
142 public BackoffStrategy backoffStrategy() {
143 return backoffStrategy;
144 }
145
146
149 public BackoffStrategy throttlingBackoffStrategy() {
150 return throttlingBackoffStrategy;
151 }
152
153
156 public Integer numRetries() {
157 return numRetries;
158 }
159
160 private RetryCondition generateAggregateRetryCondition() {
161 RetryCondition aggregate = AndRetryCondition.create(MaxNumberOfRetriesCondition.create(numRetries),
162 retryCondition);
163 if (retryCapacityCondition != null) {
164 return AndRetryCondition.create(aggregate, retryCapacityCondition);
165 }
166 return aggregate;
167 }
168
169 public Builder toBuilder() {
170 return builder(retryMode).additionalRetryConditionsAllowed(additionalRetryConditionsAllowed)
171 .numRetries(numRetries)
172 .retryCondition(retryCondition)
173 .backoffStrategy(backoffStrategy)
174 .throttlingBackoffStrategy(throttlingBackoffStrategy)
175 .retryCapacityCondition(retryCapacityCondition);
176 }
177
178 @Override
179 public String toString() {
180 return ToString.builder("RetryPolicy")
181 .add("additionalRetryConditionsAllowed", additionalRetryConditionsAllowed)
182 .add("aggregateRetryCondition", aggregateRetryCondition)
183 .add("backoffStrategy", backoffStrategy)
184 .add("throttlingBackoffStrategy", throttlingBackoffStrategy)
185 .build();
186 }
187
188 @Override
189 public boolean equals(Object o) {
190 if (this == o) {
191 return true;
192 }
193 if (o == null || getClass() != o.getClass()) {
194 return false;
195 }
196
197 RetryPolicy that = (RetryPolicy) o;
198
199 if (additionalRetryConditionsAllowed != that.additionalRetryConditionsAllowed) {
200 return false;
201 }
202 if (!aggregateRetryCondition.equals(that.aggregateRetryCondition)) {
203 return false;
204 }
205 if (!backoffStrategy.equals(that.backoffStrategy)) {
206 return false;
207 }
208 if (!throttlingBackoffStrategy.equals(that.throttlingBackoffStrategy)) {
209 return false;
210 }
211 return true;
212 }
213
214 @Override
215 public int hashCode() {
216 int result = aggregateRetryCondition.hashCode();
217 result = 31 * result + Boolean.hashCode(additionalRetryConditionsAllowed);
218 result = 31 * result + backoffStrategy.hashCode();
219 result = 31 * result + throttlingBackoffStrategy.hashCode();
220 return result;
221 }
222
223 public interface Builder extends CopyableBuilder<Builder, RetryPolicy> {
224
231 Builder additionalRetryConditionsAllowed(boolean additionalRetryConditionsAllowed);
232
233
236 boolean additionalRetryConditionsAllowed();
237
238
242 Builder backoffStrategy(BackoffStrategy backoffStrategy);
243
244
247 BackoffStrategy backoffStrategy();
248
249
254 Builder throttlingBackoffStrategy(BackoffStrategy backoffStrategy);
255
256
259 BackoffStrategy throttlingBackoffStrategy();
260
261
272 Builder retryCondition(RetryCondition retryCondition);
273
274
277 RetryCondition retryCondition();
278
279
291 Builder retryCapacityCondition(RetryCondition retryCapacityCondition);
292
293
296 RetryCondition retryCapacityCondition();
297
298
301 Builder numRetries(Integer numRetries);
302
303
306 Integer numRetries();
307
308 RetryPolicy build();
309 }
310
311
314 private static final class BuilderImpl implements Builder {
315 private final RetryMode retryMode;
316
317 private boolean additionalRetryConditionsAllowed;
318 private Integer numRetries;
319 private BackoffStrategy backoffStrategy;
320 private BackoffStrategy throttlingBackoffStrategy;
321 private RetryCondition retryCondition;
322 private RetryCondition retryCapacityCondition;
323
324 private BuilderImpl(RetryMode retryMode) {
325 this.retryMode = retryMode;
326 this.numRetries = SdkDefaultRetrySetting.maxAttempts(retryMode) - 1;
327 this.additionalRetryConditionsAllowed = true;
328 this.backoffStrategy = BackoffStrategy.defaultStrategy();
329 this.throttlingBackoffStrategy = BackoffStrategy.defaultThrottlingStrategy();
330 this.retryCondition = RetryCondition.defaultRetryCondition();
331 this.retryCapacityCondition = TokenBucketRetryCondition.forRetryMode(retryMode);
332 }
333
334 @Override
335 public Builder additionalRetryConditionsAllowed(boolean additionalRetryConditionsAllowed) {
336 this.additionalRetryConditionsAllowed = additionalRetryConditionsAllowed;
337 return this;
338 }
339
340 public void setadditionalRetryConditionsAllowed(boolean additionalRetryConditionsAllowed) {
341 additionalRetryConditionsAllowed(additionalRetryConditionsAllowed);
342 }
343
344 @Override
345 public boolean additionalRetryConditionsAllowed() {
346 return additionalRetryConditionsAllowed;
347 }
348
349 @Override
350 public Builder numRetries(Integer numRetries) {
351 this.numRetries = numRetries;
352 return this;
353 }
354
355 public void setNumRetries(Integer numRetries) {
356 numRetries(numRetries);
357 }
358
359 @Override
360 public Integer numRetries() {
361 return numRetries;
362 }
363
364 @Override
365 public Builder backoffStrategy(BackoffStrategy backoffStrategy) {
366 this.backoffStrategy = backoffStrategy;
367 return this;
368 }
369
370 public void setBackoffStrategy(BackoffStrategy backoffStrategy) {
371 backoffStrategy(backoffStrategy);
372 }
373
374 @Override
375 public BackoffStrategy backoffStrategy() {
376 return backoffStrategy;
377 }
378
379 @Override
380 public Builder throttlingBackoffStrategy(BackoffStrategy throttlingBackoffStrategy) {
381 this.throttlingBackoffStrategy = throttlingBackoffStrategy;
382 return this;
383 }
384
385 @Override
386 public BackoffStrategy throttlingBackoffStrategy() {
387 return throttlingBackoffStrategy;
388 }
389
390 public void setThrottlingBackoffStrategy(BackoffStrategy throttlingBackoffStrategy) {
391 this.throttlingBackoffStrategy = throttlingBackoffStrategy;
392 }
393
394 @Override
395 public Builder retryCondition(RetryCondition retryCondition) {
396 this.retryCondition = retryCondition;
397 return this;
398 }
399
400 public void setRetryCondition(RetryCondition retryCondition) {
401 retryCondition(retryCondition);
402 }
403
404 @Override
405 public RetryCondition retryCondition() {
406 return retryCondition;
407 }
408
409 @Override
410 public Builder retryCapacityCondition(RetryCondition retryCapacityCondition) {
411 this.retryCapacityCondition = retryCapacityCondition;
412 return this;
413 }
414
415 public void setRetryCapacityCondition(RetryCondition retryCapacityCondition) {
416 retryCapacityCondition(retryCapacityCondition);
417 }
418
419 @Override
420 public RetryCondition retryCapacityCondition() {
421 return this.retryCapacityCondition;
422 }
423
424 @Override
425 public RetryPolicy build() {
426 return new RetryPolicy(this);
427 }
428 }
429 }
430