Skip to content

Commit e685c4f

Browse files
committed
feat: use ConfiguredController
1 parent bf7ad38 commit e685c4f

File tree

2 files changed

+78
-78
lines changed

2 files changed

+78
-78
lines changed

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

Lines changed: 26 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,93 +4,50 @@
44
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID;
55
import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion;
66

7-
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
7+
import java.util.LinkedList;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.concurrent.ConcurrentHashMap;
11+
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
815
import io.fabric8.kubernetes.api.model.ListOptions;
916
import io.fabric8.kubernetes.client.CustomResource;
1017
import io.fabric8.kubernetes.client.Watch;
1118
import io.fabric8.kubernetes.client.Watcher;
1219
import io.fabric8.kubernetes.client.WatcherException;
13-
import io.fabric8.kubernetes.client.dsl.MixedOperation;
14-
import io.fabric8.kubernetes.client.dsl.Resource;
1520
import io.fabric8.kubernetes.client.utils.Utils;
1621
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
22+
import io.javaoperatorsdk.operator.processing.ConfiguredController;
1723
import io.javaoperatorsdk.operator.processing.CustomResourceCache;
1824
import io.javaoperatorsdk.operator.processing.KubernetesResourceUtils;
1925
import io.javaoperatorsdk.operator.processing.event.AbstractEventSource;
20-
import java.util.ArrayList;
21-
import java.util.List;
22-
import java.util.Map;
23-
import java.util.Set;
24-
import java.util.concurrent.ConcurrentHashMap;
25-
import org.slf4j.Logger;
26-
import org.slf4j.LoggerFactory;
2726

