Skip to content

Commit 235907d

Browse files
committed
fix: Fix NPE in ReconciliationDispatcher when custom resource cannot be retrieved on finalizer removal retry
1 parent 3a63ab3 commit 235907d

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,12 @@ private PostExecutionControl<P> handleCleanup(P resource,
294294
// cleanup is finished, nothing left to done
295295
final var finalizerName = configuration().getFinalizerName();
296296
if (deleteControl.isRemoveFinalizer() && resource.hasFinalizer(finalizerName)) {
297-
P customResource = conflictRetryingUpdate(resource, r -> r.removeFinalizer(finalizerName));
297+
P customResource = conflictRetryingUpdate(resource, r -> {
298+
if (r == null) {
299+
return false;
300+
}
301+
return r.removeFinalizer(finalizerName);
302+
});
298303
return PostExecutionControl.customResourceFinalizerRemoved(customResource);
299304
}
300305
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,24 @@ void retriesFinalizerRemovalWithFreshResource() {
240240
verify(customResourceFacade, times(1)).getResource(any(), any());
241241
}
242242

243+
@Test
244+
void deletedNamespaceIsGracefullyHandledOnFinalizerRemovalRetry() {
245+
// simulate the namespace being deleted during the finalizer removal, so the custom resource
246+
// cannot be updated and retrieved
247+
testCustomResource.addFinalizer(DEFAULT_FINALIZER);
248+
markForDeletion(testCustomResource);
249+
when(customResourceFacade.updateResource(any()))
250+
.thenThrow(new KubernetesClientException(null, 404, null));
251+
when(customResourceFacade.getResource(any(), any())).thenReturn(null);
252+
253+
var postExecControl =
254+
reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
255+
256+
assertThat(postExecControl.isFinalizerRemoved()).isTrue();
257+
verify(customResourceFacade, times(1)).updateResource(testCustomResource);
258+
verify(customResourceFacade, times(1)).getResource(any(), any());
259+
}
260+
243261
@Test
244262
void throwsExceptionIfFinalizerRemovalRetryExceeded() {
245263
testCustomResource.addFinalizer(DEFAULT_FINALIZER);
@@ -307,8 +325,6 @@ void doesNotAddFinalizerIfConfiguredNotTo() {
307325
assertEquals(0, testCustomResource.getMetadata().getFinalizers().size());
308326
}
309327

310-
311-
312328
@Test
313329
void doesNotRemovesTheSetFinalizerIfTheDeleteNotMethodInstructsIt() {
314330
testCustomResource.addFinalizer(DEFAULT_FINALIZER);
@@ -673,7 +689,6 @@ TestCustomResource createResourceWithFinalizer() {
673689
return resourceWithFinalizer;
674690
}
675691

676-
677692
private void removeFinalizers(CustomResource customResource) {
678693
customResource.getMetadata().getFinalizers().clear();
679694
}

0 commit comments

Comments
 (0)