diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java
index 57679f48ca..4ac69a199d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java
@@ -151,11 +151,11 @@ private void submitReconciliationExecution(ResourceState state) {
}
state.setUnderProcessing(true);
final var latest = maybeLatest.get();
- ExecutionScope
executionScope = new ExecutionScope<>(latest, state.getRetry());
+ ExecutionScope
executionScope = new ExecutionScope<>(state.getRetry());
state.unMarkEventReceived();
metrics.reconcileCustomResource(latest, state.getRetry(), metricsMetadata);
log.debug("Executing events for custom resource. Scope: {}", executionScope);
- executor.execute(new ReconcilerExecutor(executionScope));
+ executor.execute(new ReconcilerExecutor(resourceID, executionScope));
} else {
log.debug(
"Skipping executing controller for resource id: {}. Controller in execution: {}. Latest Resource present: {}",
@@ -388,9 +388,11 @@ private void handleAlreadyMarkedEvents() {
private class ReconcilerExecutor implements Runnable {
private final ExecutionScope
executionScope;
+ private final ResourceID resourceID;
- private ReconcilerExecutor(ExecutionScope
executionScope) {
+ private ReconcilerExecutor(ResourceID resourceID, ExecutionScope
executionScope) {
this.executionScope = executionScope;
+ this.resourceID = resourceID;
}
@Override
@@ -399,6 +401,13 @@ public void run() {
final var thread = Thread.currentThread();
final var name = thread.getName();
try {
+ var actualResource = cache.get(resourceID);
+ if (actualResource.isEmpty()) {
+ log.debug("Skipping execution; primary resource missing from cache: {}",
+ resourceID);
+ return;
+ }
+ actualResource.ifPresent(executionScope::setResource);
MDCUtils.addResourceInfo(executionScope.getResource());
thread.setName("ReconcilerExecutor-" + controllerName() + "-" + thread.getId());
PostExecutionControl
postExecutionControl =
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ExecutionScope.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ExecutionScope.java
index e750c931c3..9621ea915b 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ExecutionScope.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ExecutionScope.java
@@ -6,14 +6,18 @@
class ExecutionScope {
// the latest custom resource from cache
- private final R resource;
+ private R resource;
private final RetryInfo retryInfo;
- ExecutionScope(R resource, RetryInfo retryInfo) {
- this.resource = resource;
+ ExecutionScope(RetryInfo retryInfo) {
this.retryInfo = retryInfo;
}
+ public ExecutionScope setResource(R resource) {
+ this.resource = resource;
+ return this;
+ }
+
public R getResource() {
return resource;
}
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java
index 23b3f5c51c..583e7a7289 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java
@@ -120,7 +120,9 @@ void ifExecutionInProgressWaitsUntilItsFinished() {
void schedulesAnEventRetryOnException() {
TestCustomResource customResource = testCustomResource();
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null);
+ executionScope.setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.exceptionDuringExecution(new RuntimeException("test"));
@@ -254,7 +256,7 @@ void cancelScheduleOnceEventsOnSuccessfulExecution() {
var crID = new ResourceID("test-cr", TEST_NAMESPACE);
var cr = testCustomResource(crID);
- eventProcessor.eventProcessingFinished(new ExecutionScope(cr, null),
+ eventProcessor.eventProcessingFinished(new ExecutionScope(null).setResource(cr),
PostExecutionControl.defaultDispatch());
verify(retryTimerEventSourceMock, times(1)).cancelOnceSchedule(eq(crID));
@@ -283,7 +285,8 @@ void startProcessedMarkedEventReceivedBefore() {
@Test
void updatesEventSourceHandlerIfResourceUpdated() {
TestCustomResource customResource = testCustomResource();
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.customResourceUpdated(customResource);
@@ -297,7 +300,8 @@ void updatesEventSourceHandlerIfResourceUpdated() {
@Test
void notUpdatesEventSourceHandlerIfResourceUpdated() {
TestCustomResource customResource = testCustomResource();
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.customResourceStatusPatched(customResource);
@@ -311,7 +315,8 @@ void notUpdatesEventSourceHandlerIfResourceUpdated() {
void notReschedulesAfterTheFinalizerRemoveProcessed() {
TestCustomResource customResource = testCustomResource();
markForDeletion(customResource);
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.customResourceFinalizerRemoved(customResource);
@@ -324,7 +329,8 @@ void notReschedulesAfterTheFinalizerRemoveProcessed() {
void skipEventProcessingIfFinalizerRemoveProcessed() {
TestCustomResource customResource = testCustomResource();
markForDeletion(customResource);
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.customResourceFinalizerRemoved(customResource);
@@ -341,7 +347,8 @@ void skipEventProcessingIfFinalizerRemoveProcessed() {
void newResourceAfterMissedDeleteEvent() {
TestCustomResource customResource = testCustomResource();
markForDeletion(customResource);
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.customResourceFinalizerRemoved(customResource);
var newResource = testCustomResource();
@@ -377,7 +384,8 @@ void rateLimitsReconciliationSubmission() {
@Test
void schedulesRetryForMarReconciliationInterval() {
TestCustomResource customResource = testCustomResource();
- ExecutionScope executionScope = new ExecutionScope(customResource, null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(customResource);
PostExecutionControl postExecutionControl =
PostExecutionControl.defaultDispatch();
@@ -398,7 +406,8 @@ void schedulesRetryForMarReconciliationIntervalIfRetryExhausted() {
eventSourceManagerMock,
metricsMock));
eventProcessorWithRetry.start();
- ExecutionScope executionScope = new ExecutionScope(testCustomResource(), null);
+ ExecutionScope executionScope =
+ new ExecutionScope(null).setResource(testCustomResource());
PostExecutionControl postExecutionControl =
PostExecutionControl.exceptionDuringExecution(new RuntimeException());
when(eventProcessorWithRetry.retryEventSource()).thenReturn(retryTimerEventSourceMock);
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java
index 892fffcdbb..19bb3fd0a6 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java
@@ -374,7 +374,6 @@ void propagatesRetryInfoToContextIfFinalizerSet() {
reconciliationDispatcher.handleExecution(
new ExecutionScope(
- testCustomResource,
new RetryInfo() {
@Override
public int getAttemptCount() {
@@ -385,7 +384,7 @@ public int getAttemptCount() {
public boolean isLastAttempt() {
return true;
}
- }));
+ }).setResource(testCustomResource));
ArgumentCaptor contextArgumentCaptor =
ArgumentCaptor.forClass(Context.class);
@@ -504,7 +503,6 @@ void callErrorStatusHandlerIfImplemented() {
reconciliationDispatcher.handleExecution(
new ExecutionScope(
- testCustomResource,
new RetryInfo() {
@Override
public int getAttemptCount() {
@@ -515,7 +513,7 @@ public int getAttemptCount() {
public boolean isLastAttempt() {
return true;
}
- }));
+ }).setResource(testCustomResource));
verify(customResourceFacade, times(1)).updateStatus(testCustomResource);
verify(((ErrorStatusHandler) reconciler), times(1)).updateErrorStatus(eq(testCustomResource),
@@ -535,8 +533,7 @@ void callErrorStatusHandlerEvenOnFirstError() {
};
var postExecControl = reconciliationDispatcher.handleExecution(
- new ExecutionScope(
- testCustomResource, null));
+ new ExecutionScope(null).setResource(testCustomResource));
verify(customResourceFacade, times(1)).updateStatus(testCustomResource);
verify(((ErrorStatusHandler) reconciler), times(1)).updateErrorStatus(eq(testCustomResource),
any(), any());
@@ -555,8 +552,7 @@ void errorHandlerCanInstructNoRetryWithUpdate() {
};
var postExecControl = reconciliationDispatcher.handleExecution(
- new ExecutionScope(
- testCustomResource, null));
+ new ExecutionScope(null).setResource(testCustomResource));
verify(((ErrorStatusHandler) reconciler), times(1)).updateErrorStatus(eq(testCustomResource),
any(), any());
@@ -576,8 +572,7 @@ void errorHandlerCanInstructNoRetryNoUpdate() {
};
var postExecControl = reconciliationDispatcher.handleExecution(
- new ExecutionScope(
- testCustomResource, null));
+ new ExecutionScope(null).setResource(testCustomResource));
verify(((ErrorStatusHandler) reconciler), times(1)).updateErrorStatus(eq(testCustomResource),
any(), any());
@@ -596,8 +591,7 @@ void errorStatusHandlerCanPatchResource() {
reconciliationDispatcher.handleExecution(
- new ExecutionScope(
- testCustomResource, null));
+ new ExecutionScope(null).setResource(testCustomResource));
verify(customResourceFacade, times(1)).patchStatus(eq(testCustomResource), any());
verify(((ErrorStatusHandler) reconciler), times(1)).updateErrorStatus(eq(testCustomResource),
@@ -622,8 +616,7 @@ void ifRetryLimitedToZeroMaxAttemptsErrorHandlerGetsCorrectLastAttempt() {
reconciler.errorHandler = mockErrorHandler;
reconciliationDispatcher.handleExecution(
- new ExecutionScope(
- testCustomResource, null));
+ new ExecutionScope(null).setResource(testCustomResource));
verify(mockErrorHandler, times(1)).updateErrorStatus(any(),
ArgumentMatchers.argThat((ArgumentMatcher>) context -> {
@@ -667,7 +660,7 @@ private void removeFinalizers(CustomResource customResource) {
}
public ExecutionScope executionScopeWithCREvent(T resource) {
- return new ExecutionScope<>(resource, null);
+ return (ExecutionScope) new ExecutionScope<>(null).setResource(resource);
}
private class TestReconciler