|
14 | 14 | import io.fabric8.kubernetes.api.model.HasMetadata;
|
15 | 15 | import io.fabric8.kubernetes.client.KubernetesClient;
|
16 | 16 | import io.fabric8.kubernetes.client.informers.cache.ItemStore;
|
17 |
| -import io.javaoperatorsdk.operator.OperatorException; |
18 | 17 | import io.javaoperatorsdk.operator.ReconcilerUtils;
|
19 | 18 | import io.javaoperatorsdk.operator.api.config.Utils.Configurator;
|
20 | 19 | import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
|
|
32 | 31 | import io.javaoperatorsdk.operator.processing.retry.Retry;
|
33 | 32 |
|
34 | 33 | import static io.javaoperatorsdk.operator.api.config.ControllerConfiguration.CONTROLLER_NAME_AS_FIELD_MANAGER;
|
35 |
| -import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET; |
36 | 34 |
|
37 | 35 | public class BaseConfigurationService extends AbstractConfigurationService {
|
38 | 36 |
|
@@ -94,101 +92,124 @@ public <R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
|
94 | 92 | return config;
|
95 | 93 | }
|
96 | 94 |
|
97 |
| - @SuppressWarnings({"unchecked", "rawtypes"}) |
| 95 | + @SuppressWarnings({"rawtypes"}) |
98 | 96 | protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconciler<P> reconciler) {
|
99 | 97 | final var annotation = reconciler.getClass().getAnnotation(
|
100 | 98 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class);
|
101 | 99 |
|
102 |
| - if (annotation == null) { |
103 |
| - throw new OperatorException( |
104 |
| - "Missing mandatory @" |
105 |
| - + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class |
106 |
| - .getSimpleName() |
107 |
| - + |
108 |
| - " annotation for reconciler: " + reconciler); |
| 100 | + ResolvedControllerConfiguration<P> config = controllerConfiguration(reconciler, annotation); |
| 101 | + |
| 102 | + final var workflowAnnotation = reconciler.getClass().getAnnotation( |
| 103 | + io.javaoperatorsdk.operator.api.reconciler.Workflow.class); |
| 104 | + if (workflowAnnotation != null) { |
| 105 | + final var specs = dependentResources(workflowAnnotation, config); |
| 106 | + WorkflowSpec workflowSpec = new WorkflowSpec() { |
| 107 | + @Override |
| 108 | + public List<DependentResourceSpec> getDependentResourceSpecs() { |
| 109 | + return specs; |
| 110 | + } |
| 111 | + |
| 112 | + @Override |
| 113 | + public boolean isExplicitInvocation() { |
| 114 | + return workflowAnnotation.explicitInvocation(); |
| 115 | + } |
| 116 | + |
| 117 | + @Override |
| 118 | + public boolean handleExceptionsInReconciler() { |
| 119 | + return workflowAnnotation.handleExceptionsInReconciler(); |
| 120 | + } |
| 121 | + |
| 122 | + }; |
| 123 | + config.setWorkflowSpec(workflowSpec); |
109 | 124 | }
|
| 125 | + |
| 126 | + return config; |
| 127 | + } |
| 128 | + |
| 129 | + @SuppressWarnings({"unchecked"}) |
| 130 | + private <P extends HasMetadata> ResolvedControllerConfiguration<P> controllerConfiguration( |
| 131 | + Reconciler<P> reconciler, |
| 132 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation) { |
110 | 133 | Class<Reconciler<P>> reconcilerClass = (Class<Reconciler<P>>) reconciler.getClass();
|
111 | 134 | final var resourceClass = getResourceClassResolver().getResourceClass(reconcilerClass);
|
112 | 135 |
|
113 | 136 | final var name = ReconcilerUtils.getNameFor(reconciler);
|
114 |
| - final var generationAware = valueOrDefault( |
| 137 | + final var generationAware = valueOrDefaultFromAnnotation( |
115 | 138 | annotation,
|
116 | 139 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::generationAwareEventProcessing,
|
117 |
| - true); |
| 140 | + "generationAwareEventProcessing"); |
118 | 141 | final var associatedReconcilerClass =
|
119 | 142 | ResolvedControllerConfiguration.getAssociatedReconcilerClassName(reconciler.getClass());
|
120 | 143 |
|
121 | 144 | final var context = Utils.contextFor(name);
|
122 |
| - final Class<? extends Retry> retryClass = annotation.retry(); |
| 145 | + final Class<? extends Retry> retryClass = |
| 146 | + valueOrDefaultFromAnnotation(annotation, |
| 147 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::retry, |
| 148 | + "retry"); |
123 | 149 | final var retry = Utils.instantiateAndConfigureIfNeeded(retryClass, Retry.class,
|
124 | 150 | context, configuratorFor(Retry.class, reconciler));
|
125 | 151 |
|
126 |
| - final Class<? extends RateLimiter> rateLimiterClass = annotation.rateLimiter(); |
| 152 | + |
| 153 | + final Class<? extends RateLimiter> rateLimiterClass = valueOrDefaultFromAnnotation(annotation, |
| 154 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::rateLimiter, |
| 155 | + "rateLimiter"); |
127 | 156 | final var rateLimiter = Utils.instantiateAndConfigureIfNeeded(rateLimiterClass,
|
128 | 157 | RateLimiter.class, context, configuratorFor(RateLimiter.class, reconciler));
|
129 | 158 |
|
130 |
| - final var reconciliationInterval = annotation.maxReconciliationInterval(); |
| 159 | + final var reconciliationInterval = valueOrDefaultFromAnnotation(annotation, |
| 160 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::maxReconciliationInterval, |
| 161 | + "maxReconciliationInterval"); |
131 | 162 | long interval = -1;
|
132 | 163 | TimeUnit timeUnit = null;
|
133 | 164 | if (reconciliationInterval != null && reconciliationInterval.interval() > 0) {
|
134 | 165 | interval = reconciliationInterval.interval();
|
135 | 166 | timeUnit = reconciliationInterval.timeUnit();
|
136 | 167 | }
|
137 | 168 |
|
| 169 | + var fieldManager = valueOrDefaultFromAnnotation(annotation, |
| 170 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::fieldManager, |
| 171 | + "fieldManager"); |
138 | 172 | final var dependentFieldManager =
|
139 |
| - annotation.fieldManager().equals(CONTROLLER_NAME_AS_FIELD_MANAGER) ? name |
140 |
| - : annotation.fieldManager(); |
| 173 | + fieldManager.equals(CONTROLLER_NAME_AS_FIELD_MANAGER) ? name |
| 174 | + : fieldManager; |
141 | 175 |
|
| 176 | + var informerListLimitValue = valueOrDefaultFromAnnotation(annotation, |
| 177 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::informerListLimit, |
| 178 | + "informerListLimit"); |
142 | 179 | final var informerListLimit =
|
143 |
| - annotation.informerListLimit() == Constants.NO_LONG_VALUE_SET ? null |
144 |
| - : annotation.informerListLimit(); |
| 180 | + informerListLimitValue == Constants.NO_LONG_VALUE_SET ? null |
| 181 | + : informerListLimitValue; |
145 | 182 |
|
146 |
| - final var config = new ResolvedControllerConfiguration<P>( |
| 183 | + return new ResolvedControllerConfiguration<P>( |
147 | 184 | resourceClass, name, generationAware,
|
148 | 185 | associatedReconcilerClass, retry, rateLimiter,
|
149 | 186 | ResolvedControllerConfiguration.getMaxReconciliationInterval(interval, timeUnit),
|
150 |
| - Utils.instantiate(annotation.onAddFilter(), OnAddFilter.class, context), |
151 |
| - Utils.instantiate(annotation.onUpdateFilter(), OnUpdateFilter.class, context), |
152 |
| - Utils.instantiate(annotation.genericFilter(), GenericFilter.class, context), |
153 |
| - Set.of(valueOrDefault(annotation, |
| 187 | + Utils.instantiate(valueOrDefaultFromAnnotation(annotation, |
| 188 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::onAddFilter, |
| 189 | + "onAddFilter"), OnAddFilter.class, context), |
| 190 | + Utils.instantiate(valueOrDefaultFromAnnotation(annotation, |
| 191 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::onUpdateFilter, |
| 192 | + "onUpdateFilter"), OnUpdateFilter.class, context), |
| 193 | + Utils.instantiate(valueOrDefaultFromAnnotation(annotation, |
| 194 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::genericFilter, |
| 195 | + "genericFilter"), GenericFilter.class, context), |
| 196 | + Set.of(valueOrDefaultFromAnnotation(annotation, |
154 | 197 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::namespaces,
|
155 |
| - DEFAULT_NAMESPACES_SET.toArray(String[]::new))), |
156 |
| - valueOrDefault(annotation, |
| 198 | + "namespaces")), |
| 199 | + valueOrDefaultFromAnnotation(annotation, |
157 | 200 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::finalizerName,
|
158 |
| - Constants.NO_VALUE_SET), |
159 |
| - valueOrDefault(annotation, |
| 201 | + "finalizerName"), |
| 202 | + valueOrDefaultFromAnnotation(annotation, |
160 | 203 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::labelSelector,
|
161 |
| - Constants.NO_VALUE_SET), |
| 204 | + "labelSelector"), |
162 | 205 | null,
|
163 |
| - Utils.instantiate(annotation.itemStore(), ItemStore.class, context), dependentFieldManager, |
| 206 | + Utils.instantiate( |
| 207 | + valueOrDefaultFromAnnotation(annotation, |
| 208 | + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::itemStore, |
| 209 | + "itemStore"), |
| 210 | + ItemStore.class, context), |
| 211 | + dependentFieldManager, |
164 | 212 | this, informerListLimit);
|
165 |
| - |
166 |
| - |
167 |
| - final var workflowAnnotation = reconciler.getClass().getAnnotation( |
168 |
| - io.javaoperatorsdk.operator.api.reconciler.Workflow.class); |
169 |
| - if (workflowAnnotation != null) { |
170 |
| - final var specs = dependentResources(workflowAnnotation, config); |
171 |
| - WorkflowSpec workflowSpec = new WorkflowSpec() { |
172 |
| - @Override |
173 |
| - public List<DependentResourceSpec> getDependentResourceSpecs() { |
174 |
| - return specs; |
175 |
| - } |
176 |
| - |
177 |
| - @Override |
178 |
| - public boolean isExplicitInvocation() { |
179 |
| - return workflowAnnotation.explicitInvocation(); |
180 |
| - } |
181 |
| - |
182 |
| - @Override |
183 |
| - public boolean handleExceptionsInReconciler() { |
184 |
| - return workflowAnnotation.handleExceptionsInReconciler(); |
185 |
| - } |
186 |
| - |
187 |
| - }; |
188 |
| - config.setWorkflowSpec(workflowSpec); |
189 |
| - } |
190 |
| - |
191 |
| - return config; |
192 | 213 | }
|
193 | 214 |
|
194 | 215 | @SuppressWarnings({"unchecked", "rawtypes"})
|
@@ -239,14 +260,20 @@ public boolean checkCRDAndValidateLocalModel() {
|
239 | 260 | return Utils.shouldCheckCRDAndValidateLocalModel();
|
240 | 261 | }
|
241 | 262 |
|
242 |
| - private static <T> T valueOrDefault( |
| 263 | + @SuppressWarnings("unchecked") |
| 264 | + private static <T> T valueOrDefaultFromAnnotation( |
243 | 265 | io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration controllerConfiguration,
|
244 | 266 | Function<io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration, T> mapper,
|
245 |
| - T defaultValue) { |
246 |
| - if (controllerConfiguration == null) { |
247 |
| - return defaultValue; |
248 |
| - } else { |
249 |
| - return mapper.apply(controllerConfiguration); |
| 267 | + String defaultMethodName) { |
| 268 | + try { |
| 269 | + if (controllerConfiguration == null) { |
| 270 | + return (T) io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class |
| 271 | + .getDeclaredMethod(defaultMethodName).getDefaultValue(); |
| 272 | + } else { |
| 273 | + return mapper.apply(controllerConfiguration); |
| 274 | + } |
| 275 | + } catch (NoSuchMethodException e) { |
| 276 | + throw new RuntimeException(e); |
250 | 277 | }
|
251 | 278 | }
|
252 | 279 |
|
|
0 commit comments