2827
/** This is a special case since is not bound to a single custom resource */
2928
public class CustomResourceEventSource<T extends CustomResource<?, ?>> extends AbstractEventSource
3029
implements Watcher<T> {
3130

3231
private static final Logger log = LoggerFactory.getLogger(CustomResourceEventSource.class);
3332

34-
private final MixedOperation<T, KubernetesResourceList<T>, Resource<T>> client;
35-
private final Set<String> targetNamespaces;
36-
private final boolean generationAware;
37-
private final String resourceFinalizer;
38-
private final String labelSelector;
33+
private final ConfiguredController<T> controller;
3934
private final Map<String, Long> lastGenerationProcessedSuccessfully = new ConcurrentHashMap<>();
4035
private final List<Watch> watches;
41-
private final String resClass;
4236
private final CustomResourceCache customResourceCache;
4337

44-
public CustomResourceEventSource(
45-
MixedOperation<T, KubernetesResourceList<T>, Resource<T>> client,
46-
ControllerConfiguration<T> configuration) {
47-
this(
48-
client,
49-
configuration.getEffectiveNamespaces(),
50-
configuration.isGenerationAware(),
51-
configuration.getFinalizer(),
52-
configuration.getLabelSelector(),
53-
configuration.getCustomResourceClass(),
54-
new CustomResourceCache(configuration.getConfigurationService().getObjectMapper()));
55-
}
56-
57-
CustomResourceEventSource(
58-
MixedOperation<T, KubernetesResourceList<T>, Resource<T>> client,
59-
Set<String> targetNamespaces,
60-
boolean generationAware,
61-
String resourceFinalizer,
62-
String labelSelector,
63-
Class<T> resClass) {
64-
this(
65-
client,
66-
targetNamespaces,
67-
generationAware,
68-
resourceFinalizer,
69-
labelSelector,
70-
resClass,
71-
new CustomResourceCache());
72-
}
73-
74-
CustomResourceEventSource(
75-
MixedOperation<T, KubernetesResourceList<T>, Resource<T>> client,
76-
Set<String> targetNamespaces,
77-
boolean generationAware,
78-
String resourceFinalizer,
79-
String labelSelector,
80-
Class<T> resClass,
81-
CustomResourceCache customResourceCache) {
82-
this.client = client;
83-
this.targetNamespaces = targetNamespaces;
84-
this.generationAware = generationAware;
85-
this.resourceFinalizer = resourceFinalizer;
86-
this.labelSelector = labelSelector;
87-
this.watches = new ArrayList<>();
88-
this.resClass = resClass.getName();
89-
this.customResourceCache = customResourceCache;
38+
public CustomResourceEventSource(ConfiguredController<T> controller) {
39+
this.controller = controller;
40+
this.watches = new LinkedList<>();
41+
this.customResourceCache = new CustomResourceCache(
42+
controller.getConfiguration().getConfigurationService().getObjectMapper());
9043
}
9144

9245
@Override
9346
public void start() {
47+
final var configuration = controller.getConfiguration();
48+
final var targetNamespaces = configuration.getEffectiveNamespaces();
49+
final var client = controller.getCRClient();
50+
final var labelSelector = configuration.getLabelSelector();
9451
var options = new ListOptions();
9552
if (Utils.isNotNullOrEmpty(labelSelector)) {
9653
options.setLabelSelector(labelSelector);
@@ -99,13 +56,13 @@ public void start() {
9956
if (ControllerConfiguration.allNamespacesWatched(targetNamespaces)) {
10057
var w = client.inAnyNamespace().watch(options, this);
10158
watches.add(w);
102-
log.debug("Registered controller {} -> {} for any namespace", resClass, w);
59+
log.debug("Registered {} -> {} for any namespace", controller, w);
10360
} else {
10461
targetNamespaces.forEach(
10562
ns -> {
10663
var w = client.inNamespace(ns).watch(options, this);
10764
watches.add(w);
108-
log.debug("Registered controller {} -> {} for namespace: {}", resClass, w, ns);
65+
log.debug("Registered {} -> {} for namespace: {}", controller, w, ns);
10966
});
11067
}
11168
}
@@ -115,10 +72,10 @@ public void close() {
11572
eventHandler.close();
11673
for (Watch watch : this.watches) {
11774
try {
118-
log.info("Closing watch {} -> {}", resClass, watch);
75+
log.info("Closing watch {} -> {}", controller, watch);
11976
watch.close();
12077
} catch (Exception e) {
121-
log.warn("Error closing watcher {} -> {}", resClass, watch, e);
78+
log.warn("Error closing watcher {} -> {}", controller, watch, e);
12279
}
12380
}
12481
}
@@ -152,14 +109,15 @@ public void eventReceived(Watcher.Action action, T customResource) {
152109
}
153110

154111
private void markLastGenerationProcessed(T resource) {
155-
if (generationAware && resource.hasFinalizer(resourceFinalizer)) {
112+
if (controller.getConfiguration().isGenerationAware()
113+
&& resource.hasFinalizer(controller.getConfiguration().getFinalizer())) {
156114
lastGenerationProcessedSuccessfully.put(
157115
KubernetesResourceUtils.getUID(resource), resource.getMetadata().getGeneration());
158116
}
159117
}
160118

161119
private boolean skipBecauseOfGeneration(T customResource) {
162-
if (!generationAware) {
120+
if (!controller.getConfiguration().isGenerationAware()) {
163121
return false;
164122
}
165123
// if CR being deleted generation is naturally not changing, so we process all the events

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,35 @@
44
import static org.mockito.Mockito.mock;
55
import static org.mockito.Mockito.times;
66
import static org.mockito.Mockito.verify;
7+
import static org.mockito.Mockito.when;
8+
9+
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
10+
import java.time.LocalDateTime;
11+
import java.util.Arrays;
12+
13+
import java.util.List;
14+
import org.junit.jupiter.api.BeforeEach;
15+
import org.junit.jupiter.api.Test;
716

817
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
918
import io.fabric8.kubernetes.client.Watcher;
1019
import io.fabric8.kubernetes.client.dsl.MixedOperation;
1120
import io.fabric8.kubernetes.client.dsl.Resource;
1221
import io.javaoperatorsdk.operator.TestUtils;
22+
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
23+
import io.javaoperatorsdk.operator.processing.ConfiguredController;
1324
import io.javaoperatorsdk.operator.processing.event.EventHandler;
1425
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
15-
import java.time.LocalDateTime;
16-
import java.util.Arrays;
17-
import org.junit.jupiter.api.BeforeEach;
18-
import org.junit.jupiter.api.Test;
1926

2027
class CustomResourceEventSourceTest {
2128

2229
public static final String FINALIZER = "finalizer";
23-
MixedOperation<TestCustomResource, KubernetesResourceList<TestCustomResource>, Resource<TestCustomResource>> client =
30+
private static final MixedOperation<TestCustomResource, KubernetesResourceList<TestCustomResource>, Resource<TestCustomResource>> client =
2431
mock(MixedOperation.class);
2532
EventHandler eventHandler = mock(EventHandler.class);
2633

2734
private CustomResourceEventSource<TestCustomResource> customResourceEventSource =
28-
new CustomResourceEventSource<>(
29-
client, null, true, FINALIZER, null, TestCustomResource.class);
35+
new CustomResourceEventSource<>(new TestConfiguredController(true));
3036

3137
@BeforeEach
3238
public void setup() {
@@ -36,7 +42,7 @@ public void setup() {
3642
@Test
3743
public void skipsEventHandlingIfGenerationNotIncreased() {
3844
TestCustomResource customResource1 = TestUtils.testCustomResource();
39-
customResource1.getMetadata().setFinalizers(Arrays.asList(FINALIZER));
45+
customResource1.getMetadata().setFinalizers(List.of(FINALIZER));
4046

4147
customResourceEventSource.eventReceived(Watcher.Action.MODIFIED, customResource1);
4248
verify(eventHandler, times(1)).handleEvent(any());
@@ -73,8 +79,7 @@ public void normalExecutionIfGenerationChanges() {
7379
@Test
7480
public void handlesAllEventIfNotGenerationAware() {
7581
customResourceEventSource =
76-
new CustomResourceEventSource<>(
77-
client, null, false, FINALIZER, null, TestCustomResource.class);
82+
new CustomResourceEventSource<>(new TestConfiguredController(false));
7883
setup();
7984

8085
TestCustomResource customResource1 = TestUtils.testCustomResource();
@@ -96,4 +101,41 @@ public void eventNotMarkedForLastGenerationIfNoFinalizer() {
96101
customResourceEventSource.eventReceived(Watcher.Action.MODIFIED, customResource1);
97102
verify(eventHandler, times(2)).handleEvent(any());
98103
}
104+
105+
private static class TestConfiguredController extends ConfiguredController<TestCustomResource> {
106+
107+
public TestConfiguredController(boolean generationAware) {
108+
super(null, new TestConfiguration(generationAware), null);
109+
}
110+
111+
@Override
112+
public MixedOperation<TestCustomResource, KubernetesResourceList<TestCustomResource>, Resource<TestCustomResource>> getCRClient() {
113+
return client;
114+
}
115+
}
116+
private static class TestConfiguration implements
117+
ControllerConfiguration<TestCustomResource> {
118+
119+
final ConfigurationService service = mock(ConfigurationService.class);
120+
final boolean generationAware;
121+
public TestConfiguration(boolean generationAware) {
122+
when(service.getObjectMapper()).thenReturn(ConfigurationService.OBJECT_MAPPER);
123+
this.generationAware = generationAware;
124+
}
125+
126+
@Override
127+
public String getAssociatedControllerClassName() {
128+
return null;
129+
}
130+
131+
@Override
132+
public ConfigurationService getConfigurationService() {
133+
return service;
134+
}
135+
136+
@Override
137+
public boolean isGenerationAware() {
138+
return generationAware;
139+
}
140+
}
99141
}

0 commit comments

Comments
 (0)