11package io .javaoperatorsdk .operator .api .config ;
22
33import java .lang .annotation .Annotation ;
4- import java .lang .reflect .Constructor ;
5- import java .lang .reflect .InvocationTargetException ;
64import java .time .Duration ;
75import java .util .Arrays ;
86import java .util .Collections ;
4139public class AnnotationControllerConfiguration <P extends HasMetadata >
4240 implements io .javaoperatorsdk .operator .api .config .ControllerConfiguration <P > {
4341
44- private static final String CONTROLLER_CONFIG_ANNOTATION =
45- ControllerConfiguration .class .getSimpleName ();
46- private static final String KUBE_DEPENDENT_NAME = KubernetesDependent .class .getSimpleName ();
47-
4842 protected final Reconciler <P > reconciler ;
4943 private final ControllerConfiguration annotation ;
5044 private List <DependentResourceSpec > specs ;
@@ -152,71 +146,54 @@ public Optional<Duration> maxReconciliationInterval() {
152146 @ Override
153147 public RateLimiter getRateLimiter () {
154148 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 );
157151 }
158152
159153 @ Override
160154 public Retry getRetry () {
161155 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 );
163158 }
164159
160+
165161 @ 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 );
181171 }
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 );
189172 }
190173 }
191174
192175 @ Override
193176 @ SuppressWarnings ("unchecked" )
194177 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 )));
206181 }
207182
208183 @ SuppressWarnings ("unchecked" )
209184 @ Override
210185 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 )));
213189 }
214190
215191 @ SuppressWarnings ("unchecked" )
216192 @ Override
217193 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 )));
220197 }
221198
222199 @ SuppressWarnings ({"rawtypes" , "unchecked" })
@@ -244,12 +221,12 @@ public List<DependentResourceSpec> getDependentResources() {
244221 throw new IllegalArgumentException (
245222 "A DependentResource named '" + name + "' already exists: " + spec );
246223 }
247- final var context = "DependentResource of type '" + dependentType . getName () + "'" ;
224+ final var context = Utils . contextFor ( this , dependentType , null ) ;
248225 spec = new DependentResourceSpec (dependentType , config , name ,
249226 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 ));
253230 specsMap .put (name , spec );
254231 }
255232
@@ -258,14 +235,6 @@ public List<DependentResourceSpec> getDependentResources() {
258235 return specs ;
259236 }
260237
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-
269238 private String getName (Dependent dependent , Class <? extends DependentResource > dependentType ) {
270239 var name = dependent .name ();
271240 if (name .isBlank ()) {
@@ -299,18 +268,14 @@ private Object createKubernetesResourceConfig(Class<? extends DependentResource>
299268
300269
301270 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 );
305273 onUpdateFilter =
306- createFilter (kubeDependent .onUpdateFilter (), OnUpdateFilter .class , context )
307- .orElse (null );
274+ Utils .instantiate (kubeDependent .onUpdateFilter (), OnUpdateFilter .class , context );
308275 onDeleteFilter =
309- createFilter (kubeDependent .onDeleteFilter (), OnDeleteFilter .class , context )
310- .orElse (null );
276+ Utils .instantiate (kubeDependent .onDeleteFilter (), OnDeleteFilter .class , context );
311277 genericFilter =
312- createFilter (kubeDependent .genericFilter (), GenericFilter .class , context )
313- .orElse (null );
278+ Utils .instantiate (kubeDependent .genericFilter (), GenericFilter .class , context );
314279 }
315280
316281 config =
0 commit comments