Skip to content

Commit 73e3dfc

Browse files
authored
fix: managed workflow result is available even when exception is thrown (#2552)
Fixes #2551 Signed-off-by: Chris Laprun <[email protected]>
1 parent 57c4482 commit 73e3dfc

File tree

6 files changed

+20
-35
lines changed

6 files changed

+20
-35
lines changed

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java

+4-17
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88

99
@SuppressWarnings("rawtypes")
1010
public class DefaultManagedDependentResourceContext implements ManagedDependentResourceContext {
11-
12-
private WorkflowReconcileResult workflowReconcileResult;
13-
private WorkflowCleanupResult workflowCleanupResult;
11+
public static final Object RECONCILE_RESULT_KEY = new Object();
12+
public static final Object CLEANUP_RESULT_KEY = new Object();
1413
private final ConcurrentHashMap attributes = new ConcurrentHashMap();
1514

1615
@Override
@@ -37,25 +36,13 @@ public <T> T getMandatory(Object key, Class<T> expectedType) {
3736
+ ") is missing or not of the expected type"));
3837
}
3938

40-
public DefaultManagedDependentResourceContext setWorkflowExecutionResult(
41-
WorkflowReconcileResult workflowReconcileResult) {
42-
this.workflowReconcileResult = workflowReconcileResult;
43-
return this;
44-
}
45-
46-
public DefaultManagedDependentResourceContext setWorkflowCleanupResult(
47-
WorkflowCleanupResult workflowCleanupResult) {
48-
this.workflowCleanupResult = workflowCleanupResult;
49-
return this;
50-
}
51-
5239
@Override
5340
public Optional<WorkflowReconcileResult> getWorkflowReconcileResult() {
54-
return Optional.ofNullable(workflowReconcileResult);
41+
return get(RECONCILE_RESULT_KEY, WorkflowReconcileResult.class);
5542
}
5643

5744
@Override
5845
public Optional<WorkflowCleanupResult> getWorkflowCleanupResult() {
59-
return Optional.ofNullable(workflowCleanupResult);
46+
return get(CLEANUP_RESULT_KEY, WorkflowCleanupResult.class);
6047
}
6148
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java

