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.waiters; 17 18 import java.util.Optional; 19 import java.util.function.Predicate; 20 import software.amazon.awssdk.annotations.SdkPublicApi; 21 import software.amazon.awssdk.utils.Validate; 22 23 /** 24 * Inspects the response or errors returned from the operation and determines whether an expected state is met and returns the 25 * next {@link WaiterState} that the waiter should be transitioned to. 26 */ 27 @SdkPublicApi 28 public interface WaiterAcceptor<T> { 29 30 /** 31 * @return the next {@link WaiterState} that the waiter should be transitioned to 32 */ waiterState()33 WaiterState waiterState(); 34 35 /** 36 * Check to see if the response matches with the expected state defined by this acceptor 37 * 38 * @param response the response to inspect 39 * @return whether it accepts the response 40 */ matches(T response)41 default boolean matches(T response) { 42 return false; 43 } 44 45 /** 46 * Check to see if the exception matches the expected state defined by this acceptor 47 * 48 * @param throwable the exception to inspect 49 * @return whether it accepts the throwable 50 */ matches(Throwable throwable)51 default boolean matches(Throwable throwable) { 52 return false; 53 } 54 55 /** 56 * Optional message to provide pertaining to the next WaiterState 57 * 58 * @return the optional message 59 */ message()60 default Optional<String> message() { 61 return Optional.empty(); 62 } 63 64 /** 65 * Creates a success waiter acceptor which determines if the exception should transition the waiter to success state 66 * 67 * @param responsePredicate the predicate of the response 68 * @param <T> the response type 69 * @return a {@link WaiterAcceptor} 70 */ successOnResponseAcceptor(Predicate<T> responsePredicate)71 static <T> WaiterAcceptor<T> successOnResponseAcceptor(Predicate<T> responsePredicate) { 72 Validate.paramNotNull(responsePredicate, "responsePredicate"); 73 return new WaiterAcceptor<T>() { 74 @Override 75 public WaiterState waiterState() { 76 return WaiterState.SUCCESS; 77 } 78 79 @Override 80 public boolean matches(T response) { 81 return responsePredicate.test(response); 82 } 83 }; 84 } 85 86 /** 87 * Creates an error waiter acceptor which determines if the exception should transition the waiter to success state 88 * 89 * @param errorPredicate the {@link Throwable} predicate 90 * @param <T> the response type 91 * @return a {@link WaiterAcceptor} 92 */ 93 static <T> WaiterAcceptor<T> successOnExceptionAcceptor(Predicate<Throwable> errorPredicate) { 94 Validate.paramNotNull(errorPredicate, "errorPredicate"); 95 return new WaiterAcceptor<T>() { 96 @Override 97 public WaiterState waiterState() { 98 return WaiterState.SUCCESS; 99 } 100 101 @Override 102 public boolean matches(Throwable t) { 103 return errorPredicate.test(t); 104 } 105 }; 106 } 107 108 /** 109 * Creates an error waiter acceptor which determines if the exception should transition the waiter to failure state 110 * 111 * @param errorPredicate the {@link Throwable} predicate 112 * @param <T> the response type 113 * @return a {@link WaiterAcceptor} 114 */ 115 static <T> WaiterAcceptor<T> errorOnExceptionAcceptor(Predicate<Throwable> errorPredicate) { 116 Validate.paramNotNull(errorPredicate, "errorPredicate"); 117 return new WaiterAcceptor<T>() { 118 @Override 119 public WaiterState waiterState() { 120 return WaiterState.FAILURE; 121 } 122 123 @Override 124 public boolean matches(Throwable t) { 125 return errorPredicate.test(t); 126 } 127 }; 128 } 129 130 /** 131 * Creates a success waiter acceptor which determines if the exception should transition the waiter to success state 132 * 133 * @param responsePredicate the predicate of the response 134 * @param <T> the response type 135 * @return a {@link WaiterAcceptor} 136 */ 137 static <T> WaiterAcceptor<T> errorOnResponseAcceptor(Predicate<T> responsePredicate) { 138 Validate.paramNotNull(responsePredicate, "responsePredicate"); 139 return new WaiterAcceptor<T>() { 140 @Override 141 public WaiterState waiterState() { 142 return WaiterState.FAILURE; 143 } 144 145 @Override 146 public boolean matches(T response) { 147 return responsePredicate.test(response); 148 } 149 }; 150 } 151 152 /** 153 * Creates a success waiter acceptor which determines if the exception should transition the waiter to success state 154 * 155 * @param responsePredicate the predicate of the response 156 * @param <T> the response type 157 * @return a {@link WaiterAcceptor} 158 */ 159 static <T> WaiterAcceptor<T> errorOnResponseAcceptor(Predicate<T> responsePredicate, String message) { 160 Validate.paramNotNull(responsePredicate, "responsePredicate"); 161 Validate.paramNotNull(message, "message"); 162 return new WaiterAcceptor<T>() { 163 @Override 164 public WaiterState waiterState() { 165 return WaiterState.FAILURE; 166 } 167 168 @Override 169 public boolean matches(T response) { 170 return responsePredicate.test(response); 171 } 172 173 @Override 174 public Optional<String> message() { 175 return Optional.of(message); 176 } 177 }; 178 } 179 180 /** 181 * Creates a retry on exception waiter acceptor which determines if the exception should transition the waiter to retry state 182 * 183 * @param errorPredicate the {@link Throwable} predicate 184 * @param <T> the response type 185 * @return a {@link WaiterAcceptor} 186 */ 187 static <T> WaiterAcceptor<T> retryOnExceptionAcceptor(Predicate<Throwable> errorPredicate) { 188 Validate.paramNotNull(errorPredicate, "errorPredicate"); 189 return new WaiterAcceptor<T>() { 190 @Override 191 public WaiterState waiterState() { 192 return WaiterState.RETRY; 193 } 194 195 @Override 196 public boolean matches(Throwable t) { 197 return errorPredicate.test(t); 198 } 199 }; 200 } 201 202 /** 203 * Creates a retry on exception waiter acceptor which determines if the exception should transition the waiter to retry state 204 * 205 * @param responsePredicate the {@link Throwable} predicate 206 * @param <T> the response type 207 * @return a {@link WaiterAcceptor} 208 */ 209 static <T> WaiterAcceptor<T> retryOnResponseAcceptor(Predicate<T> responsePredicate) { 210 Validate.paramNotNull(responsePredicate, "responsePredicate"); 211 return new WaiterAcceptor<T>() { 212 @Override 213 public WaiterState waiterState() { 214 return WaiterState.RETRY; 215 } 216 217 @Override 218 public boolean matches(T t) { 219 return responsePredicate.test(t); 220 } 221 }; 222 } 223 } 224