Skip to content

Commit 1ab86ed

Browse files
committed
generic filter
1 parent c3d1c80 commit 1ab86ed

20 files changed

+105
-21
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
3030
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter;
3131
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters;
32+
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidGenericFilter;
3233
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidOnAddFilter;
3334
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidOnDeleteFilter;
3435
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidOnUpdateFilter;
@@ -158,7 +159,7 @@ public Optional<Predicate<P>> onAddFilter() {
158159

159160
private enum FilterType {
160161
onAdd(VoidOnAddFilter.class), onUpdate(VoidOnUpdateFilter.class), onDelete(
161-
VoidOnDeleteFilter.class);
162+
VoidOnDeleteFilter.class), generic(VoidGenericFilter.class);
162163

163164
final Class<?> defaultValue;
164165

@@ -191,6 +192,13 @@ public Optional<BiPredicate<P, P>> onUpdateFilter() {
191192
FilterType.onUpdate, annotation.getClass().getSimpleName());
192193
}
193194

195+
@SuppressWarnings("unchecked")
196+
@Override
197+
public Optional<Predicate<P>> genericFilter() {
198+
return (Optional<Predicate<P>>) createFilter(annotation.genericFilter(),
199+
FilterType.generic, annotation.getClass().getSimpleName());
200+
}
201+
194202
@SuppressWarnings({"rawtypes", "unchecked"})
195203
@Override
196204
public List<DependentResourceSpec> getDependentResources() {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class ControllerConfigurationOverrider<R extends HasMetadata> {
3434
private final LinkedHashMap<String, DependentResourceSpec> namedDependentResourceSpecs;
3535
private Predicate<R> onAddFilter;
3636
private BiPredicate<R, R> onUpdateFilter;
37+
private Predicate<R> genericFilter;
3738

3839
private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
3940
finalizer = original.getFinalizerName();
@@ -48,6 +49,7 @@ private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
4849
namedDependentResourceSpecs = new LinkedHashMap<>(dependentResources.size());
4950
this.onAddFilter = original.onAddFilter().orElse(null);
5051
this.onUpdateFilter = original.onUpdateFilter().orElse(null);
52+
this.genericFilter = original.genericFilter().orElse(null);
5153
dependentResources.forEach(drs -> namedDependentResourceSpecs.put(drs.getName(), drs));
5254
this.original = original;
5355
}
@@ -139,6 +141,10 @@ public ControllerConfigurationOverrider<R> withOnUpdateFilter(BiPredicate<R, R>
139141
return this;
140142
}
141143

144+
public ControllerConfigurationOverrider<R> withGenericFilter(Predicate<R> genericFilter) {
145+
this.genericFilter = genericFilter;
146+
return this;
147+
}
142148

143149
public ControllerConfigurationOverrider<R> replacingNamedDependentResourceConfig(String name,
144150
Object dependentResourceConfig) {
@@ -189,6 +195,7 @@ public ControllerConfiguration<R> build() {
189195
reconciliationMaxInterval,
190196
onAddFilter,
191197
onUpdateFilter,
198+
genericFilter,
192199
newDependentSpecs);
193200
}
194201

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ public DefaultControllerConfiguration(
4343
Duration reconciliationMaxInterval,
4444
Predicate<R> onAddFilter,
4545
BiPredicate<R, R> onUpdateFilter,
46+
Predicate<R> genericFilter,
4647
List<DependentResourceSpec> dependents) {
47-
super(labelSelector, resourceClass, onAddFilter, onUpdateFilter, namespaces);
48+
super(labelSelector, resourceClass, onAddFilter, onUpdateFilter, genericFilter, namespaces);
4849
this.associatedControllerClassName = associatedControllerClassName;
4950
this.name = name;
5051
this.crdName = crdName;

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,24 @@ public class DefaultResourceConfiguration<R extends HasMetadata>
1717
private final Class<R> resourceClass;
1818
private final Predicate<R> onAddFilter;
1919
private final BiPredicate<R, R> onUpdateFilter;
20+
private final Predicate<R> genericFilter;
2021

2122
public DefaultResourceConfiguration(String labelSelector, Class<R> resourceClass,
2223
Predicate<R> onAddFilter,
23-
BiPredicate<R, R> onUpdateFilter, String... namespaces) {
24-
this(labelSelector, resourceClass, onAddFilter, onUpdateFilter,
24+
BiPredicate<R, R> onUpdateFilter, Predicate<R> genericFilter, String... namespaces) {
25+
this(labelSelector, resourceClass, onAddFilter, onUpdateFilter, genericFilter,
2526
namespaces == null || namespaces.length == 0 ? DEFAULT_NAMESPACES_SET
2627
: Set.of(namespaces));
2728
}
2829

2930
public DefaultResourceConfiguration(String labelSelector, Class<R> resourceClass,
3031
Predicate<R> onAddFilter,
31-
BiPredicate<R, R> onUpdateFilter, Set<String> namespaces) {
32+
BiPredicate<R, R> onUpdateFilter, Predicate<R> genericFilter, Set<String> namespaces) {
3233
this.labelSelector = labelSelector;
3334
this.resourceClass = resourceClass;
3435
this.onAddFilter = onAddFilter;
3536
this.onUpdateFilter = onUpdateFilter;
37+
this.genericFilter = genericFilter;
3638
this.namespaces =
3739
namespaces == null || namespaces.isEmpty() ? DEFAULT_NAMESPACES_SET
3840
: namespaces;
@@ -67,4 +69,8 @@ public Optional<Predicate<R>> onAddFilter() {
6769
public Optional<BiPredicate<R, R>> onUpdateFilter() {
6870
return Optional.ofNullable(onUpdateFilter);
6971
}
72+
73+
public Optional<Predicate<R>> genericFilter() {
74+
return Optional.ofNullable(genericFilter);
75+
}
7076
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ default Optional<BiPredicate<R, R>> onUpdateFilter() {
2828
return Optional.empty();
2929
}
3030

31+
default Optional<Predicate<R>> genericFilter() {
32+
return Optional.empty();
33+
}
34+
3135
/**
3236
* Retrieves the label selector that is used to filter which resources are actually watched by the
3337
* associated event source. See the official documentation on the

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ protected DefaultInformerConfiguration(String labelSelector,
3232
Set<String> namespaces, boolean followControllerNamespaceChanges,
3333
Predicate<R> onAddFilter,
3434
BiPredicate<R, R> onUpdateFilter,
35-
BiPredicate<R, Boolean> onDeleteFilter) {
36-
super(labelSelector, resourceClass, onAddFilter, onUpdateFilter, namespaces);
35+
BiPredicate<R, Boolean> onDeleteFilter,
36+
Predicate<R> genericFilter) {
37+
super(labelSelector, resourceClass, onAddFilter, onUpdateFilter, genericFilter, namespaces);
3738
this.followControllerNamespaceChanges = followControllerNamespaceChanges;
3839

3940
this.secondaryToPrimaryMapper =
@@ -73,6 +74,8 @@ public Optional<BiPredicate<R, Boolean>> onDeleteFilter() {
7374

7475
Optional<BiPredicate<R, Boolean>> onDeleteFilter();
7576

77+
Optional<Predicate<R>> genericFilter();
78+
7679
@SuppressWarnings("unused")
7780
class InformerConfigurationBuilder<R extends HasMetadata> {
7881

@@ -83,6 +86,7 @@ class InformerConfigurationBuilder<R extends HasMetadata> {
8386
private Predicate<R> onAddFilter;
8487
private BiPredicate<R, R> onUpdateFilter;
8588
private BiPredicate<R, Boolean> onDeleteFilter;
89+
private Predicate<R> genericFilter;
8690
private boolean inheritControllerNamespacesOnChange = false;
8791

8892
private InformerConfigurationBuilder(Class<R> resourceClass) {
@@ -173,11 +177,16 @@ public InformerConfigurationBuilder<R> withOnDeleteFilter(
173177
return this;
174178
}
175179

180+
public InformerConfigurationBuilder<R> withGenericFilter(Predicate<R> genericFilter) {
181+
this.genericFilter = genericFilter;
182+
return this;
183+
}
184+
176185
public InformerConfiguration<R> build() {
177186
return new DefaultInformerConfiguration<>(labelSelector, resourceClass,
178187
secondaryToPrimaryMapper,
179188
namespaces, inheritControllerNamespacesOnChange, onAddFilter, onUpdateFilter,
180-
onDeleteFilter);
189+
onDeleteFilter, genericFilter);
181190
}
182191
}
183192

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.fabric8.kubernetes.api.model.HasMetadata;
1111
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
1212
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter;
13+
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidGenericFilter;
1314
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidOnAddFilter;
1415
import io.javaoperatorsdk.operator.processing.event.source.filter.VoidOnUpdateFilter;
1516

@@ -76,6 +77,11 @@
7677
/** Filter of onUpdate events of resources. */
7778
Class<? extends BiPredicate<? extends HasMetadata, ? extends HasMetadata>> onUpdateFilter() default VoidOnUpdateFilter.class;
7879

80+
/**
81+
* Filter applied to all operations (add, update, delete). Used to ignore some resources.
82+
**/
83+
Class<? extends Predicate<? extends HasMetadata>> genericFilter() default VoidGenericFilter.class;
84+
7985
/**
8086
* Optional configuration of the maximal interval the SDK will wait for a reconciliation request
8187
* to happen before one will be automatically triggered.

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public abstract class AbstractEventSourceHolderDependentResource<R, P extends Ha
2222
protected Predicate<R> onAddFilter;
2323
protected BiPredicate<R, R> onUpdateFilter;
2424
protected BiPredicate<R, Boolean> onDeleteFilter;
25+
protected Predicate<R> genericFilter;
2526

2627

2728
public EventSource initEventSource(EventSourceContext<P> context) {
@@ -50,6 +51,7 @@ protected void applyFilters() {
5051
this.eventSource.setOnAddFilter(onAddFilter);
5152
this.eventSource.setOnUpdateFilter(onUpdateFilter);
5253
this.eventSource.setOnDeleteFilter(onDeleteFilter);
54+
this.eventSource.setGenericFilter(genericFilter);
5355
}
5456

5557
protected T eventSource() {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public abstract class AbstractResourceEventSource<R, P extends HasMetadata>
1313
protected Predicate<R> onAddFilter;
1414
protected BiPredicate<R, R> onUpdateFilter;
1515
protected BiPredicate<R, Boolean> onDeleteFilter;
16+
protected Predicate<R> genericFilter;
1617

1718
protected AbstractResourceEventSource(Class<R> resourceClass) {
1819
this.resourceClass = resourceClass;
@@ -36,4 +37,8 @@ public void setOnDeleteFilter(
3637
BiPredicate<R, Boolean> onDeleteFilter) {
3738
this.onDeleteFilter = onDeleteFilter;
3839
}
40+
41+
public void setGenericFilter(Predicate<R> genericFilter) {
42+
this.genericFilter = genericFilter;
43+
}
3944
}

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ private boolean acceptedByFiler(Map<String, R> cachedResourceMap,
121121
var addedResources = new HashMap<>(newResourcesMap);
122122
addedResources.keySet().removeAll(cachedResourceMap.keySet());
123123
if (onAddFilter != null) {
124-
var anyAddAccepted = addedResources.values().stream().anyMatch(onAddFilter::test);
124+
var anyAddAccepted =
125+
addedResources.values().stream().anyMatch(r -> acceptedByGenericFiler(r) &&
126+
onAddFilter.test(r));
125127
if (anyAddAccepted) {
126128
return true;
127129
}
@@ -133,7 +135,8 @@ private boolean acceptedByFiler(Map<String, R> cachedResourceMap,
133135
deletedResource.keySet().removeAll(newResourcesMap.keySet());
134136
if (onDeleteFilter != null) {
135137
var anyDeleteAccepted =
136-
deletedResource.values().stream().anyMatch(r -> onDeleteFilter.test(r, false));
138+
deletedResource.values().stream()
139+
.anyMatch(r -> acceptedByGenericFiler(r) && onDeleteFilter.test(r, false));
137140
if (anyDeleteAccepted) {
138141
return true;
139142
}
@@ -151,7 +154,11 @@ private boolean acceptedByFiler(Map<String, R> cachedResourceMap,
151154
if (onUpdateFilter != null) {
152155
var anyUpdated = possibleUpdatedResources.entrySet().stream()
153156
.anyMatch(
154-
entry -> onUpdateFilter.test(newResourcesMap.get(entry.getKey()), entry.getValue()));
157+
entry -> {
158+
var newResource = newResourcesMap.get(entry.getKey());
159+
return acceptedByGenericFiler(newResourcesMap.get(entry.getKey())) &&
160+
onUpdateFilter.test(newResourcesMap.get(entry.getKey()), entry.getValue());
161+
});
155162
if (anyUpdated) {
156163
return true;
157164
}
@@ -162,6 +169,10 @@ private boolean acceptedByFiler(Map<String, R> cachedResourceMap,
162169
return false;
163170
}
164171

172+
private boolean acceptedByGenericFiler(R resource) {
173+
return genericFilter == null || genericFilter.test(resource);
174+
}
175+
165176
@Override
166177
public synchronized void handleRecentResourceCreate(ResourceID primaryID, R resource) {
167178
var actualValues = cache.get(primaryID);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ default Optional<R> getSecondaryResource(P primary) {
3131

3232
void setOnDeleteFilter(BiPredicate<R, Boolean> onDeleteFilter);
3333

34+
void setGenericFilter(Predicate<R> onUpdateFilter);
3435
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ && acceptFilters(action, resource, oldResource)) {
8080
}
8181

8282
private boolean acceptFilters(ResourceAction action, T resource, T oldResource) {
83-
// delete event not filtered, there is no reconciliation for delete anyways
83+
// delete event is filtered for generic filter only.
84+
if (genericFilter != null && !genericFilter.test(resource)) {
85+
return false;
86+
}
8487
switch (action) {
8588
case ADDED:
8689
return onAddFilter == null || onAddFilter.test(resource);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
public class InternalEventFilters {
99

10+
// todo unit tests
11+
1012
static <T extends HasMetadata> BiPredicate<T, T> onUpdateMarkedForDeletion() {
1113
return (newResource, oldResource) -> newResource.isMarkedForDeletion();
1214
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.javaoperatorsdk.operator.processing.event.source.filter;
2+
3+
import java.util.function.Predicate;
4+
5+
import io.fabric8.kubernetes.api.model.HasMetadata;
6+
7+
public class VoidGenericFilter implements Predicate<HasMetadata> {
8+
@Override
9+
public boolean test(HasMetadata hasMetadata) {
10+
return true;
11+
}
12+
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public InformerEventSource(InformerConfiguration<R> configuration,
9191
onAddFilter = configuration.onAddFilter().orElse(null);
9292
onUpdateFilter = configuration.onUpdateFilter().orElse(null);
9393
onDeleteFilter = configuration.onDeleteFilter().orElse(null);
94+
genericFilter = configuration.genericFilter().orElse(null);
9495
}
9596

9697
@Override
@@ -126,7 +127,7 @@ public void onDelete(R resource, boolean b) {
126127
}
127128
primaryToSecondaryIndex.onDelete(resource);
128129
super.onDelete(resource, b);
129-
if (onDeleteFilter == null || onDeleteFilter.test(resource, b)) {
130+
if (acceptedByDeleteFilters(resource, b)) {
130131
propagateEvent(resource);
131132
}
132133
}
@@ -294,6 +295,9 @@ public boolean allowsNamespaceChanges() {
294295

295296

296297
private boolean eventAcceptedByFilter(Operation operation, R newObject, R oldObject) {
298+
if (genericFilter != null && !genericFilter.test(newObject)) {
299+
return false;
300+
}
297301
if (operation == Operation.ADD) {
298302
return onAddFilter == null || onAddFilter.test(newObject);
299303
} else {
@@ -304,4 +308,9 @@ private boolean eventAcceptedByFilter(Operation operation, R newObject, R oldObj
304308
private enum Operation {
305309
ADD, UPDATE
306310
}
311+
312+
private boolean acceptedByDeleteFilters(R resource, boolean b) {
313+
return (onDeleteFilter == null || onDeleteFilter.test(resource, b)) &&
314+
(genericFilter == null || genericFilter.test(resource));
315+
}
307316
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package io.javaoperatorsdk.operator.processing.event.source.polling;
22

3-
import java.util.Map;
4-
import java.util.Set;
5-
import java.util.Timer;
6-
import java.util.TimerTask;
3+
import java.util.*;
74

85
import org.slf4j.Logger;
96
import org.slf4j.LoggerFactory;

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerManagerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private static class TestControllerConfiguration<R extends HasMetadata>
6363
public TestControllerConfiguration(Reconciler<R> controller, Class<R> crClass) {
6464
super(null, getControllerName(controller),
6565
CustomResource.getCRDName(crClass), null, false, null, null, null, null, crClass,
66-
null, null, null, null);
66+
null, null, null, null, null);
6767
this.controller = controller;
6868
}
6969

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ public static class MyConfiguration extends DefaultControllerConfiguration<TestC
136136
public MyConfiguration() {
137137
super(MyController.class.getCanonicalName(), "mycontroller", null, Constants.NO_VALUE_SET,
138138
false, null,
139-
null, null, null, TestCustomResource.class, null, null, null, null);
139+
null, null, null, TestCustomResource.class, null,
140+
null, null, null, null);
140141
}
141142
}
142143

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public ControllerConfig(String finalizer, boolean generationAware,
145145
eventFilter,
146146
customResourceClass,
147147
null,
148-
null, null, null);
148+
null, null, null, null);
149149
}
150150
}
151151

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public TestConfiguration(boolean generationAware, Predicate<TestCustomResource>
169169
null,
170170
TestCustomResource.class,
171171
null,
172-
onAddFilter, onUpdateFilter, null);
172+
onAddFilter, onUpdateFilter, null, null);
173173
}
174174
}
175175
}

0 commit comments

Comments
 (0)