+1-8
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceNotFoundException;
3939
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider;
4040
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceReferencer;
41-
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext;
4241
import io.javaoperatorsdk.operator.health.ControllerHealthInfo;
4342
import io.javaoperatorsdk.operator.processing.dependent.workflow.Workflow;
4443
import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowCleanupResult;
@@ -145,10 +144,7 @@ public Map<String, Object> metadata() {
145144
public UpdateControl<P> execute() throws Exception {
146145
initContextIfNeeded(resource, context);
147146
if (!managedWorkflow.isEmpty()) {
148-
var res = managedWorkflow.reconcile(resource, context);
149-
((DefaultManagedDependentResourceContext) context.managedDependentResourceContext())
150-
.setWorkflowExecutionResult(res);
151-
res.throwAggregateExceptionIfErrorsPresent();
147+
managedWorkflow.reconcile(resource, context);
152148
}
153149
return reconciler.reconcile(resource, context);
154150
}
@@ -191,9 +187,6 @@ public DeleteControl execute() {
191187
WorkflowCleanupResult workflowCleanupResult = null;
192188
if (managedWorkflow.hasCleaner()) {
193189
workflowCleanupResult = managedWorkflow.cleanup(resource, context);
194-
((DefaultManagedDependentResourceContext) context.managedDependentResourceContext())
195-
.setWorkflowCleanupResult(workflowCleanupResult);
196-
workflowCleanupResult.throwAggregateExceptionIfErrorsPresent();
197190
}
198191
if (isCleaner) {
199192
var cleanupResult = ((Cleaner<P>) reconciler).cleanup(resource, context);

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter;
1313
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
1414
import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected;
15+
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext;
1516
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource;
1617

1718
/**
@@ -79,7 +80,7 @@ private Map<String, DependentResourceNode> toMap(Set<DependentResourceNode> node
7980
}
8081
map.put(node.getName(), node);
8182
}
82-
if (topLevelResources.size() == 0) {
83+
if (topLevelResources.isEmpty()) {
8384
throw new IllegalStateException(
8485
"No top-level dependent resources found. This might indicate a cyclic Set of DependentResourceNode has been provided.");
8586
}
@@ -91,6 +92,8 @@ public WorkflowReconcileResult reconcile(P primary, Context<P> context) {
9192
WorkflowReconcileExecutor<P> workflowReconcileExecutor =
9293
new WorkflowReconcileExecutor<>(this, primary, context);
9394
var result = workflowReconcileExecutor.reconcile();
95+
context.managedDependentResourceContext()
96+
.put(DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY, result);
9497
if (throwExceptionAutomatically) {
9598
result.throwAggregateExceptionIfErrorsPresent();
9699
}
@@ -102,6 +105,8 @@ public WorkflowCleanupResult cleanup(P primary, Context<P> context) {
102105
WorkflowCleanupExecutor<P> workflowCleanupExecutor =
103106
new WorkflowCleanupExecutor<>(this, primary, context);
104107
var result = workflowCleanupExecutor.cleanup();
108+
context.managedDependentResourceContext()
109+
.put(DefaultManagedDependentResourceContext.CLEANUP_RESULT_KEY, result);
105110
if (throwExceptionAutomatically) {
106111
result.throwAggregateExceptionIfErrorsPresent();
107112
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowBuilder.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
@SuppressWarnings({"rawtypes", "unchecked"})
1515
public class WorkflowBuilder<P extends HasMetadata> {
1616

17-
private final Map<String, DependentResourceNode<?, P>> dependentResourceNodes =
18-
new HashMap<>();
17+
private final Map<String, DependentResourceNode<?, P>> dependentResourceNodes = new HashMap<>();
1918
private boolean throwExceptionAutomatically = THROW_EXCEPTION_AUTOMATICALLY_DEFAULT;
2019
private DependentResourceNode currentNode;
2120
private boolean isCleaner = false;

Diff for: operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
1515
import io.javaoperatorsdk.operator.api.reconciler.Context;
1616
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
17+
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext;
1718
import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
1819
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
1920

2021
import static io.javaoperatorsdk.operator.processing.dependent.workflow.ExecutionAssert.assertThat;
2122
import static org.junit.jupiter.api.Assertions.assertThrows;
22-
import static org.mockito.Mockito.mock;
23-
import static org.mockito.Mockito.when;
23+
import static org.mockito.Mockito.*;
2424

2525
class WorkflowCleanupExecutorTest extends AbstractWorkflowExecutorTest {
2626

@@ -29,8 +29,7 @@ class WorkflowCleanupExecutorTest extends AbstractWorkflowExecutorTest {
2929
protected TestDeleterDependent dd3 = new TestDeleterDependent("DR_DELETER_3");
3030
protected TestDeleterDependent dd4 = new TestDeleterDependent("DR_DELETER_4");
3131
@SuppressWarnings("unchecked")
32-
33-
Context<TestCustomResource> mockContext = mock(Context.class);
32+
Context<TestCustomResource> mockContext = spy(Context.class);
3433
ExecutorService executorService = Executors.newCachedThreadPool();
3534

3635
@BeforeEach
@@ -45,7 +44,8 @@ void setup() {
4544
when(eventSourceContextMock.getControllerConfiguration()).thenReturn(mockControllerConfig);
4645
when(mockControllerConfig.getConfigurationService())
4746
.thenReturn(mock(ConfigurationService.class));
48-
47+
when(mockContext.managedDependentResourceContext())
48+
.thenReturn(mock(ManagedDependentResourceContext.class));
4949
when(mockContext.getWorkflowExecutorService()).thenReturn(executorService);
5050
when(mockContext.eventSourceRetriever()).thenReturn(eventSourceRetrieverMock);
5151
}

Diff for: operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@
99

1010
import io.javaoperatorsdk.operator.AggregatedOperatorException;
1111
import io.javaoperatorsdk.operator.api.reconciler.Context;
12+
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext;
1213
import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
1314
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
1415

1516
import static io.javaoperatorsdk.operator.processing.dependent.workflow.ExecutionAssert.assertThat;
1617
import static org.junit.jupiter.api.Assertions.assertThrows;
1718
import static org.mockito.Mockito.*;
1819

19-
@SuppressWarnings("rawtypes")
2020
class WorkflowReconcileExecutorTest extends AbstractWorkflowExecutorTest {
2121

2222
@SuppressWarnings("unchecked")
23-
Context<TestCustomResource> mockContext = mock(Context.class);
23+
Context<TestCustomResource> mockContext = spy(Context.class);
2424
ExecutorService executorService = Executors.newCachedThreadPool();
2525

2626
TestDependent dr3 = new TestDependent("DR_3");
2727
TestDependent dr4 = new TestDependent("DR_4");
2828

2929
@BeforeEach
3030
void setup() {
31+
when(mockContext.managedDependentResourceContext()).thenReturn(mock(ManagedDependentResourceContext.class));
3132
when(mockContext.getWorkflowExecutorService()).thenReturn(executorService);
3233
when(mockContext.eventSourceRetriever()).thenReturn(mock(EventSourceRetriever.class));
3334
}

0 commit comments

Comments
 (0)