Skip to content

Commit 8c4fd8d

Browse files
committed
feat: record resource class in InformerConfiguration
Signed-off-by: Chris Laprun <[email protected]>
1 parent 0bfff0a commit 8c4fd8d

File tree

9 files changed

+58
-33
lines changed

9 files changed

+58
-33
lines changed

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,18 @@
22

33

44
import io.fabric8.kubernetes.api.model.HasMetadata;
5-
import io.javaoperatorsdk.operator.ReconcilerUtils;
65
import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
76

87
public interface ResourceConfiguration<R extends HasMetadata> {
98

109
default String getResourceTypeName() {
11-
return ReconcilerUtils.getResourceTypeName(getResourceClass());
10+
return getInformerConfig().getResourceTypeName();
1211
}
1312

1413
InformerConfiguration<R> getInformerConfig();
1514

1615
@SuppressWarnings("unchecked")
1716
default Class<R> getResourceClass() {
18-
return (Class<R>) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(),
19-
ResourceConfiguration.class);
17+
return getInformerConfig().getResourceClass();
2018
}
2119
}

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

+23-8
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
import java.util.Set;
66
import java.util.stream.Collectors;
77

8+
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
89
import io.fabric8.kubernetes.api.model.HasMetadata;
910
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
1011
import io.javaoperatorsdk.operator.OperatorException;
12+
import io.javaoperatorsdk.operator.ReconcilerUtils;
1113
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
1214
import io.javaoperatorsdk.operator.api.config.Utils;
1315
import io.javaoperatorsdk.operator.api.reconciler.Constants;
@@ -23,6 +25,8 @@
2325
@SuppressWarnings("unused")
2426
public class InformerConfiguration<R extends HasMetadata> {
2527
private final Builder builder = new Builder();
28+
private final Class<R> resourceClass;
29+
private final String resourceTypeName;
2630
private String name;
2731
private Set<String> namespaces;
2832
private Boolean followControllerNamespacesOnChange;
@@ -34,11 +38,12 @@ public class InformerConfiguration<R extends HasMetadata> {
3438
private ItemStore<R> itemStore;
3539
private Long informerListLimit;
3640

37-
public InformerConfiguration(String name, Set<String> namespaces,
41+
protected InformerConfiguration(Class<R> resourceClass, String name, Set<String> namespaces,
3842
boolean followControllerNamespacesOnChange,
3943
String labelSelector, OnAddFilter<? super R> onAddFilter,
4044
OnUpdateFilter<? super R> onUpdateFilter, OnDeleteFilter<? super R> onDeleteFilter,
4145
GenericFilter<? super R> genericFilter, ItemStore<R> itemStore, Long informerListLimit) {
46+
this(resourceClass);
4247
this.name = name;
4348
this.namespaces = namespaces;
4449
this.followControllerNamespacesOnChange = followControllerNamespacesOnChange;
@@ -51,23 +56,25 @@ public InformerConfiguration(String name, Set<String> namespaces,
5156
this.informerListLimit = informerListLimit;
5257
}
5358

54-
private InformerConfiguration() {}
55-
56-
@SuppressWarnings({"rawtypes", "unchecked"})
57-
public static <R extends HasMetadata> InformerConfiguration<R>.Builder builder() {
58-
return new InformerConfiguration().builder;
59+
private InformerConfiguration(Class<R> resourceClass) {
60+
this.resourceClass = resourceClass;
61+
this.resourceTypeName = resourceClass.isAssignableFrom(GenericKubernetesResource.class)
62+
// in general this is irrelevant now for secondary resources it is used just by controller
63+
// where GenericKubernetesResource now does not apply
64+
? GenericKubernetesResource.class.getSimpleName()
65+
: ReconcilerUtils.getResourceTypeName(resourceClass);
5966
}
6067

6168
@SuppressWarnings({"rawtypes", "unchecked"})
6269
public static <R extends HasMetadata> InformerConfiguration<R>.Builder builder(
6370
Class<R> resourceClass) {
64-
return new InformerConfiguration().builder;
71+
return new InformerConfiguration(resourceClass).builder;
6572
}
6673

6774
@SuppressWarnings({"rawtypes", "unchecked"})
6875
public static <R extends HasMetadata> InformerConfiguration<R>.Builder builder(
6976
InformerConfiguration<R> original) {
70-
return new InformerConfiguration(original.name, original.namespaces,
77+
return new InformerConfiguration(original.resourceClass, original.name, original.namespaces,
7178
original.followControllerNamespacesOnChange, original.labelSelector, original.onAddFilter,
7279
original.onUpdateFilter, original.onDeleteFilter, original.genericFilter,
7380
original.itemStore, original.informerListLimit).builder;
@@ -115,6 +122,14 @@ public static boolean inheritsNamespacesFromController(Set<String> namespaces) {
115122
return SAME_AS_CONTROLLER_NAMESPACES_SET.equals(namespaces);
116123
}
117124

125+
public Class<R> getResourceClass() {
126+
return resourceClass;
127+
}
128+
129+
public String getResourceTypeName() {
130+
return resourceTypeName;
131+
}
132+
118133
public String getName() {
119134
return name;
120135
}

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

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,32 @@
66
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ConfiguredDependentResource;
77

88
@SuppressWarnings({"rawtypes", "unchecked"})
9-
public interface DependentResourceFactory<C extends ControllerConfiguration<?>> {
9+
public interface DependentResourceFactory<C extends ControllerConfiguration<?>, D extends DependentResourceSpec> {
1010

1111
DependentResourceFactory DEFAULT = new DependentResourceFactory() {};
1212

13-
default DependentResource createFrom(DependentResourceSpec spec, C controllerConfiguration) {
13+
default DependentResource createFrom(D spec, C controllerConfiguration) {
1414
final var dependentResourceClass = spec.getDependentResourceClass();
1515
return Utils.instantiateAndConfigureIfNeeded(dependentResourceClass,
1616
DependentResource.class,
1717
Utils.contextFor(controllerConfiguration, dependentResourceClass, Dependent.class),
1818
(instance) -> configure(instance, spec, controllerConfiguration));
1919
}
2020

21-
default void configure(DependentResource instance, DependentResourceSpec spec,
22-
C controllerConfiguration) {
21+
default void configure(DependentResource instance, D spec, C controllerConfiguration) {
2322
if (instance instanceof ConfiguredDependentResource configurable) {
2423
final var config = controllerConfiguration.getConfigurationFor(spec);
2524
if (config != null) {
2625
configurable.configureWith(config);
2726
}
2827
}
2928
}
29+
30+
default Class<?> associatedResourceType(D spec) {
31+
final var dependentResourceClass = spec.getDependentResourceClass();
32+
final var dr = Utils.instantiateAndConfigureIfNeeded(dependentResourceClass,
33+
DependentResource.class,
34+
null, null);
35+
return dr != null ? dr.resourceType() : null;
36+
}
3037
}

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ private InformerConfiguration<R> createInformerConfig(
4343
Class<? extends KubernetesDependentResource<?, ?>> dependentResourceClass =
4444
(Class<? extends KubernetesDependentResource<?, ?>>) spec.getDependentResourceClass();
4545

46-
InformerConfiguration<R>.Builder config = InformerConfiguration.builder();
46+
final var resourceType = controllerConfig.getConfigurationService().dependentResourceFactory()
47+
.associatedResourceType(spec);
48+
49+
InformerConfiguration<R>.Builder config = InformerConfiguration.builder(resourceType);
4750
if (configAnnotation != null) {
4851
final var informerConfig = configAnnotation.informer();
4952
final var context = Utils.contextFor(controllerConfig, dependentResourceClass,

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,16 @@ public void broadcastOnResourceEvent(ResourceAction action, P resource, P oldRes
173173
}
174174

175175
public void changeNamespaces(Set<String> namespaces) {
176-
eventSources.controllerEventSource()
177-
.changeNamespaces(namespaces);
178-
executorServiceManager.boundedExecuteAndWaitForAllToComplete(eventSources
176+
eventSources.controllerEventSource().changeNamespaces(namespaces);
177+
final var namespaceChangeables = eventSources
179178
.additionalEventSources()
180179
.filter(NamespaceChangeable.class::isInstance)
181180
.map(NamespaceChangeable.class::cast)
182-
.filter(NamespaceChangeable::allowsNamespaceChanges), e -> {
183-
e.changeNamespaces(namespaces);
184-
return null;
185-
},
181+
.filter(NamespaceChangeable::allowsNamespaceChanges);
182+
executorServiceManager.boundedExecuteAndWaitForAllToComplete(namespaceChangeables, e -> {
183+
e.changeNamespaces(namespaces);
184+
return null;
185+
},
186186
getEventSourceThreadNamer("changeNamespace"));
187187
}
188188

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/InformerConfigurationTest.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import org.junit.jupiter.api.Test;
77

8+
import io.fabric8.kubernetes.api.model.ConfigMap;
89
import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
910
import io.javaoperatorsdk.operator.api.reconciler.Constants;
1011

@@ -46,19 +47,21 @@ void currentNamespaceWatched() {
4647

4748
@Test
4849
void nullLabelSelectorByDefault() {
49-
final var informerConfig = InformerConfiguration.builder().buildForInformerEventSource();
50+
final var informerConfig =
51+
InformerConfiguration.builder(ConfigMap.class).buildForInformerEventSource();
5052
assertNull(informerConfig.getLabelSelector());
5153
}
5254

5355
@Test
5456
void shouldWatchAllNamespacesByDefaultForControllers() {
55-
final var informerConfig = InformerConfiguration.builder().buildForController();
57+
final var informerConfig = InformerConfiguration.builder(ConfigMap.class).buildForController();
5658
assertTrue(informerConfig.watchAllNamespaces());
5759
}
5860

5961
@Test
6062
void shouldFollowControllerNamespacesByDefaultForInformerEventSource() {
61-
final var informerConfig = InformerConfiguration.builder().buildForInformerEventSource();
63+
final var informerConfig =
64+
InformerConfiguration.builder(ConfigMap.class).buildForInformerEventSource();
6265
assertTrue(informerConfig.isFollowControllerNamespacesOnChange());
6366
}
6467

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,13 @@ void changesNamespacesOnControllerAndInformerEventSources() {
168168
when(controllerResourceEventSourceMock.allowsNamespaceChanges()).thenCallRealMethod();
169169
var manager = new EventSourceManager(controller, eventSources);
170170

171-
InformerEventSourceConfiguration informerConfigurationMock =
171+
InformerEventSourceConfiguration eventSourceConfigurationMock =
172172
mock(InformerEventSourceConfiguration.class);
173-
when(informerConfigurationMock.followControllerNamespaceChanges()).thenReturn(true);
174173
InformerEventSource informerEventSource = mock(InformerEventSource.class);
175174
when(informerEventSource.name()).thenReturn("ies");
176175
when(informerEventSource.resourceType()).thenReturn(TestCustomResource.class);
177-
when(informerEventSource.configuration()).thenReturn(informerConfigurationMock);
178-
when(informerEventSource.allowsNamespaceChanges()).thenCallRealMethod();
176+
when(informerEventSource.configuration()).thenReturn(eventSourceConfigurationMock);
177+
when(informerEventSource.allowsNamespaceChanges()).thenReturn(true);
179178
manager.registerEventSource(informerEventSource);
180179

181180
manager.changeNamespaces(Set.of(newNamespaces));

sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private void initDependentResources(KubernetesClient client) {
8585

8686
Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR)
8787
.forEach(dr -> dr.configureWith(new KubernetesDependentResourceConfigBuilder()
88-
.withKubernetesDependentInformerConfig(InformerConfiguration.builder()
88+
.withKubernetesDependentInformerConfig(InformerConfiguration.builder(dr.resourceType())
8989
.withLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR)
9090
.buildForInformerEventSource())
9191
.build()));

sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ private Workflow<WebPage> createDependentResourcesAndWorkflow() {
9696
// configure them with our label selector
9797
Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR)
9898
.forEach(dr -> dr.configureWith(new KubernetesDependentResourceConfigBuilder()
99-
.withKubernetesDependentInformerConfig(InformerConfiguration.builder()
99+
.withKubernetesDependentInformerConfig(InformerConfiguration.builder(dr.resourceType())
100100
.withLabelSelector(SELECTOR + "=true")
101101
.buildForInformerEventSource())
102102
.build()));

0 commit comments

Comments
 (0)