generated from quarkiverse/quarkiverse-template
-
Notifications
You must be signed in to change notification settings - Fork 49
/
ConfigurationUtils.java
144 lines (130 loc) · 6.31 KB
/
ConfigurationUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package io.quarkiverse.operatorsdk.common;
import static io.quarkiverse.operatorsdk.common.Constants.CONTROLLER_CONFIGURATION;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.IndexView;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.api.config.Utils;
public class ConfigurationUtils {
private ConfigurationUtils() {
}
/**
* Extracts the appropriate configuration value for the controller checking first any annotation
* configuration, then potentially overriding it by a properties-provided value or returning a
* default value if neither is provided.
*
* @param <T> the expected type of the configuration value we're trying to extract
* @param <C> the type of the external configuration values can be overridden from
* @param annotation the annotation from which a field is to be extracted
* @param extractor a Function extracting the optional value we're interested in from the
* external configuration
* @param annotationField the name of the field we want to retrieve from the specified annotation
* if present
* @param converter a Function converting the annotation value to the type we're expecting
* @param defaultValue a Supplier that computes/retrieve a default value when needed
* @return the extracted configuration value
*/
public static <C, T> T extract(
C externalConfig,
AnnotationInstance annotation,
Function<C, Optional<T>> extractor,
String annotationField,
Function<AnnotationValue, T> converter,
Supplier<T> defaultValue) {
// first check if we have an external configuration
if (externalConfig != null) {
// extract value from config if present
return extractor
.apply(externalConfig)
// or get from the annotation or default
.orElse(
annotationValueOrDefault(annotation, annotationField, converter, defaultValue));
} else {
// get from annotation or default
return annotationValueOrDefault(annotation, annotationField, converter, defaultValue);
}
}
public static <T> T annotationValueOrDefault(
AnnotationInstance annotation,
String annotationFieldName,
Function<AnnotationValue, T> converter,
Supplier<T> defaultValue) {
return annotation != null
?
// get converted annotation value of get default
Optional.ofNullable(annotation.value(annotationFieldName)).map(converter).orElseGet(defaultValue)
:
// get default
defaultValue.get();
}
public static <T> ClassInfo getClassInfoForInstantiation(AnnotationValue toInstantiate,
Class<T> interfaceClass,
IndexView index) {
final var expectedTypeDN = toInstantiate.asClass().name();
final var expectedTypeInfo = index.getClassByName(expectedTypeDN);
if (!expectedTypeInfo.hasNoArgsConstructor()) {
throw new IllegalArgumentException(interfaceClass.getSimpleName() +
" implementations must provide a no-arg constructor for instantiation purposes");
}
return expectedTypeInfo;
}
@SuppressWarnings("unchecked")
public static <T> T instantiateImplementationClass(
AnnotationInstance annotation,
String annotationFieldName,
Class<T> interfaceClass,
Class<? extends T> defaultImplementation,
boolean returnNullIfDefault,
IndexView index) {
defaultImplementation = returnNullIfDefault ? null : defaultImplementation;
final var implementationClass = annotation != null
?
// get converted annotation value of get default
Optional.ofNullable(annotation.value(annotationFieldName))
.map(av -> {
final var expectedTypeInfo = getClassInfoForInstantiation(av,
interfaceClass,
index);
final var typeName = expectedTypeInfo.name().toString();
return ClassLoadingUtils.loadClass(typeName,
interfaceClass);
})
.orElse((Class<T>) defaultImplementation)
:
// get default
defaultImplementation;
if (returnNullIfDefault && implementationClass == null) {
return null;
}
return ClassLoadingUtils.instantiate(implementationClass);
}
/**
* Checks whether CRD presence should be checked on the cluster and if custom resources should be (somewhat) validated.
* If the {@link Utils#CHECK_CRD_ENV_KEY} system property is set, this will be used, regardless of other configuration
* options.
*
* @param validate value from the build time configuration
* @return the value specified by {@link Utils#CHECK_CRD_ENV_KEY} if set, the value specified by the build time
* configuration property otherwise
*/
public static boolean shouldValidateCustomResources(boolean validate) {
if (Utils.isValidateCustomResourcesEnvVarSet()) {
return Utils.shouldCheckCRDAndValidateLocalModel();
}
return validate;
}
public static String getReconcilerName(ClassInfo info) {
final var controllerClassName = info.name().toString();
final var controllerAnnotation = info.classAnnotation(CONTROLLER_CONFIGURATION);
return getReconcilerName(controllerClassName, controllerAnnotation);
}
public static String getReconcilerName(String reconcilerClassName, AnnotationInstance configuration) {
final var defaultControllerName = ReconcilerUtils.getDefaultReconcilerName(reconcilerClassName);
return ConfigurationUtils.annotationValueOrDefault(
configuration, "name", AnnotationValue::asString, () -> defaultControllerName);
}
}