1
- // Copyright 2017, 2018 , Oracle Corporation and/or its affiliates. All rights reserved.
1
+ // Copyright 2017, 2019 , Oracle Corporation and/or its affiliates. All rights reserved.
2
2
// Licensed under the Universal Permissive License v 1.0 as shown at
3
3
// http://oss.oracle.com/licenses/upl.
4
4
5
5
package oracle .kubernetes .operator .helpers ;
6
6
7
+ import static java .net .HttpURLConnection .HTTP_CONFLICT ;
8
+
7
9
import com .squareup .okhttp .Call ;
8
10
import io .kubernetes .client .ApiCallback ;
9
11
import io .kubernetes .client .ApiClient ;
46
48
import oracle .kubernetes .operator .calls .RequestParams ;
47
49
import oracle .kubernetes .operator .calls .SynchronousCallDispatcher ;
48
50
import oracle .kubernetes .operator .calls .SynchronousCallFactory ;
51
+ import oracle .kubernetes .operator .logging .LoggingFacade ;
52
+ import oracle .kubernetes .operator .logging .LoggingFactory ;
53
+ import oracle .kubernetes .operator .logging .MessageKeys ;
49
54
import oracle .kubernetes .operator .work .Step ;
50
55
import oracle .kubernetes .weblogic .domain .v2 .Domain ;
51
56
import oracle .kubernetes .weblogic .domain .v2 .DomainList ;
@@ -58,6 +63,8 @@ public class CallBuilder {
58
63
/** HTTP status code for "Not Found" */
59
64
public static final int NOT_FOUND = 404 ;
60
65
66
+ private static final LoggingFacade LOGGER = LoggingFactory .getLogger ("Operator" , "Operator" );
67
+
61
68
private static SynchronousCallDispatcher DISPATCHER =
62
69
new SynchronousCallDispatcher () {
63
70
@ Override
@@ -159,6 +166,65 @@ public VersionInfo readVersionCode() throws ApiException {
159
166
requestParams , ((client , params ) -> new VersionApi (client ).getCode ()));
160
167
}
161
168
169
+ /**
170
+ * Class extended by callers to {@link
171
+ * #executeSynchronousCallWithConflictRetry(RequestParamsBuilder, SynchronousCallFactory,
172
+ * ConflictRetry)} for building the RequestParams to be passed to {@link
173
+ * #executeSynchronousCall(RequestParams, SynchronousCallFactory)}.
174
+ *
175
+ * @param <T> Type of kubernetes object to be passed to the API
176
+ */
177
+ abstract static class RequestParamsBuilder <T > {
178
+ T body ;
179
+
180
+ public RequestParamsBuilder (T body ) {
181
+ this .body = body ;
182
+ }
183
+
184
+ abstract RequestParams buildRequestParams ();
185
+
186
+ void setBody (T body ) {
187
+ this .body = body ;
188
+ }
189
+ }
190
+
191
+ private <T > T executeSynchronousCallWithConflictRetry (
192
+ RequestParamsBuilder requestParamsBuilder ,
193
+ SynchronousCallFactory <T > factory ,
194
+ ConflictRetry <T > conflictRetry )
195
+ throws ApiException {
196
+ int retryCount = 0 ;
197
+ while (retryCount == 0 || retryCount < maxRetryCount ) {
198
+ retryCount ++;
199
+ RequestParams requestParams = requestParamsBuilder .buildRequestParams ();
200
+ try {
201
+ return executeSynchronousCall (requestParams , factory );
202
+ } catch (ApiException apiException ) {
203
+ boolean retry = false ;
204
+ if (apiException .getCode () == HTTP_CONFLICT
205
+ && conflictRetry != null
206
+ && retryCount < maxRetryCount ) {
207
+ T body = conflictRetry .getUpdatedObject ();
208
+ if (body != null ) {
209
+ requestParamsBuilder .setBody (body );
210
+ retry = true ;
211
+ LOGGER .fine (
212
+ MessageKeys .SYNC_RETRY ,
213
+ requestParams .call ,
214
+ apiException .getCode (),
215
+ apiException .getMessage (),
216
+ retryCount ,
217
+ maxRetryCount );
218
+ }
219
+ }
220
+ if (!retry ) {
221
+ throw apiException ;
222
+ }
223
+ }
224
+ }
225
+ return null ;
226
+ }
227
+
162
228
private <T > T executeSynchronousCall (
163
229
RequestParams requestParams , SynchronousCallFactory <T > factory ) throws ApiException {
164
230
return DISPATCHER .execute (factory , requestParams , helper );
@@ -295,6 +361,33 @@ public Step readDomainAsync(String name, String namespace, ResponseStep<Domain>
295
361
.replaceWebLogicOracleV2NamespacedDomain (
296
362
requestParams .name , requestParams .namespace , (Domain ) requestParams .body , pretty );
297
363
364
+ /**
365
+ * Replace domain
366
+ *
367
+ * @param uid the domain uid (unique within the k8s cluster)
368
+ * @param namespace Namespace
369
+ * @param body Body
370
+ * @param conflictRetry ConflictRetry implementation to be called to obtain the latest version of
371
+ * the Domain for retrying the replaceDomain synchronous call if previous call failed with
372
+ * Conflict response code (409)
373
+ * @return Replaced domain
374
+ * @throws ApiException APIException
375
+ */
376
+ public Domain replaceDomainWithConflictRetry (
377
+ String uid , String namespace , Domain body , ConflictRetry <Domain > conflictRetry )
378
+ throws ApiException {
379
+ return executeSynchronousCallWithConflictRetry (
380
+ new RequestParamsBuilder <Domain >(body ) {
381
+
382
+ @ Override
383
+ RequestParams buildRequestParams () {
384
+ return new RequestParams ("replaceDomain" , namespace , uid , body );
385
+ }
386
+ },
387
+ REPLACE_DOMAIN_CALL ,
388
+ conflictRetry );
389
+ }
390
+
298
391
/**
299
392
* Replace domain
300
393
*
0 commit comments