Skip to content

Commit a47b428

Browse files
authored
OWLS-90614 - Handle ApiException with 409 code returned from the replaceEvent API call (#2443)
* OWLS-90614 - Handle api exception with 409 code and "storage error" during replace event and other API calls. * Changes to always create a new event after 409 error. * Add async call name to the ASYNC_NO_RETRY log message.
1 parent ab5f394 commit a47b428

File tree

6 files changed

+35
-5
lines changed

6 files changed

+35
-5
lines changed

operator/src/main/java/oracle/kubernetes/operator/calls/UnrecoverableErrorBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public static <T> boolean isAsyncCallNotFoundFailure(CallResponse<T> callRespons
2828
return callResponse.isFailure() && isNotFound(callResponse.getE());
2929
}
3030

31+
public static <T> boolean isAsyncCallConflictFailure(CallResponse<T> callResponse) {
32+
return callResponse.isFailure() && hasConflict(callResponse.getE());
33+
}
34+
3135
private static boolean isUnrecoverable(ApiException e) {
3236
return UnrecoverableErrorBuilderImpl.isUnrecoverable(e);
3337
}
@@ -36,6 +40,10 @@ private static boolean isNotFound(ApiException e) {
3640
return UnrecoverableErrorBuilderImpl.isNotFound(e);
3741
}
3842

43+
private static boolean hasConflict(ApiException e) {
44+
return UnrecoverableErrorBuilderImpl.hasConflict(e);
45+
}
46+
3947
/**
4048
* Populate FailureStatusSource from a failed call response.
4149
* @param callResponse the failed call response

operator/src/main/java/oracle/kubernetes/operator/calls/unprocessable/UnrecoverableErrorBuilderImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ public static boolean isNotFound(ApiException e) {
6969
return code == 404 || code == 410;
7070
}
7171

72+
public static boolean hasConflict(ApiException e) {
73+
return e.getCode() == 409;
74+
}
75+
7276
/**
7377
* Create unrecoverable error builder.
7478
*/

operator/src/main/java/oracle/kubernetes/operator/helpers/EventHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ public NextAction onFailure(Packet packet, CallResponse<CoreV1Event> callRespons
257257
if (hasLoggedForbiddenNSWatchStoppedEvent(this, callResponse)) {
258258
return doNext(packet);
259259
}
260-
if (UnrecoverableErrorBuilder.isAsyncCallNotFoundFailure(callResponse)) {
260+
if (UnrecoverableErrorBuilder.isAsyncCallNotFoundFailure(callResponse)
261+
|| UnrecoverableErrorBuilder.isAsyncCallConflictFailure(callResponse)) {
261262
return doNext(Step.chain(createCreateEventCall(createEventModel(packet, eventData)), getNext()), packet);
262263
} else if (UnrecoverableErrorBuilder.isAsyncCallUnrecoverableFailure(callResponse)) {
263264
return onFailureNoRetry(packet, callResponse);

operator/src/main/java/oracle/kubernetes/operator/helpers/ResponseStep.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ private NextAction doPotentialRetry(Step conflictStep, Packet packet, CallRespon
139139
.map(rs -> rs.doPotentialRetry(conflictStep, packet, callResponse.getStatusCode()))
140140
.orElseGet(() -> {
141141
LOGGER.fine(MessageKeys.ASYNC_NO_RETRY,
142-
callResponse.getExceptionString(), callResponse.getStatusCode(), callResponse.getHeadersString());
142+
callResponse.getRequestParams().call,
143+
callResponse.getExceptionString(), callResponse.getStatusCode(), callResponse.getHeadersString());
143144
return null;
144145
});
145146
}

operator/src/main/resources/Operator.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ WLSKO-0089=Pod {0} has failed
6060
WLSKO-0094=Async call {0} invoking: {1}, namespace: {2}, name: {3}, body: {4}, fieldSelector: {5}, labelSelector: {6}, resourceVersion: {7}
6161
WLSKO-0095=Async call {0} failed: {1}, code: {2}, headers {3} after invoking {4}, namespace: {5}, name: {6}, body: {7}, fieldSelector: {8}, labelSelector: {9}, resourceVersion: {10}, response body: {11}
6262
WLSKO-0096=Async call {0} invoking: {1} succeeded: {2}, code: {3}, headers {4}
63-
WLSKO-0097=Async call will not be retried: {0}, code: {1}, headers {2}
63+
WLSKO-0097=Async call {0} will not be retried: {1}, code: {2}, headers {3}
6464
WLSKO-0098=Async call {0} will be retried after delay: {1} ms: {2}, namespace: {3}, name: {4}
6565
WLSKO-0099=Async call {0} timed-out: {1}, namespace: {2}, name: {3}, body: {4}, fieldSelector: {5}, labelSelector: {6}, resourceVersion: {7}
6666
WLSKO-0101=Watch event: {0}, object: {1}

operator/src/test/java/oracle/kubernetes/operator/helpers/EventHelperTest.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,22 @@ public void whenCreateEventTwice_fail404OnReplaceEvent_domainProcessingStartingE
277277
containsEventsWithCountOne(getEvents(testSupport), DOMAIN_PROCESSING_STARTING_EVENT, 2));
278278
}
279279

280+
@Test
281+
public void whenCreateEventTwice_fail409OnReplaceEvent_domainProcessingStartingEventCreatedTwice() {
282+
testSupport.runSteps(Step.chain(
283+
createEventStep(new EventData(DOMAIN_PROCESSING_STARTING)),
284+
createEventStep(new EventData(DOMAIN_PROCESSING_COMPLETED))));
285+
286+
dispatchAddedEventWatches();
287+
CoreV1Event event = EventTestUtils.getEventWithReason(getEvents(testSupport), DOMAIN_PROCESSING_STARTING_EVENT);
288+
testSupport.failOnReplace(EVENT, EventTestUtils.getName(event), NS, HTTP_CONFLICT);
289+
290+
testSupport.runSteps(Step.chain(createEventStep(new EventData(DOMAIN_PROCESSING_STARTING))));
291+
292+
assertThat("Found 2 DOMAIN_PROCESSING_STARTING events with count 1",
293+
containsEventsWithCountOne(getEvents(testSupport), DOMAIN_PROCESSING_STARTING_EVENT, 2));
294+
}
295+
280296
@Test
281297
public void whenCreateEventTwice_fail410OnReplaceEvent_domainProcessingStartingEventCreatedTwice() {
282298
testSupport.runSteps(Step.chain(
@@ -819,8 +835,8 @@ public void whenNSWatchStoppedEventCreatedTwice_fail409OnReplace_eventCreatedOnc
819835

820836
testSupport.runSteps(eventStep);
821837

822-
assertThat("Found 1 NAMESPACE_WATCHING_STOPPED event with expected count 2",
823-
containsOneEventWithCount(getEvents(testSupport),
838+
assertThat("Found 2 NAMESPACE_WATCHING_STOPPED event with expected count 1",
839+
containsEventsWithCountOne(getEvents(testSupport),
824840
NAMESPACE_WATCHING_STOPPED_EVENT, 2), is(true));
825841
}
826842

0 commit comments

Comments
 (0)