Skip to content

Commit b068d1d

Browse files
committed
wip
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 825cd2e commit b068d1d

18 files changed

+141
-36
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,14 @@ private <P extends HasMetadata> ResolvedControllerConfiguration<P> controllerCon
296296
final var dependentFieldManager =
297297
fieldManager.equals(CONTROLLER_NAME_AS_FIELD_MANAGER) ? name : fieldManager;
298298

299+
var controllerMode = annotation == null ? ControllerMode.DEFAULT : annotation.controllerMode();
300+
299301
InformerConfiguration<P> informerConfig =
300302
InformerConfiguration.builder(resourceClass)
301303
.initFromAnnotation(annotation != null ? annotation.informer() : null, context)
302304
.buildForController();
303305

304-
return new ResolvedControllerConfiguration<P>(
306+
return new ResolvedControllerConfiguration<>(
305307
name,
306308
generationAware,
307309
associatedReconcilerClass,
@@ -315,7 +317,8 @@ private <P extends HasMetadata> ResolvedControllerConfiguration<P> controllerCon
315317
null,
316318
dependentFieldManager,
317319
this,
318-
informerConfig);
320+
informerConfig,
321+
controllerMode);
319322
}
320323

321324
protected boolean createIfNeeded() {

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,11 @@ default String fieldManager() {
9393

9494
<C> C getConfigurationFor(DependentResourceSpec<?, P, C> spec);
9595

96-
default ControllerMode getMode() {
96+
default ControllerMode getControllerMode() {
9797
return ControllerMode.DEFAULT;
9898
}
99+
100+
default boolean isAllEventReconcileMode() {
101+
return getControllerMode() == ControllerMode.ALL_EVENT_RECONCILE;
102+
}
99103
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class ControllerConfigurationOverrider<R extends HasMetadata> {
3030
private Duration reconciliationMaxInterval;
3131
private Map<DependentResourceSpec, Object> configurations;
3232
private final InformerConfiguration<R>.Builder config;
33+
private ControllerMode controllerMode;
3334

3435
private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
3536
this.finalizer = original.getFinalizerName();
@@ -42,6 +43,7 @@ private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
4243
this.rateLimiter = original.getRateLimiter();
4344
this.name = original.getName();
4445
this.fieldManager = original.fieldManager();
46+
this.controllerMode = original.getControllerMode();
4547
}
4648

4749
public ControllerConfigurationOverrider<R> withFinalizer(String finalizer) {
@@ -154,6 +156,11 @@ public ControllerConfigurationOverrider<R> withFieldManager(String dependentFiel
154156
return this;
155157
}
156158

159+
public ControllerConfigurationOverrider<R> withControllerMode(ControllerMode controllerMode) {
160+
this.controllerMode = controllerMode;
161+
return this;
162+
}
163+
157164
/**
158165
* Sets a max page size limit when starting the informer. This will result in pagination while
159166
* populating the cache. This means that longer lists will take multiple requests to fetch. See
@@ -198,6 +205,7 @@ public ControllerConfiguration<R> build() {
198205
fieldManager,
199206
original.getConfigurationService(),
200207
config.buildForController(),
208+
controllerMode,
201209
original.getWorkflowSpec().orElse(null));
202210
}
203211

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerMode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
public enum ControllerMode {
44
DEFAULT,
5-
RECONCILE_ALL_EVENT
5+
ALL_EVENT_RECONCILE
66
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class ResolvedControllerConfiguration<P extends HasMetadata>
3030
private final ConfigurationService configurationService;
3131
private final String fieldManager;
3232
private WorkflowSpec workflowSpec;
33+
private ControllerMode controllerMode;
3334

3435
public ResolvedControllerConfiguration(ControllerConfiguration<P> other) {
3536
this(
@@ -44,6 +45,7 @@ public ResolvedControllerConfiguration(ControllerConfiguration<P> other) {
4445
other.fieldManager(),
4546
other.getConfigurationService(),
4647
other.getInformerConfig(),
48+
other.getControllerMode(),
4749
other.getWorkflowSpec().orElse(null));
4850
}
4951

@@ -59,6 +61,7 @@ public ResolvedControllerConfiguration(
5961
String fieldManager,
6062
ConfigurationService configurationService,
6163
InformerConfiguration<P> informerConfig,
64+
ControllerMode controllerMode,
6265
WorkflowSpec workflowSpec) {
6366
this(
6467
name,
@@ -71,7 +74,8 @@ public ResolvedControllerConfiguration(
7174
configurations,
7275
fieldManager,
7376
configurationService,
74-
informerConfig);
77+
informerConfig,
78+
controllerMode);
7579
setWorkflowSpec(workflowSpec);
7680
}
7781

@@ -86,7 +90,8 @@ protected ResolvedControllerConfiguration(
8690
Map<DependentResourceSpec, Object> configurations,
8791
String fieldManager,
8892
ConfigurationService configurationService,
89-
InformerConfiguration<P> informerConfig) {
93+
InformerConfiguration<P> informerConfig,
94+
ControllerMode controllerMode) {
9095
this.informerConfig = informerConfig;
9196
this.configurationService = configurationService;
9297
this.name = ControllerConfiguration.ensureValidName(name, associatedReconcilerClassName);
@@ -99,6 +104,7 @@ protected ResolvedControllerConfiguration(
99104
this.finalizer =
100105
ControllerConfiguration.ensureValidFinalizerName(finalizer, getResourceTypeName());
101106
this.fieldManager = fieldManager;
107+
this.controllerMode = controllerMode;
102108
}
103109

104110
protected ResolvedControllerConfiguration(
@@ -117,7 +123,8 @@ protected ResolvedControllerConfiguration(
117123
null,
118124
null,
119125
configurationService,
120-
InformerConfiguration.builder(resourceClass).buildForController());
126+
InformerConfiguration.builder(resourceClass).buildForController(),
127+
null);
121128
}
122129

123130
@Override
@@ -207,4 +214,9 @@ public <C> C getConfigurationFor(DependentResourceSpec<?, P, C> spec) {
207214
public String fieldManager() {
208215
return fieldManager;
209216
}
217+
218+
@Override
219+
public ControllerMode getControllerMode() {
220+
return controllerMode;
221+
}
210222
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,8 @@ default <R> Stream<R> getSecondaryResourcesAsStream(Class<R> expectedType) {
7272
* @return {@code true} is another reconciliation is already scheduled, {@code false} otherwise
7373
*/
7474
boolean isNextReconciliationImminent();
75+
76+
boolean isDeleteEventPresent();
77+
78+
boolean isDeleteFinalStateUnknown();
7579
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,5 @@ MaxReconciliationInterval maxReconciliationInterval() default
7979
*/
8080
String fieldManager() default CONTROLLER_NAME_AS_FIELD_MANAGER;
8181

82-
ControllerMode allEventMode() default ControllerMode.DEFAULT;
82+
ControllerMode controllerMode() default ControllerMode.DEFAULT;
8383
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,21 @@ public class DefaultContext<P extends HasMetadata> implements Context<P> {
2424
private final ControllerConfiguration<P> controllerConfiguration;
2525
private final DefaultManagedWorkflowAndDependentResourceContext<P>
2626
defaultManagedDependentResourceContext;
27-
28-
public DefaultContext(RetryInfo retryInfo, Controller<P> controller, P primaryResource) {
27+
private final boolean isDeleteEventPresent;
28+
private final boolean isDeleteFinalStateUnknown;
29+
30+
public DefaultContext(
31+
RetryInfo retryInfo,
32+
Controller<P> controller,
33+
P primaryResource,
34+
boolean isDeleteEventPresent,
35+
boolean isDeleteFinalStateUnknown) {
2936
this.retryInfo = retryInfo;
3037
this.controller = controller;
3138
this.primaryResource = primaryResource;
3239
this.controllerConfiguration = controller.getConfiguration();
40+
this.isDeleteEventPresent = isDeleteEventPresent;
41+
this.isDeleteFinalStateUnknown = isDeleteFinalStateUnknown;
3342
this.defaultManagedDependentResourceContext =
3443
new DefaultManagedWorkflowAndDependentResourceContext<>(controller, primaryResource, this);
3544
}
@@ -119,6 +128,16 @@ public boolean isNextReconciliationImminent() {
119128
.isNextReconciliationImminent(ResourceID.fromResource(primaryResource));
120129
}
121130

131+
@Override
132+
public boolean isDeleteEventPresent() {
133+
return isDeleteEventPresent;
134+
}
135+
136+
@Override
137+
public boolean isDeleteFinalStateUnknown() {
138+
return isDeleteFinalStateUnknown;
139+
}
140+
122141
public DefaultContext<P> setRetryInfo(RetryInfo retryInfo) {
123142
this.retryInfo = retryInfo;
124143
return this;

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

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import io.javaoperatorsdk.operator.OperatorException;
1616
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1717
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
18-
import io.javaoperatorsdk.operator.api.config.ControllerMode;
1918
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
2019
import io.javaoperatorsdk.operator.api.reconciler.Constants;
2120
import io.javaoperatorsdk.operator.processing.LifecycleAware;
@@ -24,6 +23,7 @@
2423
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter.RateLimitState;
2524
import io.javaoperatorsdk.operator.processing.event.source.Cache;
2625
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceAction;
26+
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceDeleteEvent;
2727
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEvent;
2828
import io.javaoperatorsdk.operator.processing.event.source.timer.TimerEventSource;
2929
import io.javaoperatorsdk.operator.processing.retry.Retry;
@@ -123,7 +123,7 @@ public synchronized void handleEvent(Event event) {
123123
}
124124

125125
private void handleMarkedEventForResource(ResourceState state) {
126-
if (state.deleteEventPresent() && !isAllEventMode()) {
126+
if (state.deleteEventPresent() && !controllerConfiguration.isAllEventReconcileMode()) {
127127
cleanupForDeletedEvent(state.getId());
128128
} else if (!state.processedMarkForDeletionPresent()) {
129129
submitReconciliationExecution(state);
@@ -180,7 +180,9 @@ private void handleEventMarking(Event event, ResourceState state) {
180180
if (event instanceof ResourceEvent resourceEvent) {
181181
if (resourceEvent.getAction() == ResourceAction.DELETED) {
182182
log.debug("Marking delete event received for: {}", relatedCustomResourceID);
183-
state.markDeleteEventReceived(resourceEvent.getResource().orElseThrow());
183+
state.markDeleteEventReceived(
184+
resourceEvent.getResource().orElseThrow(),
185+
((ResourceDeleteEvent) resourceEvent).isDeletedFinalStateUnknown());
184186
} else {
185187
if (state.processedMarkForDeletionPresent() && isResourceMarkedForDeletion(resourceEvent)) {
186188
log.debug(
@@ -252,7 +254,8 @@ synchronized void eventProcessingFinished(
252254
}
253255
cleanupOnSuccessfulExecution(executionScope);
254256
metrics.finishedReconciliation(executionScope.getResource(), metricsMetadata);
255-
if (state.deleteEventPresent()) {
257+
if ((controllerConfiguration.isAllEventReconcileMode() && executionScope.isDeleteEvent())
258+
|| (!controllerConfiguration.isAllEventReconcileMode() && state.deleteEventPresent())) {
256259
cleanupForDeletedEvent(executionScope.getResourceID());
257260
} else if (postExecutionControl.isFinalizerRemoved()) {
258261
state.markProcessedMarkForDeletion();
@@ -451,6 +454,7 @@ private ReconcilerExecutor(ResourceID resourceID, ExecutionScope<P> executionSco
451454
}
452455

453456
@Override
457+
@SuppressWarnings("unchecked")
454458
public void run() {
455459
if (!running) {
456460
// this is needed for the case when controller stopped, but there is a graceful shutdown
@@ -465,15 +469,26 @@ public void run() {
465469
try {
466470
var actualResource = cache.get(resourceID);
467471
if (actualResource.isEmpty()) {
468-
if (isAllEventMode()) {
472+
if (controllerConfiguration.isAllEventReconcileMode()) {
473+
log.debug(
474+
"Resource not found in the cache, checking for delete event resource: {}",
475+
resourceID);
469476
var state = resourceStateManager.get(resourceID);
470477
actualResource =
471478
(Optional<P>)
472-
state.filter(s -> s.deleteEventPresent()).map(s -> s.getLastKnownResource());
479+
state
480+
.filter(ResourceState::deleteEventPresent)
481+
.map(ResourceState::getLastKnownResource);
482+
if (actualResource.isEmpty()) {
483+
log.debug(
484+
"Skipping execution; delete event resource not found in state: {}", resourceID);
485+
return;
486+
}
487+
executionScope.setDeleteEvent(true);
488+
} else {
489+
log.debug("Skipping execution; primary resource missing from cache: {}", resourceID);
490+
return;
473491
}
474-
475-
log.debug("Skipping execution; primary resource missing from cache: {}", resourceID);
476-
return;
477492
}
478493
actualResource.ifPresent(executionScope::setResource);
479494
MDCUtils.addResourceInfo(executionScope.getResource());
@@ -509,8 +524,4 @@ public synchronized boolean isUnderProcessing(ResourceID resourceID) {
509524
public synchronized boolean isRunning() {
510525
return running;
511526
}
512-
513-
private boolean isAllEventMode() {
514-
return controllerConfiguration.getMode() == ControllerMode.RECONCILE_ALL_EVENT;
515-
}
516527
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class ExecutionScope<R extends HasMetadata> {
88
// the latest custom resource from cache
99
private R resource;
1010
private final RetryInfo retryInfo;
11+
private boolean deleteEvent = false;
12+
private boolean isDeleteFinalStateUnknown = false;
1113

1214
ExecutionScope(RetryInfo retryInfo) {
1315
this.retryInfo = retryInfo;
@@ -26,6 +28,22 @@ public ResourceID getResourceID() {
2628
return ResourceID.fromResource(resource);
2729
}
2830

31+
public boolean isDeleteEvent() {
32+
return deleteEvent;
33+
}
34+
35+
public void setDeleteEvent(boolean deleteEvent) {
36+
this.deleteEvent = deleteEvent;
37+
}
38+
39+
public boolean isDeleteFinalStateUnknown() {
40+
return isDeleteFinalStateUnknown;
41+
}
42+
43+
public void setDeleteFinalStateUnknown(boolean deleteFinalStateUnknown) {
44+
isDeleteFinalStateUnknown = deleteFinalStateUnknown;
45+
}
46+
2947
@Override
3048
public String toString() {
3149
if (resource == null) {

0 commit comments

Comments
 (0)