@@ -24,6 +24,10 @@ public class ReconcilerUtils {
24
24
25
25
private static final String FINALIZER_NAME_SUFFIX = "/finalizer" ;
26
26
protected static final String MISSING_GROUP_SUFFIX = ".javaoperatorsdk.io" ;
27
+ private static final String GET_SPEC = "getSpec" ;
28
+ private static final String SET_SPEC = "setSpec" ;
29
+ private static final Pattern API_URI_PATTERN =
30
+ Pattern .compile (".*http(s?)://[^/]*/api(s?)/(\\ S*).*" ); // NOSONAR: input is controlled
27
31
28
32
// prevent instantiation of util class
29
33
private ReconcilerUtils () {}
@@ -94,25 +98,55 @@ public static boolean specsEqual(HasMetadata r1, HasMetadata r2) {
94
98
95
99
// will be replaced with: https://github.com/fabric8io/kubernetes-client/issues/3816
96
100
public static Object getSpec (HasMetadata resource ) {
101
+ // optimize CustomResource case
102
+ if (resource instanceof CustomResource ) {
103
+ CustomResource cr = (CustomResource ) resource ;
104
+ return cr .getSpec ();
105
+ }
106
+
97
107
try {
98
- Method getSpecMethod = resource .getClass ().getMethod ("getSpec" );
108
+ Method getSpecMethod = resource .getClass ().getMethod (GET_SPEC );
99
109
return getSpecMethod .invoke (resource );
100
110
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e ) {
101
- throw new IllegalStateException ( "No spec found on resource" , e );
111
+ throw noSpecException ( resource , e );
102
112
}
103
113
}
104
114
115
+ @ SuppressWarnings ("unchecked" )
105
116
public static Object setSpec (HasMetadata resource , Object spec ) {
117
+ // optimize CustomResource case
118
+ if (resource instanceof CustomResource ) {
119
+ CustomResource cr = (CustomResource ) resource ;
120
+ cr .setSpec (spec );
121
+ return null ;
122
+ }
123
+
106
124
try {
107
125
Class <? extends HasMetadata > resourceClass = resource .getClass ();
108
- Method setSpecMethod =
109
- resource .getClass ().getMethod ("setSpec" , getSpecClass (resourceClass , spec ));
126
+
127
+ // if given spec is null, find the method just using its name
128
+ Method setSpecMethod ;
129
+ if (spec != null ) {
130
+ setSpecMethod = resourceClass .getMethod (SET_SPEC , spec .getClass ());
131
+ } else {
132
+ setSpecMethod = Arrays .stream (resourceClass .getMethods ())
133
+ .filter (method -> SET_SPEC .equals (method .getName ()))
134
+ .findFirst ()
135
+ .orElseThrow (() -> noSpecException (resource , null ));
136
+ }
137
+
110
138
return setSpecMethod .invoke (resource , spec );
111
139
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e ) {
112
- throw new IllegalStateException ( "No spec found on resource" , e );
140
+ throw noSpecException ( resource , e );
113
141
}
114
142
}
115
143
144
+ private static IllegalStateException noSpecException (HasMetadata resource ,
145
+ ReflectiveOperationException e ) {
146
+ return new IllegalStateException ("No spec found on resource " + resource .getClass ().getName (),
147
+ e );
148
+ }
149
+
116
150
public static <T > T loadYaml (Class <T > clazz , Class loader , String yaml ) {
117
151
try (InputStream is = loader .getResourceAsStream (yaml )) {
118
152
if (Builder .class .isAssignableFrom (clazz )) {
@@ -149,9 +183,7 @@ private static boolean matchesResourceType(String resourceTypeName,
149
183
} else {
150
184
// extract matching information from URI in the message if available
151
185
final var message = exception .getMessage ();
152
- final var regex = Pattern
153
- .compile (".*http(s?)://[^/]*/api(s?)/(\\ S*).*" ) // NOSONAR: input is controlled
154
- .matcher (message );
186
+ final var regex = API_URI_PATTERN .matcher (message );
155
187
if (regex .matches ()) {
156
188
var group = regex .group (3 );
157
189
if (group .endsWith ("." )) {
@@ -168,14 +200,4 @@ private static boolean matchesResourceType(String resourceTypeName,
168
200
}
169
201
return false ;
170
202
}
171
-
172
- // CustomResouce has a parameterized parameter type
173
- private static Class getSpecClass (Class <? extends HasMetadata > resourceClass , Object spec ) {
174
- if (CustomResource .class .isAssignableFrom (resourceClass )) {
175
- return Object .class ;
176
- } else {
177
- return spec .getClass ();
178
- }
179
- }
180
-
181
203
}
0 commit comments