1
1
package io .javaoperatorsdk .operator .processing .event ;
2
2
3
+ import java .net .HttpURLConnection ;
3
4
import java .time .Duration ;
4
5
import java .util .HashMap ;
5
6
import java .util .Map ;
10
11
import org .slf4j .LoggerFactory ;
11
12
12
13
import io .fabric8 .kubernetes .api .model .HasMetadata ;
14
+ import io .fabric8 .kubernetes .client .KubernetesClientException ;
13
15
import io .javaoperatorsdk .operator .OperatorException ;
14
16
import io .javaoperatorsdk .operator .api .config .ConfigurationService ;
15
17
import io .javaoperatorsdk .operator .api .config .ControllerConfiguration ;
@@ -224,6 +226,7 @@ synchronized void eventProcessingFinished(
224
226
postExecutionControl );
225
227
unsetUnderExecution (resourceID );
226
228
229
+ logErrorIfNoRetryConfigured (executionScope , postExecutionControl );
227
230
// If a delete event present at this phase, it was received during reconciliation.
228
231
// So we either removed the finalizer during reconciliation or we don't use finalizers.
229
232
// Either way we don't want to retry.
@@ -261,6 +264,17 @@ synchronized void eventProcessingFinished(
261
264
}
262
265
}
263
266
267
+ /**
268
+ * In case retry is configured more complex error logging takes place, see handleRetryOnException
269
+ */
270
+ private void logErrorIfNoRetryConfigured (ExecutionScope <P > executionScope ,
271
+ PostExecutionControl <P > postExecutionControl ) {
272
+ if (!isRetryConfigured () && postExecutionControl .exceptionDuringExecution ()) {
273
+ log .error ("Error during event processing {}" , executionScope ,
274
+ postExecutionControl .getRuntimeException ().orElseThrow ());
275
+ }
276
+ }
277
+
264
278
private void reScheduleExecutionIfInstructed (
265
279
PostExecutionControl <P > postExecutionControl , P customResource ) {
266
280
@@ -302,6 +316,7 @@ private void handleRetryOnException(
302
316
boolean eventPresent = state .eventPresent ();
303
317
state .markEventReceived ();
304
318
319
+ retryAwareErrorLogging (state .getRetry (), eventPresent , exception , executionScope );
305
320
if (eventPresent ) {
306
321
log .debug ("New events exists for for resource id: {}" , resourceID );
307
322
submitReconciliationExecution (state );
@@ -319,11 +334,29 @@ private void handleRetryOnException(
319
334
retryEventSource ().scheduleOnce (resourceID , delay );
320
335
},
321
336
() -> {
322
- log .error ("Exhausted retries for {} " , executionScope );
337
+ log .error ("Exhausted retries for scope {}. " , executionScope );
323
338
scheduleExecutionForMaxReconciliationInterval (executionScope .getResource ());
324
339
});
325
340
}
326
341
342
+ private void retryAwareErrorLogging (RetryExecution retry , boolean eventPresent ,
343
+ Exception exception ,
344
+ ExecutionScope <P > executionScope ) {
345
+ if (!eventPresent && !retry .isLastAttempt () && exception instanceof KubernetesClientException ) {
346
+ KubernetesClientException ex = (KubernetesClientException ) exception ;
347
+ if (ex .getCode () == HttpURLConnection .HTTP_CONFLICT ) {
348
+ log .debug ("Full client conflict error during event processing {}" , executionScope ,
349
+ exception );
350
+ log .warn (
351
+ "Resource Kubernetes Resource Creator/Update Conflict during reconciliation. Message: {} Resource name: {}" ,
352
+ ex .getMessage (), ex .getFullResourceName ());
353
+ return ;
354
+ }
355
+ }
356
+ log .error ("Error during event processing {}" , executionScope ,
357
+ exception );
358
+ }
359
+
327
360
private void cleanupOnSuccessfulExecution (ExecutionScope <P > executionScope ) {
328
361
log .debug (
329
362
"Cleanup for successful execution for resource: {}" , getName (executionScope .getResource ()));
0 commit comments