1
1
package io .javaoperatorsdk .operator .api .config ;
2
2
3
3
import java .lang .annotation .Annotation ;
4
- import java .lang .reflect .Constructor ;
5
- import java .lang .reflect .InvocationTargetException ;
6
4
import java .time .Duration ;
7
5
import java .util .Arrays ;
8
6
import java .util .Collections ;
41
39
public class AnnotationControllerConfiguration <P extends HasMetadata >
42
40
implements io .javaoperatorsdk .operator .api .config .ControllerConfiguration <P > {
43
41
44
- private static final String CONTROLLER_CONFIG_ANNOTATION =
45
- ControllerConfiguration .class .getSimpleName ();
46
- private static final String KUBE_DEPENDENT_NAME = KubernetesDependent .class .getSimpleName ();
47
-
48
42
protected final Reconciler <P > reconciler ;
49
43
private final ControllerConfiguration annotation ;
50
44
private List <DependentResourceSpec > specs ;
@@ -152,71 +146,54 @@ public Optional<Duration> maxReconciliationInterval() {
152
146
@ Override
153
147
public RateLimiter getRateLimiter () {
154
148
final Class <? extends RateLimiter > rateLimiterClass = annotation .rateLimiter ();
155
- return instantiateAndConfigureIfNeeded (rateLimiterClass , RateLimiter .class ,
156
- CONTROLLER_CONFIG_ANNOTATION );
149
+ return Utils . instantiateAndConfigureIfNeeded (rateLimiterClass , RateLimiter .class ,
150
+ Utils . contextFor ( this , null , null ), this :: configureFromAnnotatedReconciler );
157
151
}
158
152
159
153
@ Override
160
154
public Retry getRetry () {
161
155
final Class <? extends Retry > retryClass = annotation .retry ();
162
- return instantiateAndConfigureIfNeeded (retryClass , Retry .class , CONTROLLER_CONFIG_ANNOTATION );
156
+ return Utils .instantiateAndConfigureIfNeeded (retryClass , Retry .class ,
157
+ Utils .contextFor (this , null , null ), this ::configureFromAnnotatedReconciler );
163
158
}
164
159
160
+
165
161
@ SuppressWarnings ("unchecked" )
166
- protected <T > T instantiateAndConfigureIfNeeded (Class <? extends T > targetClass ,
167
- Class <T > expectedType , String context ) {
168
- try {
169
- final Constructor <? extends T > constructor = targetClass .getDeclaredConstructor ();
170
- constructor .setAccessible (true );
171
- final var instance = constructor .newInstance ();
172
- if (instance instanceof AnnotationConfigurable ) {
173
- AnnotationConfigurable configurable = (AnnotationConfigurable ) instance ;
174
- final Class <? extends Annotation > configurationClass =
175
- (Class <? extends Annotation >) Utils .getFirstTypeArgumentFromSuperClassOrInterface (
176
- targetClass , AnnotationConfigurable .class );
177
- final var configAnnotation = reconciler .getClass ().getAnnotation (configurationClass );
178
- if (configAnnotation != null ) {
179
- configurable .initFrom (configAnnotation );
180
- }
162
+ private <T > void configureFromAnnotatedReconciler (T instance ) {
163
+ if (instance instanceof AnnotationConfigurable ) {
164
+ AnnotationConfigurable configurable = (AnnotationConfigurable ) instance ;
165
+ final Class <? extends Annotation > configurationClass =
166
+ (Class <? extends Annotation >) Utils .getFirstTypeArgumentFromSuperClassOrInterface (
167
+ instance .getClass (), AnnotationConfigurable .class );
168
+ final var configAnnotation = reconciler .getClass ().getAnnotation (configurationClass );
169
+ if (configAnnotation != null ) {
170
+ configurable .initFrom (configAnnotation );
181
171
}
182
- return instance ;
183
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException
184
- | NoSuchMethodException e ) {
185
- throw new OperatorException ("Couldn't instantiate " + expectedType .getSimpleName () + " '"
186
- + targetClass .getName () + "' for '" + getName ()
187
- + "' reconciler in " + context
188
- + ". You need to provide an accessible no-arg constructor." , e );
189
172
}
190
173
}
191
174
192
175
@ Override
193
176
@ SuppressWarnings ("unchecked" )
194
177
public Optional <OnAddFilter <P >> onAddFilter () {
195
- return (Optional <OnAddFilter <P >>) createFilter (annotation .onAddFilter (), OnAddFilter .class ,
196
- CONTROLLER_CONFIG_ANNOTATION );
197
- }
198
-
199
- protected <T > Optional <? extends T > createFilter (Class <? extends T > filter , Class <T > defaultValue ,
200
- String origin ) {
201
- if (defaultValue .equals (filter )) {
202
- return Optional .empty ();
203
- } else {
204
- return Optional .of (instantiateAndConfigureIfNeeded (filter , defaultValue , origin ));
205
- }
178
+ return Optional .ofNullable (
179
+ Utils .instantiate (annotation .onAddFilter (), OnAddFilter .class ,
180
+ Utils .contextFor (this , null , null )));
206
181
}
207
182
208
183
@ SuppressWarnings ("unchecked" )
209
184
@ Override
210
185
public Optional <OnUpdateFilter <P >> onUpdateFilter () {
211
- return (Optional <OnUpdateFilter <P >>) createFilter (annotation .onUpdateFilter (),
212
- OnUpdateFilter .class , CONTROLLER_CONFIG_ANNOTATION );
186
+ return Optional .ofNullable (
187
+ Utils .instantiate (annotation .onUpdateFilter (), OnUpdateFilter .class ,
188
+ Utils .contextFor (this , null , null )));
213
189
}
214
190
215
191
@ SuppressWarnings ("unchecked" )
216
192
@ Override
217
193
public Optional <GenericFilter <P >> genericFilter () {
218
- return (Optional <GenericFilter <P >>) createFilter (annotation .genericFilter (),
219
- GenericFilter .class , CONTROLLER_CONFIG_ANNOTATION );
194
+ return Optional .ofNullable (
195
+ Utils .instantiate (annotation .genericFilter (), GenericFilter .class ,
196
+ Utils .contextFor (this , null , null )));
220
197
}
221
198
222
199
@ SuppressWarnings ({"rawtypes" , "unchecked" })
@@ -244,12 +221,12 @@ public List<DependentResourceSpec> getDependentResources() {
244
221
throw new IllegalArgumentException (
245
222
"A DependentResource named '" + name + "' already exists: " + spec );
246
223
}
247
- final var context = "DependentResource of type '" + dependentType . getName () + "'" ;
224
+ final var context = Utils . contextFor ( this , dependentType , null ) ;
248
225
spec = new DependentResourceSpec (dependentType , config , name ,
249
226
Set .of (dependent .dependsOn ()),
250
- instantiateConditionIfNotDefault (dependent .readyPostcondition (), context ),
251
- instantiateConditionIfNotDefault (dependent .reconcilePrecondition (), context ),
252
- instantiateConditionIfNotDefault (dependent .deletePostcondition (), context ));
227
+ Utils . instantiate (dependent .readyPostcondition (), Condition . class , context ),
228
+ Utils . instantiate (dependent .reconcilePrecondition (), Condition . class , context ),
229
+ Utils . instantiate (dependent .deletePostcondition (), Condition . class , context ));
253
230
specsMap .put (name , spec );
254
231
}
255
232
@@ -258,14 +235,6 @@ public List<DependentResourceSpec> getDependentResources() {
258
235
return specs ;
259
236
}
260
237
261
- protected Condition <?, ?> instantiateConditionIfNotDefault (Class <? extends Condition > condition ,
262
- String context ) {
263
- if (condition != Condition .class ) {
264
- return instantiateAndConfigureIfNeeded (condition , Condition .class , context );
265
- }
266
- return null ;
267
- }
268
-
269
238
private String getName (Dependent dependent , Class <? extends DependentResource > dependentType ) {
270
239
var name = dependent .name ();
271
240
if (name .isBlank ()) {
@@ -299,18 +268,14 @@ private Object createKubernetesResourceConfig(Class<? extends DependentResource>
299
268
300
269
301
270
final var context =
302
- KUBE_DEPENDENT_NAME + " annotation on " + dependentType .getName () + " DependentResource" ;
303
- onAddFilter = createFilter (kubeDependent .onAddFilter (), OnAddFilter .class , context )
304
- .orElse (null );
271
+ Utils .contextFor (this , dependentType , null );
272
+ onAddFilter = Utils .instantiate (kubeDependent .onAddFilter (), OnAddFilter .class , context );
305
273
onUpdateFilter =
306
- createFilter (kubeDependent .onUpdateFilter (), OnUpdateFilter .class , context )
307
- .orElse (null );
274
+ Utils .instantiate (kubeDependent .onUpdateFilter (), OnUpdateFilter .class , context );
308
275
onDeleteFilter =
309
- createFilter (kubeDependent .onDeleteFilter (), OnDeleteFilter .class , context )
310
- .orElse (null );
276
+ Utils .instantiate (kubeDependent .onDeleteFilter (), OnDeleteFilter .class , context );
311
277
genericFilter =
312
- createFilter (kubeDependent .genericFilter (), GenericFilter .class , context )
313
- .orElse (null );
278
+ Utils .instantiate (kubeDependent .genericFilter (), GenericFilter .class , context );
314
279
}
315
280
316
281
config =
0 commit comments