Skip to content

Commit f85103a

Browse files
committed
refactor: move getResourceClassResolver to BaseConfigurationService (#2451)
The class resolving mechanism is only needed in that class right now Signed-off-by: Chris Laprun <[email protected]>
1 parent 8526fa9 commit f85103a

File tree

5 files changed

+98
-104
lines changed

5 files changed

+98
-104
lines changed

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java

+94-84
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class BaseConfigurationService extends AbstractConfigurationService {
3939

4040
private static final String LOGGER_NAME = "Default ConfigurationService implementation";
4141
private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
42+
private static final ResourceClassResolver DEFAULT_RESOLVER = new DefaultResourceClassResolver();
4243

4344
public BaseConfigurationService(Version version) {
4445
this(version, null);
@@ -56,6 +57,89 @@ public BaseConfigurationService() {
5657
this(Utils.VERSION);
5758
}
5859

60+
@SuppressWarnings({"unchecked", "rawtypes"})
61+
private static List<DependentResourceSpec> dependentResources(
62+
Workflow annotation,
63+
ControllerConfiguration<?> controllerConfiguration) {
64+
final var dependents = annotation.dependents();
65+
66+
67+
if (dependents == null || dependents.length == 0) {
68+
return Collections.emptyList();
69+
}
70+
71+
final var specsMap = new LinkedHashMap<String, DependentResourceSpec>(dependents.length);
72+
for (Dependent dependent : dependents) {
73+
final Class<? extends DependentResource> dependentType = dependent.type();
74+
75+
final var dependentName = getName(dependent.name(), dependentType);
76+
var spec = specsMap.get(dependentName);
77+
if (spec != null) {
78+
throw new IllegalArgumentException(
79+
"A DependentResource named '" + dependentName + "' already exists: " + spec);
80+
}
81+
82+
final var name = controllerConfiguration.getName();
83+
84+
var eventSourceName = dependent.useEventSourceWithName();
85+
eventSourceName = Constants.NO_VALUE_SET.equals(eventSourceName) ? null : eventSourceName;
86+
final var context = Utils.contextFor(name, dependentType, null);
87+
spec = new DependentResourceSpec(dependentType, dependentName,
88+
Set.of(dependent.dependsOn()),
89+
Utils.instantiate(dependent.readyPostcondition(), Condition.class, context),
90+
Utils.instantiate(dependent.reconcilePrecondition(), Condition.class, context),
91+
Utils.instantiate(dependent.deletePostcondition(), Condition.class, context),
92+
Utils.instantiate(dependent.activationCondition(), Condition.class, context),
93+
eventSourceName);
94+
95+
// extract potential configuration
96+
DependentResourceConfigurationResolver.configureSpecFromConfigured(spec,
97+
controllerConfiguration,
98+
dependentType);
99+
100+
specsMap.put(dependentName, spec);
101+
}
102+
return specsMap.values().stream().toList();
103+
}
104+
105+
private static <T> T valueOrDefault(
106+
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration controllerConfiguration,
107+
Function<io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration, T> mapper,
108+
T defaultValue) {
109+
if (controllerConfiguration == null) {
110+
return defaultValue;
111+
} else {
112+
return mapper.apply(controllerConfiguration);
113+
}
114+
}
115+
116+
@SuppressWarnings("rawtypes")
117+
private static String getName(String name, Class<? extends DependentResource> dependentType) {
118+
if (name.isBlank()) {
119+
name = DependentResource.defaultNameFor(dependentType);
120+
}
121+
return name;
122+
}
123+
124+
@SuppressWarnings("unused")
125+
private static <T> Configurator<T> configuratorFor(Class<T> instanceType,
126+
Reconciler<?> reconciler) {
127+
return instance -> configureFromAnnotatedReconciler(instance, reconciler);
128+
}
129+
130+
@SuppressWarnings({"unchecked", "rawtypes"})
131+
private static void configureFromAnnotatedReconciler(Object instance, Reconciler<?> reconciler) {
132+
if (instance instanceof AnnotationConfigurable configurable) {
133+
final Class<? extends Annotation> configurationClass =
134+
(Class<? extends Annotation>) Utils.getFirstTypeArgumentFromSuperClassOrInterface(
135+
instance.getClass(), AnnotationConfigurable.class);
136+
final var configAnnotation = reconciler.getClass().getAnnotation(configurationClass);
137+
if (configAnnotation != null) {
138+
configurable.initFrom(configAnnotation);
139+
}
140+
}
141+
}
142+
59143
@Override
60144
protected void logMissingReconcilerWarning(String reconcilerKey, String reconcilersNameMessage) {
61145
logger.warn("Configuration for reconciler '{}' was not found. {}", reconcilerKey,
@@ -95,6 +179,15 @@ public <R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
95179
return config;
96180
}
97181

182+
/**
183+
* Override if a different class resolution is needed
184+
*
185+
* @return the custom {@link ResourceClassResolver} implementation to use
186+
*/
187+
protected ResourceClassResolver getResourceClassResolver() {
188+
return DEFAULT_RESOLVER;
189+
}
190+
98191
@SuppressWarnings({"unchecked", "rawtypes"})
99192
protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconciler<P> reconciler) {
100193
final var annotation = reconciler.getClass().getAnnotation(
@@ -109,7 +202,7 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile
109202
" annotation for reconciler: " + reconciler);
110203
}
111204
Class<Reconciler<P>> reconcilerClass = (Class<Reconciler<P>>) reconciler.getClass();
112-
final var resourceClass = getResourceClassResolver().getResourceClass(reconcilerClass);
205+
final var resourceClass = getResourceClassResolver().getPrimaryResourceClass(reconcilerClass);
113206

114207
final var name = ReconcilerUtils.getNameFor(reconciler);
115208
final var generationAware = valueOrDefault(
@@ -192,51 +285,6 @@ public boolean handleExceptionsInReconciler() {
192285
return config;
193286
}
194287

195-
@SuppressWarnings({"unchecked", "rawtypes"})
196-
private static List<DependentResourceSpec> dependentResources(
197-
Workflow annotation,
198-
ControllerConfiguration<?> controllerConfiguration) {
199-
final var dependents = annotation.dependents();
200-
201-
202-
if (dependents == null || dependents.length == 0) {
203-
return Collections.emptyList();
204-
}
205-
206-
final var specsMap = new LinkedHashMap<String, DependentResourceSpec>(dependents.length);
207-
for (Dependent dependent : dependents) {
208-
final Class<? extends DependentResource> dependentType = dependent.type();
209-
210-
final var dependentName = getName(dependent.name(), dependentType);
211-
var spec = specsMap.get(dependentName);
212-
if (spec != null) {
213-
throw new IllegalArgumentException(
214-
"A DependentResource named '" + dependentName + "' already exists: " + spec);
215-
}
216-
217-
final var name = controllerConfiguration.getName();
218-
219-
var eventSourceName = dependent.useEventSourceWithName();
220-
eventSourceName = Constants.NO_VALUE_SET.equals(eventSourceName) ? null : eventSourceName;
221-
final var context = Utils.contextFor(name, dependentType, null);
222-
spec = new DependentResourceSpec(dependentType, dependentName,
223-
Set.of(dependent.dependsOn()),
224-
Utils.instantiate(dependent.readyPostcondition(), Condition.class, context),
225-
Utils.instantiate(dependent.reconcilePrecondition(), Condition.class, context),
226-
Utils.instantiate(dependent.deletePostcondition(), Condition.class, context),
227-
Utils.instantiate(dependent.activationCondition(), Condition.class, context),
228-
eventSourceName);
229-
230-
// extract potential configuration
231-
DependentResourceConfigurationResolver.configureSpecFromConfigured(spec,
232-
controllerConfiguration,
233-
dependentType);
234-
235-
specsMap.put(dependentName, spec);
236-
}
237-
return specsMap.values().stream().toList();
238-
}
239-
240288
protected boolean createIfNeeded() {
241289
return true;
242290
}
@@ -245,42 +293,4 @@ protected boolean createIfNeeded() {
245293
public boolean checkCRDAndValidateLocalModel() {
246294
return Utils.shouldCheckCRDAndValidateLocalModel();
247295
}
248-
249-
private static <T> T valueOrDefault(
250-
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration controllerConfiguration,
251-
Function<io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration, T> mapper,
252-
T defaultValue) {
253-
if (controllerConfiguration == null) {
254-
return defaultValue;
255-
} else {
256-
return mapper.apply(controllerConfiguration);
257-
}
258-
}
259-
260-
@SuppressWarnings("rawtypes")
261-
private static String getName(String name, Class<? extends DependentResource> dependentType) {
262-
if (name.isBlank()) {
263-
name = DependentResource.defaultNameFor(dependentType);
264-
}
265-
return name;
266-
}
267-
268-
@SuppressWarnings("unused")
269-
private static <T> Configurator<T> configuratorFor(Class<T> instanceType,
270-
Reconciler<?> reconciler) {
271-
return instance -> configureFromAnnotatedReconciler(instance, reconciler);
272-
}
273-
274-
@SuppressWarnings({"unchecked", "rawtypes"})
275-
private static void configureFromAnnotatedReconciler(Object instance, Reconciler<?> reconciler) {
276-
if (instance instanceof AnnotationConfigurable configurable) {
277-
final Class<? extends Annotation> configurationClass =
278-
(Class<? extends Annotation>) Utils.getFirstTypeArgumentFromSuperClassOrInterface(
279-
instance.getClass(), AnnotationConfigurable.class);
280-
final var configAnnotation = reconciler.getClass().getAnnotation(configurationClass);
281-
if (configAnnotation != null) {
282-
configurable.initFrom(configAnnotation);
283-
}
284-
}
285-
}
286296
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java

-4
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,6 @@ default ManagedWorkflowFactory getWorkflowFactory() {
236236
return ManagedWorkflowFactory.DEFAULT;
237237
}
238238

239-
default ResourceClassResolver getResourceClassResolver() {
240-
return new DefaultResourceClassResolver();
241-
}
242-
243239
/**
244240
* Creates a new {@link ConfigurationService} instance used to configure an
245241
* {@link io.javaoperatorsdk.operator.Operator} instance, starting from the specified base

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java

+1-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
1616
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResourceFactory;
1717

18-
@SuppressWarnings("unused")
18+
@SuppressWarnings({"unused", "UnusedReturnValue"})
1919
public class ConfigurationServiceOverrider {
2020

2121
private static final Logger log = LoggerFactory.getLogger(ConfigurationServiceOverrider.class);
@@ -33,7 +33,6 @@ public class ConfigurationServiceOverrider {
3333
private InformerStoppedHandler informerStoppedHandler;
3434
private Boolean stopOnInformerErrorDuringStartup;
3535
private Duration cacheSyncTimeout;
36-
private ResourceClassResolver resourceClassResolver;
3736
private Boolean ssaBasedCreateUpdateMatchForDependentResources;
3837
private Set<Class<? extends HasMetadata>> defaultNonSSAResource;
3938
private Boolean previousAnnotationForDependentResources;
@@ -133,12 +132,6 @@ public ConfigurationServiceOverrider withCacheSyncTimeout(Duration cacheSyncTime
133132
return this;
134133
}
135134

136-
public ConfigurationServiceOverrider withResourceClassResolver(
137-
ResourceClassResolver resourceClassResolver) {
138-
this.resourceClassResolver = resourceClassResolver;
139-
return this;
140-
}
141-
142135
public ConfigurationServiceOverrider withSSABasedCreateUpdateMatchForDependentResources(
143136
boolean value) {
144137
this.ssaBasedCreateUpdateMatchForDependentResources = value;
@@ -280,12 +273,6 @@ public Duration cacheSyncTimeout() {
280273
return overriddenValueOrDefault(cacheSyncTimeout, ConfigurationService::cacheSyncTimeout);
281274
}
282275

283-
@Override
284-
public ResourceClassResolver getResourceClassResolver() {
285-
return overriddenValueOrDefault(resourceClassResolver,
286-
ConfigurationService::getResourceClassResolver);
287-
}
288-
289276
@Override
290277
public boolean ssaBasedCreateUpdateMatchForDependentResources() {
291278
return overriddenValueOrDefault(ssaBasedCreateUpdateMatchForDependentResources,

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class DefaultResourceClassResolver implements ResourceClassResolver {
77

88
@SuppressWarnings("unchecked")
99
@Override
10-
public <R extends HasMetadata> Class<R> getResourceClass(
10+
public <R extends HasMetadata> Class<R> getPrimaryResourceClass(
1111
Class<? extends Reconciler<R>> reconcilerClass) {
1212
return (Class<R>) Utils.getFirstTypeArgumentFromSuperClassOrInterface(reconcilerClass,
1313
Reconciler.class);

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java

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

66
public interface ResourceClassResolver {
77

8-
<R extends HasMetadata> Class<R> getResourceClass(Class<? extends Reconciler<R>> reconcilerClass);
8+
<P extends HasMetadata> Class<P> getPrimaryResourceClass(
9+
Class<? extends Reconciler<P>> reconcilerClass);
910

1011
}

0 commit comments

Comments
 (0)