Skip to content

Commit c4b5371

Browse files
committed
fixes for code review
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 18e6a40 commit c4b5371

File tree

7 files changed

+73
-15
lines changed

7 files changed

+73
-15
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,20 @@ public static <P extends HasMetadata> P removeFinalizer(
274274
r -> r.hasFinalizer(finalizerName));
275275
}
276276

277+
/**
278+
* @param client KubernetesClient
279+
* @param resource to update
280+
* @param resourceChangesOperator changes to be done on the resource before update
281+
* @param preCondition condition to check if the patch operation still needs to be performed or
282+
* not.
283+
* @return updated resource or unchanged if the precondition does not hold.
284+
* @param <P> resource type
285+
*/
277286
@SuppressWarnings("unchecked")
278287
public static <P extends HasMetadata> P conflictRetryingPatch(
279288
KubernetesClient client,
280289
P resource,
281-
UnaryOperator<P> unaryOperator,
290+
UnaryOperator<P> resourceChangesOperator,
282291
Predicate<P> preCondition) {
283292
if (log.isDebugEnabled()) {
284293
log.debug("Conflict retrying update for: {}", ResourceID.fromResource(resource));
@@ -289,7 +298,7 @@ public static <P extends HasMetadata> P conflictRetryingPatch(
289298
if (!preCondition.test(resource)) {
290299
return resource;
291300
}
292-
return client.resource(resource).edit(unaryOperator);
301+
return client.resource(resource).edit(resourceChangesOperator);
293302
} catch (KubernetesClientException e) {
294303
log.trace("Exception during patch for resource: {}", resource);
295304
retryIndex++;

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private void submitReconciliationExecution(ResourceState state) {
145145
Optional<P> maybeLatest = cache.get(resourceID);
146146
maybeLatest.ifPresent(MDCUtils::addResourceInfo);
147147
if (!controllerUnderExecution
148-
&& (maybeLatest.isPresent() || (triggerOnAllEvent() && state.deleteEventPresent()))) {
148+
&& (maybeLatest.isPresent() || isTriggerOnAllEventAndDeleteEventPresent(state))) {
149149
var rateLimit = state.getRateLimit();
150150
if (rateLimit == null) {
151151
rateLimit = rateLimiter.initState();
@@ -228,7 +228,7 @@ private void handleEventMarking(Event event, ResourceState state) {
228228
}
229229
} else if (!state.deleteEventPresent() && !state.processedMarkForDeletionPresent()) {
230230
state.markEventReceived(triggerOnAllEvent());
231-
} else if (triggerOnAllEvent() && state.deleteEventPresent()) {
231+
} else if (isTriggerOnAllEventAndDeleteEventPresent(state)) {
232232
state.markAdditionalEventAfterDeleteEvent();
233233
} else if (log.isDebugEnabled()) {
234234
log.debug(
@@ -285,7 +285,7 @@ synchronized void eventProcessingFinished(
285285
state.markProcessedMarkForDeletion();
286286
metrics.cleanupDoneFor(resourceID, metricsMetadata);
287287
} else {
288-
if (state.eventPresent() || (triggerOnAllEvent() && state.deleteEventPresent())) {
288+
if (state.eventPresent() || isTriggerOnAllEventAndDeleteEventPresent(state)) {
289289
log.debug("Submitting for reconciliation.");
290290
submitReconciliationExecution(state);
291291
} else {
@@ -294,6 +294,10 @@ synchronized void eventProcessingFinished(
294294
}
295295
}
296296

297+
private boolean isTriggerOnAllEventAndDeleteEventPresent(ResourceState state) {
298+
return triggerOnAllEvent() && state.deleteEventPresent();
299+
}
300+
297301
/**
298302
* In case retry is configured more complex error logging takes place, see handleRetryOnException
299303
*/
@@ -502,15 +506,16 @@ public void run() {
502506
log.debug(
503507
"Resource not found in the cache, checking for delete event resource: {}",
504508
resourceID);
505-
var state = resourceStateManager.get(resourceID);
506509
if (executionScope.isDeleteEvent()) {
510+
var state = resourceStateManager.get(resourceID);
507511
actualResource =
508512
(Optional<P>)
509513
state
510514
.filter(ResourceState::deleteEventPresent)
511515
.map(ResourceState::getLastKnownResource);
512516
if (actualResource.isEmpty()) {
513-
throw new IllegalStateException("this should not happen");
517+
throw new IllegalStateException(
518+
"ActualResource should be always present, either from cache or delete event.");
514519
}
515520
} else {
516521
log.debug("Skipping execution since delete event received meanwhile");

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public ReconciliationDispatcher(Controller<P> controller) {
6464
}
6565

6666
public PostExecutionControl<P> handleExecution(ExecutionScope<P> executionScope) {
67+
validateExecutionScope(executionScope);
6768
try {
6869
return handleDispatch(executionScope);
6970
} catch (Exception e) {
@@ -90,7 +91,6 @@ && shouldNotDispatchToCleanupWhenMarkedForDeletion(originalResource)) {
9091
originalResource.getMetadata().getFinalizers());
9192
return PostExecutionControl.defaultDispatch();
9293
}
93-
9494
Context<P> context =
9595
new DefaultContext<>(
9696
executionScope.getRetryInfo(),
@@ -435,6 +435,15 @@ public P conflictRetryingPatch(
435435
}
436436
}
437437

438+
private void validateExecutionScope(ExecutionScope<P> executionScope) {
439+
if (!triggerOnAllEvent()
440+
&& (executionScope.isDeleteEvent() || executionScope.isDeleteFinalStateUnknown())) {
441+
throw new OperatorException(
442+
"isDeleteEvent or isDeleteFinalStateUnknown cannot be true if not triggerOnAllEvent."
443+
+ " This indicates an issue with the implementation.");
444+
}
445+
}
446+
438447
// created to support unit testing
439448
static class CustomResourceFacade<R extends HasMetadata> {
440449

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ private enum EventingState {
3838
private EventingState eventing;
3939
private RateLimitState rateLimit;
4040
private HasMetadata lastKnownResource;
41-
private boolean isDeleteFinalStateUnknown;
41+
private boolean isDeleteFinalStateUnknown = false;
4242

4343
public ResourceState(ResourceID id) {
4444
this.id = id;

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ public void onUpdate(T oldCustomResource, T newCustomResource) {
124124
}
125125

126126
@Override
127-
public void onDelete(T resource, boolean b) {
128-
super.onDelete(resource, b);
129-
eventReceived(ResourceAction.DELETED, resource, null, b);
127+
public void onDelete(T resource, boolean deletedFinalStateUnknown) {
128+
super.onDelete(resource, deletedFinalStateUnknown);
129+
eventReceived(ResourceAction.DELETED, resource, null, deletedFinalStateUnknown);
130130
}
131131

132132
@Override

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceDeleteEvent.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package io.javaoperatorsdk.operator.processing.event.source.controller;
22

3+
import java.util.Objects;
4+
35
import io.fabric8.kubernetes.api.model.HasMetadata;
46
import io.javaoperatorsdk.operator.processing.event.ResourceID;
57

8+
/**
9+
* Extends ResourceEvent for informer Delete events, it holds also information if the final stat is
10+
* unknown for the deleted resource.
11+
*/
612
public class ResourceDeleteEvent extends ResourceEvent {
713

814
private final boolean deletedFinalStateUnknown;
@@ -19,4 +25,18 @@ public ResourceDeleteEvent(
1925
public boolean isDeletedFinalStateUnknown() {
2026
return deletedFinalStateUnknown;
2127
}
28+
29+
@Override
30+
public boolean equals(Object o) {
31+
if (this == o) return true;
32+
if (o == null || getClass() != o.getClass()) return false;
33+
if (!super.equals(o)) return false;
34+
ResourceDeleteEvent that = (ResourceDeleteEvent) o;
35+
return deletedFinalStateUnknown == that.deletedFinalStateUnknown;
36+
}
37+
38+
@Override
39+
public int hashCode() {
40+
return Objects.hash(super.hashCode(), deletedFinalStateUnknown);
41+
}
2242
}

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
@@ -687,6 +687,24 @@ void reSchedulesFromErrorHandler() {
687687
assertThat(res.getRuntimeException()).isEmpty();
688688
}
689689

690+
@Test
691+
void isDeleteEventCannotBeTrueIfNotTriggerOnAllEvent() {
692+
assertThrows(
693+
OperatorException.class,
694+
() ->
695+
reconciliationDispatcher.handleExecution(
696+
new ExecutionScope(null, null, true, false).setResource(testCustomResource)));
697+
}
698+
699+
@Test
700+
void isDeleteFinalStateUnknownEventCannotBeTrueIfNotTriggerOnAllEvent() {
701+
assertThrows(
702+
OperatorException.class,
703+
() ->
704+
reconciliationDispatcher.handleExecution(
705+
new ExecutionScope(null, null, false, true).setResource(testCustomResource)));
706+
}
707+
690708
@Test
691709
void reconcilerContextUsesTheSameInstanceOfResourceAsParam() {
692710
initConfigService(false, false);
@@ -709,9 +727,6 @@ void reconcilerContextUsesTheSameInstanceOfResourceAsParam() {
709727
.isNotSameAs(testCustomResource);
710728
}
711729

712-
@Test
713-
void procAllEventModeNoReSchedulesAllowedForDeleteEvent() {}
714-
715730
private ObservedGenCustomResource createObservedGenCustomResource() {
716731
ObservedGenCustomResource observedGenCustomResource = new ObservedGenCustomResource();
717732
observedGenCustomResource.setMetadata(new ObjectMeta());

0 commit comments

Comments
 (0)