6
6
import io .javaoperatorsdk .operator .api .ResourceController ;
7
7
import io .javaoperatorsdk .operator .api .config .ConfigurationService ;
8
8
import io .javaoperatorsdk .operator .api .config .ControllerConfiguration ;
9
+ import io .javaoperatorsdk .operator .api .config .RetryConfiguration ;
9
10
import io .javaoperatorsdk .quarkus .extension .ConfigurationServiceRecorder ;
11
+ import io .javaoperatorsdk .quarkus .extension .ExternalConfiguration ;
12
+ import io .javaoperatorsdk .quarkus .extension .ExternalControllerConfiguration ;
10
13
import io .javaoperatorsdk .quarkus .extension .OperatorProducer ;
11
14
import io .javaoperatorsdk .quarkus .extension .QuarkusConfigurationService ;
12
15
import io .javaoperatorsdk .quarkus .extension .QuarkusControllerConfiguration ;
@@ -49,6 +52,8 @@ class QuarkusExtensionProcessor {
49
52
throw new IllegalArgumentException ();
50
53
};
51
54
55
+ private ExternalConfiguration externalConfiguration ;
56
+
52
57
@ BuildStep
53
58
void indexSDKDependencies (
54
59
BuildProducer <IndexDependencyBuildItem > indexDependency ,
@@ -110,16 +115,6 @@ private ControllerConfiguration createControllerConfiguration(
110
115
.setDefaultScope (APPLICATION_SCOPED )
111
116
.build ());
112
117
113
- // generate configuration
114
- final var controllerAnnotation = info .classAnnotation (CONTROLLER );
115
- if (controllerAnnotation == null ) {
116
- throw new IllegalArgumentException (
117
- resourceControllerClassName
118
- + " is missing the @"
119
- + Controller .class .getCanonicalName ()
120
- + " annotation" );
121
- }
122
-
123
118
// load CR class
124
119
final Class <CustomResource > crClass = (Class <CustomResource >) loadClass (crType );
125
120
@@ -137,38 +132,45 @@ private ControllerConfiguration createControllerConfiguration(
137
132
// register CR class for introspection
138
133
reflectionClasses .produce (new ReflectiveClassBuildItem (true , true , crClass ));
139
134
135
+ // retrieve the Controller annotation if it exists
136
+ final var controllerAnnotation = info .classAnnotation (CONTROLLER );
137
+
138
+ // retrieve the controller's name
139
+ final var defaultControllerName =
140
+ ControllerUtils .getDefaultResourceControllerName (resourceControllerClassName );
140
141
final var name =
141
- valueOrDefault (
142
- controllerAnnotation ,
143
- "name" ,
144
- AnnotationValue ::asString ,
145
- () -> ControllerUtils .getDefaultResourceControllerName (resourceControllerClassName ));
142
+ annotationValueOrDefault (
143
+ controllerAnnotation , "name" , AnnotationValue ::asString , () -> defaultControllerName );
144
+
145
+ // check if we have externalized configuration to provide values
146
+ final var extContConfig = externalConfiguration .controllers .get (name );
147
+
148
+ final var extractor = new ValueExtractor (controllerAnnotation , extContConfig );
146
149
147
150
// create the configuration
148
151
final var configuration =
149
152
new QuarkusControllerConfiguration (
150
153
resourceControllerClassName ,
151
154
name ,
152
155
crdName ,
153
- valueOrDefault (
154
- controllerAnnotation ,
156
+ extractor . extract (
157
+ c -> c . finalizer ,
155
158
"finalizerName" ,
156
159
AnnotationValue ::asString ,
157
160
() -> ControllerUtils .getDefaultFinalizerName (crdName )),
158
- valueOrDefault (
159
- controllerAnnotation ,
161
+ extractor . extract (
162
+ c -> c . generationAware ,
160
163
"generationAwareEventProcessing" ,
161
164
AnnotationValue ::asBoolean ,
162
165
() -> true ),
163
166
QuarkusControllerConfiguration .asSet (
164
- valueOrDefault (
165
- controllerAnnotation ,
167
+ extractor . extract (
168
+ c -> c . namespaces . map ( l -> l . toArray ( new String [ 0 ])) ,
166
169
"namespaces" ,
167
170
AnnotationValue ::asStringArray ,
168
171
() -> new String [] {})),
169
172
crType ,
170
- null // todo: fix-me
171
- );
173
+ retryConfiguration (extContConfig ));
172
174
173
175
log .infov (
174
176
"Processed ''{0}'' controller named ''{1}'' for ''{2}'' CR (version ''{3}'')" ,
@@ -177,12 +179,72 @@ private ControllerConfiguration createControllerConfiguration(
177
179
return configuration ;
178
180
}
179
181
180
- private <T > T valueOrDefault (
182
+ private RetryConfiguration retryConfiguration (ExternalControllerConfiguration extConfig ) {
183
+ return extConfig == null ? null : RetryConfigurationResolver .resolve (extConfig .retry );
184
+ }
185
+
186
+ private static class ValueExtractor {
187
+
188
+ private final AnnotationInstance controllerAnnotation ;
189
+ private final ExternalControllerConfiguration extContConfig ;
190
+
191
+ ValueExtractor (
192
+ AnnotationInstance controllerAnnotation , ExternalControllerConfiguration extContConfig ) {
193
+ this .controllerAnnotation = controllerAnnotation ;
194
+ this .extContConfig = extContConfig ;
195
+ }
196
+
197
+ /**
198
+ * Extracts the appropriate configuration value for the controller checking first any annotation
199
+ * configuration, then potentially overriding it by a properties-provided value or returning a
200
+ * default value if neither is provided.
201
+ *
202
+ * @param extractor a Function extracting the optional value we're interested in from the
203
+ * external configuration
204
+ * @param annotationField the name of the {@link Controller} annotation we're want to retrieve
205
+ * if present
206
+ * @param converter a Function converting the annotation value to the type we're expecting
207
+ * @param defaultValue a Supplier that computes/retrieve a default value when needed
208
+ * @param <T> the expected type of the configuration value we're trying to extract
209
+ * @return the extracted configuration value
210
+ */
211
+ <T > T extract (
212
+ Function <ExternalControllerConfiguration , Optional <T >> extractor ,
213
+ String annotationField ,
214
+ Function <AnnotationValue , T > converter ,
215
+ Supplier <T > defaultValue ) {
216
+ // first check if we have an external configuration
217
+ if (extContConfig != null ) {
218
+ // extract value from config if present
219
+ return extractor
220
+ .apply (extContConfig )
221
+ // or get from the annotation or default
222
+ .orElse (annotationValueOrDefault (annotationField , converter , defaultValue ));
223
+ } else {
224
+ // get from annotation or default
225
+ return annotationValueOrDefault (annotationField , converter , defaultValue );
226
+ }
227
+ }
228
+
229
+ private <T > T annotationValueOrDefault (
230
+ String name , Function <AnnotationValue , T > converter , Supplier <T > defaultValue ) {
231
+ return QuarkusExtensionProcessor .annotationValueOrDefault (
232
+ controllerAnnotation , name , converter , defaultValue );
233
+ }
234
+ }
235
+
236
+ private static <T > T annotationValueOrDefault (
181
237
AnnotationInstance annotation ,
182
238
String name ,
183
239
Function <AnnotationValue , T > converter ,
184
240
Supplier <T > defaultValue ) {
185
- return Optional .ofNullable (annotation .value (name )).map (converter ).orElseGet (defaultValue );
241
+ return annotation != null
242
+ ?
243
+ // get converted annotation value of get default
244
+ Optional .ofNullable (annotation .value (name )).map (converter ).orElseGet (defaultValue )
245
+ :
246
+ // get default
247
+ defaultValue .get ();
186
248
}
187
249
188
250
private Class <?> loadClass (String className ) {
0 commit comments