Skip to content

Commit 9ae6108

Browse files
authored
fix with resource filter bug and related behavior update (#808)
1 parent d08e54b commit 9ae6108

File tree

13 files changed

+171
-18
lines changed

13 files changed

+171
-18
lines changed

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
@@ -55,5 +55,5 @@
5555
* @return the list of event filters.
5656
*/
5757
@SuppressWarnings("rawtypes")
58-
Class<ResourceEventFilter>[] eventFilters() default {};
58+
Class<? extends ResourceEventFilter>[] eventFilters() default {};
5959
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ public ControllerResourceEventSource(Controller<T> controller) {
5454
var filters = new ResourceEventFilter[] {
5555
ResourceEventFilters.finalizerNeededAndApplied(),
5656
ResourceEventFilters.markedForDeletion(),
57-
ResourceEventFilters.and(
58-
controller.getConfiguration().getEventFilter(),
59-
ResourceEventFilters.generationAware()),
57+
ResourceEventFilters.generationAware(),
6058
null
6159
};
6260

@@ -66,7 +64,11 @@ public ControllerResourceEventSource(Controller<T> controller) {
6664
} else {
6765
onceWhitelistEventFilterEventFilter = null;
6866
}
69-
filter = ResourceEventFilters.or(filters);
67+
if (controller.getConfiguration().getEventFilter() != null) {
68+
filter = controller.getConfiguration().getEventFilter().and(ResourceEventFilters.or(filters));
69+
} else {
70+
filter = ResourceEventFilters.or(filters);
71+
}
7072
}
7173

7274
@Override

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public void observedGenerationFiltering() {
123123
}
124124

125125
@Test
126-
public void eventNotFilteredByCustomPredicateIfFinalizerIsRequired() {
126+
public void eventAlwaysFilteredByCustomPredicate() {
127127
var config = new TestControllerConfig(
128128
FINALIZER,
129129
false,
@@ -138,13 +138,7 @@ public void eventNotFilteredByCustomPredicateIfFinalizerIsRequired() {
138138
cr.getStatus().setConfigMapStatus("1");
139139

140140
eventSource.eventReceived(ResourceAction.UPDATED, cr, cr);
141-
verify(eventHandler, times(1)).handleEvent(any());
142-
143-
cr.getMetadata().setGeneration(1L);
144-
cr.getStatus().setConfigMapStatus("1");
145-
146-
eventSource.eventReceived(ResourceAction.UPDATED, cr, cr);
147-
verify(eventHandler, times(2)).handleEvent(any());
141+
verify(eventHandler, times(0)).handleEvent(any());
148142
}
149143

150144
private static class TestControllerConfig extends ControllerConfig<TestCustomResource> {

operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public ResourceEventFilter<R> getEventFilter() {
9090
if (answer == null) {
9191
answer = filter;
9292
} else {
93-
answer = filter.and(filter);
93+
answer = answer.and(filter);
9494
}
9595
} catch (Exception e) {
9696
throw new RuntimeException(e);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.javaoperatorsdk.operator;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.RegisterExtension;
5+
6+
import io.fabric8.kubernetes.api.model.ObjectMeta;
7+
import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
8+
import io.javaoperatorsdk.operator.junit.OperatorExtension;
9+
import io.javaoperatorsdk.operator.sample.customfilter.CustomFilteringTestReconciler;
10+
import io.javaoperatorsdk.operator.sample.customfilter.CustomFilteringTestResource;
11+
import io.javaoperatorsdk.operator.sample.customfilter.CustomFilteringTestResourceSpec;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
public class CustomResourceFilterIT {
16+
17+
@RegisterExtension
18+
OperatorExtension operator =
19+
OperatorExtension.builder()
20+
.withConfigurationService(DefaultConfigurationService.instance())
21+
.withReconciler(new CustomFilteringTestReconciler())
22+
.build();
23+
24+
@Test
25+
public void doesCustomFiltering() throws InterruptedException {
26+
var filtered1 = createTestResource("filtered1", true, false);
27+
var filtered2 = createTestResource("filtered2", false, true);
28+
var notFiltered = createTestResource("notfiltered", true, true);
29+
operator.create(CustomFilteringTestResource.class, filtered1);
30+
operator.create(CustomFilteringTestResource.class, filtered2);
31+
operator.create(CustomFilteringTestResource.class, notFiltered);
32+
33+
Thread.sleep(300);
34+
35+
assertThat(
36+
((CustomFilteringTestReconciler) operator.getReconcilers().get(0)).getNumberOfExecutions())
37+
.isEqualTo(1);
38+
}
39+
40+
41+
CustomFilteringTestResource createTestResource(String name, boolean filter1, boolean filter2) {
42+
CustomFilteringTestResource resource = new CustomFilteringTestResource();
43+
resource.setMetadata(new ObjectMeta());
44+
resource.getMetadata().setName(name);
45+
resource.setSpec(new CustomFilteringTestResourceSpec());
46+
resource.getSpec().setFilter1(filter1);
47+
resource.getSpec().setFilter2(filter2);
48+
return resource;
49+
}
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.javaoperatorsdk.operator.sample.customfilter;
2+
3+
import java.util.concurrent.atomic.AtomicInteger;
4+
5+
import io.javaoperatorsdk.operator.api.reconciler.Context;
6+
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
7+
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
8+
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
9+
10+
@ControllerConfiguration(eventFilters = {CustomFlagFilter.class, CustomFlagFilter2.class})
11+
public class CustomFilteringTestReconciler implements Reconciler<CustomFilteringTestResource> {
12+
13+
private final AtomicInteger numberOfExecutions = new AtomicInteger(0);
14+
15+
@Override
16+
public UpdateControl<CustomFilteringTestResource> reconcile(CustomFilteringTestResource resource,
17+
Context context) {
18+
numberOfExecutions.incrementAndGet();
19+
return UpdateControl.noUpdate();
20+
}
21+
22+
public int getNumberOfExecutions() {
23+
return numberOfExecutions.get();
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.javaoperatorsdk.operator.sample.customfilter;
2+
3+
import io.fabric8.kubernetes.api.model.Namespaced;
4+
import io.fabric8.kubernetes.client.CustomResource;
5+
import io.fabric8.kubernetes.model.annotation.Group;
6+
import io.fabric8.kubernetes.model.annotation.ShortNames;
7+
import io.fabric8.kubernetes.model.annotation.Version;
8+
9+
@Group("sample.javaoperatorsdk")
10+
@Version("v1")
11+
@ShortNames("cft")
12+
public class CustomFilteringTestResource
13+
extends CustomResource<CustomFilteringTestResourceSpec, Void>
14+
implements Namespaced {
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.javaoperatorsdk.operator.sample.customfilter;
2+
3+
public class CustomFilteringTestResourceSpec {
4+
5+
private boolean filter1;
6+
7+
private boolean filter2;
8+
9+
public boolean isFilter1() {
10+
return filter1;
11+
}
12+
13+
public CustomFilteringTestResourceSpec setFilter1(boolean filter1) {
14+
this.filter1 = filter1;
15+
return this;
16+
}
17+
18+
public boolean isFilter2() {
19+
return filter2;
20+
}
21+
22+
public CustomFilteringTestResourceSpec setFilter2(boolean filter2) {
23+
this.filter2 = filter2;
24+
return this;
25+
}
26+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.javaoperatorsdk.operator.sample.customfilter;
2+
3+
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
4+
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter;
5+
6+
public class CustomFlagFilter implements ResourceEventFilter<CustomFilteringTestResource> {
7+
8+
@Override
9+
public boolean acceptChange(ControllerConfiguration<CustomFilteringTestResource> configuration,
10+
CustomFilteringTestResource oldResource, CustomFilteringTestResource newResource) {
11+
return newResource.getSpec().isFilter1();
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.javaoperatorsdk.operator.sample.customfilter;
2+
3+
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
4+
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter;
5+
6+
public class CustomFlagFilter2 implements ResourceEventFilter<CustomFilteringTestResource> {
7+
8+
@Override
9+
public boolean acceptChange(ControllerConfiguration<CustomFilteringTestResource> configuration,
10+
CustomFilteringTestResource oldResource, CustomFilteringTestResource newResource) {
11+
return newResource.getSpec().isFilter2();
12+
}
13+
}

0 commit comments

Comments
 (0)