31
31
*
32
32
* <ol>
33
33
* <li>{@link CallChain#initiate(String, ProxyClient, Object, StdCallbackContext)}
34
- * <li>{@link RequestMaker#request (Function)}
34
+ * <li>{@link RequestMaker#translate (Function)}
35
35
* <li>{@link Caller#call(BiFunction)}
36
36
* <li>{@link Completed#done(Function)}
37
37
* </ol>
40
40
*/
41
41
public interface CallChain {
42
42
43
+ /**
44
+ * Provides an API initiator interface that works for all API calls that need
45
+ * conversion, retry-backoff strategy, common exception handling and more
46
+ * against desired state of the resource and callback context. This needs to be
47
+ * instantiated once with the client, model and callback context and used. It
48
+ * takes a reference to the desired state model, so any changes made on the
49
+ * model object will be reflected here. The model and callback can accessed from
50
+ * the instantiator instance
51
+ *
52
+ * @param <ClientT> the AWS Service client.
53
+ * @param <ModelT> the model object being worked on
54
+ * @param <CallbackT> the callback context
55
+ */
56
+ interface Initiator <ClientT , ModelT , CallbackT extends StdCallbackContext > {
57
+ /**
58
+ * Each service call must be first initiated. Every call is provided a separate
59
+ * name called call graph. This is essential from both a tracing perspective as
60
+ * well as {@link StdCallbackContext} automated replay capabilities.
61
+ *
62
+ * @param callGraph, the name of the service operation this call graph is about.
63
+ * @return Provides the next logical set in the fluent API.
64
+ */
65
+ RequestMaker <ClientT , ModelT , CallbackT > initiate (String callGraph );
66
+
67
+ /**
68
+ * @return the model associated with the API initiator. Can not be null
69
+ */
70
+ ModelT getResourceModel ();
71
+
72
+ /**
73
+ * @return the callback context associated with API initiator, Can not be null
74
+ */
75
+ CallbackT getCallbackContext ();
76
+
77
+ /**
78
+ * Can rebind a new model to the call chain while retaining the client and
79
+ * callback context
80
+ *
81
+ * @param model, the new model for the callchain initiation
82
+ * @param <NewModelT>, this actual model type
83
+ * @return new {@link Initiator} that now has the new model associated with it
84
+ */
85
+ <NewModelT > Initiator <ClientT , NewModelT , CallbackT > rebindModel (NewModelT model );
86
+
87
+ /**
88
+ * Can rebind a new callback context for a call chain while retaining the model
89
+ * and client
90
+ *
91
+ * @param callback the new callback context
92
+ * @param <NewCallbackT> new callback context type
93
+ * @return new {@link Initiator} that now has the new callback associated with
94
+ * it
95
+ */
96
+ <NewCallbackT extends StdCallbackContext > Initiator <ClientT , ModelT , NewCallbackT > rebindCallback (NewCallbackT callback );
97
+ }
98
+
99
+ /**
100
+ * factory method can created an {@link Initiator}
101
+ *
102
+ * @param client AWS Service Client. Recommend using Sync client as the
103
+ * framework handles interleaving as needed.
104
+ * @param model the resource desired state model, usually
105
+ * @param context callback context that tracks all outbound API calls
106
+ * @param <ClientT> Actual client e.g. KinesisClient.
107
+ * @param <ModelT> The type (POJO) of Resource model.
108
+ * @param <CallbackT>, callback context the extends {@link StdCallbackContext}
109
+ *
110
+ * @return an instance of the {@link Initiator}
111
+ */
112
+ <ClientT , ModelT , CallbackT extends StdCallbackContext >
113
+ Initiator <ClientT , ModelT , CallbackT >
114
+ newInitiator (ProxyClient <ClientT > client , ModelT model , CallbackT context );
115
+
43
116
/**
44
117
* Each service call must be first initiated. Every call is provided a separate
45
118
* name called call graph. This is eseential from both a tracing perspective as
@@ -71,32 +144,54 @@ public interface CallChain {
71
144
*/
72
145
interface RequestMaker <ClientT , ModelT , CallbackT extends StdCallbackContext > {
73
146
/**
147
+ * use {@link #translate(Function)}
148
+ *
74
149
* Take a reference to the tranlater that take the resource model POJO as input
75
150
* and provide a request object as needed to make the Service call.
76
151
*
77
152
* @param maker, provide a functional transform from model to request object.
78
153
* @param <RequestT>, the web service request created
79
154
* @return returns the next step, to actually call the service.
80
155
*/
81
- <RequestT > Caller <RequestT , ClientT , ModelT , CallbackT > request (Function <ModelT , RequestT > maker );
156
+ @ Deprecated
157
+ default <RequestT > Caller <RequestT , ClientT , ModelT , CallbackT > request (Function <ModelT , RequestT > maker ) {
158
+ return translate (maker );
159
+ }
160
+
161
+ /**
162
+ * Take a reference to the tranlater that take the resource model POJO as input
163
+ * and provide a request object as needed to make the Service call.
164
+ *
165
+ * @param maker, provide a functional transform from model to request object.
166
+ * @param <RequestT>, the web service request created
167
+ * @return returns the next step, to actually call the service.
168
+ */
169
+ <RequestT > Caller <RequestT , ClientT , ModelT , CallbackT > translate (Function <ModelT , RequestT > maker );
82
170
}
83
171
84
172
/**
85
173
* This Encapsulates the actual Call to the service that is being made via
86
174
* caller. This allow for the proxy to intercept and wrap the caller in cases of
87
175
* replay and provide the memoized response back
88
176
*
89
- * @param <RequestT>
90
- * @param <ClientT>
91
- * @param <ModelT>
92
- * @param <CallbackT>
177
+ * @param <RequestT>, the AWS serivce request we are making
178
+ * @param <ClientT>, the web service client to make the call
179
+ * @param <ModelT>, the current model we are using
180
+ * @param <CallbackT>, the callback context for handling all AWS service request
181
+ * responses
93
182
*/
94
183
interface Caller <RequestT , ClientT , ModelT , CallbackT extends StdCallbackContext > {
95
184
<ResponseT >
96
185
Stabilizer <RequestT , ResponseT , ClientT , ModelT , CallbackT >
97
186
call (BiFunction <RequestT , ProxyClient <ClientT >, ResponseT > caller );
98
187
99
- Caller <RequestT , ClientT , ModelT , CallbackT > retry (Delay delay );
188
+ @ Deprecated
189
+ default Caller <RequestT , ClientT , ModelT , CallbackT > retry (Delay delay ) {
190
+ return backoff (delay );
191
+ }
192
+
193
+ Caller <RequestT , ClientT , ModelT , CallbackT > backoff (Delay delay );
194
+
100
195
}
101
196
102
197
/**
@@ -154,8 +249,39 @@ interface Exceptional<RequestT, ResponseT, ClientT, ModelT, CallbackT extends St
154
249
* @return true of you want to attempt another retry of the operation. false to
155
250
* indicate propagate error/fault.
156
251
*/
252
+ @ Deprecated
253
+ default Completed <RequestT , ResponseT , ClientT , ModelT , CallbackT >
254
+ exceptFilter (Callback <? super RequestT , Exception , ClientT , ModelT , CallbackT , Boolean > handler ) {
255
+ return retryErrorFilter (handler );
256
+ }
257
+
258
+ /**
259
+ * @param handler, a predicate lambda expression that takes the web request,
260
+ * exception, client, model and context to determine to retry the
261
+ * exception thrown by the service or fail operation. This is the
262
+ * simpler model then {@link #handleError(ExceptionPropagate)} for
263
+ * most common retry scenarios If we need more control over the
264
+ * outcome, then use {@link #handleError(ExceptionPropagate)}
265
+ * @return true of you want to attempt another retry of the operation. false to
266
+ * indicate propagate error/fault.
267
+ */
157
268
Completed <RequestT , ResponseT , ClientT , ModelT , CallbackT >
158
- exceptFilter (Callback <? super RequestT , Exception , ClientT , ModelT , CallbackT , Boolean > handler );
269
+ retryErrorFilter (Callback <? super RequestT , Exception , ClientT , ModelT , CallbackT , Boolean > handler );
270
+
271
+ /**
272
+ * @param handler, a lambda expression that takes the web request, response,
273
+ * client, model and context returns a successful or failed
274
+ * {@link ProgressEvent} back or can rethrow service exception to
275
+ * propagate errors. If handler needs to retry the exception, the it
276
+ * will throw a
277
+ * {@link software.amazon.awssdk.core.exception.RetryableException}
278
+ * @return a ProgressEvent for the model
279
+ */
280
+ @ Deprecated
281
+ default Completed <RequestT , ResponseT , ClientT , ModelT , CallbackT > exceptHandler (ExceptionPropagate <? super RequestT ,
282
+ Exception , ClientT , ModelT , CallbackT , ProgressEvent <ModelT , CallbackT >> handler ) {
283
+ return handleError (handler );
284
+ }
159
285
160
286
/**
161
287
* @param handler, a lambda expression that take the web request, response,
@@ -164,8 +290,26 @@ interface Exceptional<RequestT, ResponseT, ClientT, ModelT, CallbackT extends St
164
290
* @return If status is {@link OperationStatus#IN_PROGRESS} we will attempt
165
291
* another retry. Otherwise failure is propagated.
166
292
*/
167
- Completed <RequestT , ResponseT , ClientT , ModelT , CallbackT > exceptHandler (Callback <? super RequestT , Exception , ClientT ,
168
- ModelT , CallbackT , ProgressEvent <ModelT , CallbackT >> handler );
293
+ Completed <RequestT , ResponseT , ClientT , ModelT , CallbackT > handleError (ExceptionPropagate <? super RequestT , Exception ,
294
+ ClientT , ModelT , CallbackT , ProgressEvent <ModelT , CallbackT >> handler );
295
+ }
296
+
297
+ /**
298
+ * When implementing this interface, developers can either propagate the
299
+ * exception as is. If the exception can be retried, throw
300
+ * {@link software.amazon.awssdk.core.exception.RetryableException}
301
+ *
302
+ * @param <RequestT> the API request object
303
+ * @param <E> the exception that is thrown by the API
304
+ * @param <ClientT> the service client
305
+ * @param <ModelT> current desired state resource model
306
+ * @param <CallbackT> current callback context
307
+ * @param <ReturnT> result object
308
+ */
309
+ @ FunctionalInterface
310
+ interface ExceptionPropagate <RequestT , E extends Exception , ClientT , ModelT , CallbackT extends StdCallbackContext , ReturnT > {
311
+ ReturnT invoke (RequestT request , E exception , ProxyClient <ClientT > client , ModelT model , CallbackT context )
312
+ throws Exception ;
169
313
}
170
314
171
315
/**
@@ -242,24 +386,27 @@ interface Completed<RequestT, ResponseT, ClientT, ModelT, CallbackT extends StdC
242
386
done (Callback <RequestT , ResponseT , ClientT , ModelT , CallbackT , ProgressEvent <ModelT , CallbackT >> callback );
243
387
244
388
/**
245
- * Helper function that provides a {@link OperationStatus#SUCCESS} status when
246
- * the callchain is done
389
+ * @return {@link ProgressEvent} Helper function that provides a
390
+ * {@link OperationStatus#SUCCESS} status when the callchain is done
247
391
*/
248
392
default ProgressEvent <ModelT , CallbackT > success () {
249
393
return done ((request , response , client , model , context ) -> ProgressEvent .success (model , context ));
250
394
}
251
395
252
396
/**
253
- * Helper function that provides a {@link OperationStatus#IN_PROGRESS} status
254
- * when the callchain is done
397
+ * @return {@link ProgressEvent} Helper function that provides a
398
+ * {@link OperationStatus#IN_PROGRESS} status when the callchain is done
255
399
*/
256
400
default ProgressEvent <ModelT , CallbackT > progress () {
257
401
return progress (0 );
258
402
}
259
403
260
404
/**
261
- * Helper function that provides a {@link OperationStatus#IN_PROGRESS} status
262
- * when the callchain is done
405
+ * @param callbackDelay the number of seconds to delay before calling back into
406
+ * this externally
407
+ * @return {@link ProgressEvent} Helper function that provides a
408
+ * {@link OperationStatus#IN_PROGRESS} status when the callchain is done
409
+ * with callback delay
263
410
*/
264
411
default ProgressEvent <ModelT , CallbackT > progress (int callbackDelay ) {
265
412
return done ((request , response , client , model , context ) -> ProgressEvent .defaultInProgressHandler (context ,
0 commit comments