1 /*
2  * Copyright 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
16 package software.amazon.awssdk.core.retry.conditions;
17
18 import java.util.Arrays;
19 import java.util.HashSet;
20 import java.util.Optional;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23 import software.amazon.awssdk.annotations.SdkPublicApi;
24 import software.amazon.awssdk.core.retry.RetryPolicyContext;
25 import software.amazon.awssdk.utils.ToString;
26 import software.amazon.awssdk.utils.Validate;
27
28 /**
29  * Retry condition implementation that retries if the HTTP status code matches one of the provided status codes.
30  */

31 @SdkPublicApi
32 public final class RetryOnStatusCodeCondition implements RetryCondition {
33
34     private final Set<Integer> statusCodesToRetryOn;
35
36     private RetryOnStatusCodeCondition(Set<Integer> statusCodesToRetryOn) {
37         this.statusCodesToRetryOn = new HashSet<>(
38                 Validate.paramNotNull(statusCodesToRetryOn, "statusCodesToRetryOn"));
39     }
40
41     /**
42      * @param context Context about the state of the last request and information about the number of requests made.
43      * @return True if the HTTP status code matches one of the provided status codes. False if it doesn't match or the request
44      *     failed for reasons other than an exceptional HTTP response (i.e. IOException).
45      */

46     @Override
47     public boolean shouldRetry(RetryPolicyContext context) {
48         return Optional.ofNullable(context.httpStatusCode()).map(s ->
49             statusCodesToRetryOn.stream().anyMatch(code -> code.equals(s))).orElse(false);
50     }
51
52     public static RetryOnStatusCodeCondition create(Set<Integer> statusCodesToRetryOn) {
53         return new RetryOnStatusCodeCondition(statusCodesToRetryOn);
54     }
55
56     public static RetryOnStatusCodeCondition create(Integer... statusCodesToRetryOn) {
57         return new RetryOnStatusCodeCondition(Arrays.stream(statusCodesToRetryOn).collect(Collectors.toSet()));
58     }
59
60     @Override
61     public boolean equals(Object o) {
62         if (this == o) {
63             return true;
64         }
65         if (o == null || getClass() != o.getClass()) {
66             return false;
67         }
68
69         RetryOnStatusCodeCondition that = (RetryOnStatusCodeCondition) o;
70
71         return statusCodesToRetryOn.equals(that.statusCodesToRetryOn);
72     }
73
74     @Override
75     public int hashCode() {
76         return statusCodesToRetryOn.hashCode();
77     }
78
79     @Override
80     public String toString() {
81         return ToString.builder("RetryOnStatusCodeCondition")
82                        .add("statusCodesToRetryOn", statusCodesToRetryOn)
83                        .build();
84     }
85 }
86