@@ -53,11 +53,13 @@ public class ModelMapper {
53
53
// Model's api-version midfix to kubernetes api-version
54
54
private static List <String > preBuiltApiVersions = new ArrayList <>();
55
55
56
- // TODO(yue9944882): make the map bi-directional
57
- private static Map < GroupVersionKind , Class <?>> classesByGVK = new ConcurrentHashMap <>();
56
+ private static BiDirectionalMap < GroupVersionKind , Class <?>> classesByGVK =
57
+ new BiDirectionalMap <>();
58
58
59
- // TODO(yue9944882): make the map bi-directional
60
- private static Map <GroupVersionResource , Class <?>> classesByGVR = new ConcurrentHashMap <>();
59
+ private static BiDirectionalMap <GroupVersionResource , Class <?>> classesByGVR =
60
+ new BiDirectionalMap <>();
61
+
62
+ private static Map <Class <?>, Boolean > isNamespacedByClasses = new ConcurrentHashMap <>();
61
63
62
64
private static Set <Discovery .APIResource > lastAPIDiscovery = new HashSet <>();
63
65
@@ -114,8 +116,31 @@ public static void addModelMap(String group, String version, String kind, Class<
114
116
*/
115
117
public static void addModelMap (
116
118
String group , String version , String kind , String resourceNamePlural , Class <?> clazz ) {
117
- classesByGVK .put (new GroupVersionKind (group , version , kind ), clazz );
118
- classesByGVR .put (new GroupVersionResource (group , version , resourceNamePlural ), clazz );
119
+ // TODO(yue9944882): consistency between bi-directional maps
120
+ classesByGVK .add (new GroupVersionKind (group , version , kind ), clazz );
121
+ classesByGVR .add (new GroupVersionResource (group , version , resourceNamePlural ), clazz );
122
+ }
123
+
124
+ /**
125
+ * Registering concrete model classes by its group, version, kind and isNamespaced (e.g. "apps",
126
+ * "v1", "Deployment", true).
127
+ *
128
+ * @param group the group
129
+ * @param version the version
130
+ * @param kind the kind
131
+ * @param resourceNamePlural the resource name plural
132
+ * @param isNamespacedResource the is namespaced resource
133
+ * @param clazz the clazz
134
+ */
135
+ public static void addModelMap (
136
+ String group ,
137
+ String version ,
138
+ String kind ,
139
+ String resourceNamePlural ,
140
+ Boolean isNamespacedResource ,
141
+ Class <?> clazz ) {
142
+ addModelMap (group , version , kind , resourceNamePlural , clazz );
143
+ isNamespacedByClasses .put (clazz , isNamespacedResource );
119
144
}
120
145
121
146
/**
@@ -149,7 +174,7 @@ public static Class<?> getApiTypeClass(String apiGroupVersion, String kind) {
149
174
* @return the api type class
150
175
*/
151
176
public static Class <?> getApiTypeClass (String group , String version , String kind ) {
152
- Class <?> clazz = classesByGVK .get (new GroupVersionKind (group , version , kind ));
177
+ Class <?> clazz = classesByGVK .getByK (new GroupVersionKind (group , version , kind ));
153
178
if (clazz != null ) {
154
179
return clazz ;
155
180
}
@@ -163,11 +188,7 @@ public static Class<?> getApiTypeClass(String group, String version, String kind
163
188
* @return the group version kind by class
164
189
*/
165
190
public static GroupVersionKind getGroupVersionKindByClass (Class <?> clazz ) {
166
- return classesByGVK .entrySet ().stream ()
167
- .filter (e -> clazz .equals (e .getValue ()))
168
- .map (e -> e .getKey ())
169
- .findFirst ()
170
- .orElse (preBuiltGetGroupVersionKindByClass (clazz ));
191
+ return classesByGVK .getByV (clazz );
171
192
}
172
193
173
194
/**
@@ -177,13 +198,18 @@ public static GroupVersionKind getGroupVersionKindByClass(Class<?> clazz) {
177
198
* @return the group version kind by class
178
199
*/
179
200
public static GroupVersionResource getGroupVersionResourceByClass (Class <?> clazz ) {
180
- return classesByGVR .entrySet ().stream ()
181
- .filter (e -> clazz .equals (e .getValue ()))
182
- .map (e -> e .getKey ())
183
- .findFirst ()
184
- .get ();
201
+ return classesByGVR .getByV (clazz );
185
202
}
186
203
204
+ /**
205
+ * Refreshes the model mapping by syncing up w/the api discovery info from the kubernetes
206
+ * apiserver. These mapping will be cached for {@link
207
+ * ModelMapper#DEFAULT_DISCOVERY_REFRESH_INTERVAL}.
208
+ *
209
+ * @param discovery the discovery
210
+ * @return the set
211
+ * @throws ApiException the api exception
212
+ */
187
213
public static Set <Discovery .APIResource > refresh (Discovery discovery ) throws ApiException {
188
214
return refresh (discovery , DEFAULT_DISCOVERY_REFRESH_INTERVAL );
189
215
}
@@ -220,6 +246,7 @@ public static Set<Discovery.APIResource> refresh(Discovery discovery, Duration r
220
246
version ,
221
247
apiResource .getKind (),
222
248
apiResource .getResourcePlural (),
249
+ apiResource .getNamespaced (),
223
250
clazz );
224
251
}
225
252
}
@@ -253,6 +280,16 @@ public static GroupVersionKind preBuiltGetGroupVersionKindByClass(Class<?> clazz
253
280
.get ();
254
281
}
255
282
283
+ /**
284
+ * Checks whether the class is connected with a namespaced kubernetes resource.
285
+ *
286
+ * @param clazz the clazz
287
+ * @return the boolean
288
+ */
289
+ public static Boolean isNamespaced (Class <?> clazz ) {
290
+ return isNamespacedByClasses .get (clazz );
291
+ }
292
+
256
293
private static void initApiGroupMap () {
257
294
preBuiltApiGroups .put ("Admissionregistration" , "admissionregistration.k8s.io" );
258
295
preBuiltApiGroups .put ("Apiextensions" , "apiextensions.k8s.io" );
@@ -325,4 +362,22 @@ private static Pair<String, String> getApiVersion(String name) {
325
362
.findFirst ()
326
363
.orElse (new MutablePair (null , name ));
327
364
}
365
+
366
+ static class BiDirectionalMap <K , V > {
367
+ private Map <K , V > kvMap = new HashMap <>();
368
+ private Map <V , K > vkMap = new HashMap <>();
369
+
370
+ synchronized void add (K k , V v ) {
371
+ kvMap .put (k , v );
372
+ vkMap .put (v , k );
373
+ }
374
+
375
+ synchronized V getByK (K k ) {
376
+ return kvMap .get (k );
377
+ }
378
+
379
+ synchronized K getByV (V v ) {
380
+ return vkMap .get (v );
381
+ }
382
+ }
328
383
}
0 commit comments