Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 042ed26

Browse files
committedAug 29, 2024··
refactor: clean up, cache already resolved GVKs
Signed-off-by: Chris Laprun <[email protected]>
1 parent 67693eb commit 042ed26

File tree

6 files changed

+110
-30
lines changed

6 files changed

+110
-30
lines changed
 

‎operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/GroupVersionKind.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package io.javaoperatorsdk.operator.processing;
22

3+
import java.util.Map;
34
import java.util.Objects;
5+
import java.util.concurrent.ConcurrentHashMap;
46

57
import io.fabric8.kubernetes.api.model.HasMetadata;
6-
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.GroupVersionKindPlural;
78

89
public class GroupVersionKind {
910
private final String group;
1011
private final String version;
1112
private final String kind;
1213
private final String apiVersion;
14+
protected final static Map<Class<? extends HasMetadata>, GroupVersionKind> CACHE =
15+
new ConcurrentHashMap<>();
1316

14-
/**
15-
* @deprecated Use {@link GroupVersionKindPlural#gvkFor(String, String)} instead
16-
*/
17-
@Deprecated(forRemoval = true)
1817
public GroupVersionKind(String apiVersion, String kind) {
1918
this.kind = kind;
2019
String[] groupAndVersion = apiVersion.split("/");
@@ -29,13 +28,14 @@ public GroupVersionKind(String apiVersion, String kind) {
2928
}
3029

3130
public static GroupVersionKind gvkFor(Class<? extends HasMetadata> resourceClass) {
32-
return GroupVersionKindPlural.gvkFor(resourceClass);
31+
return CACHE.computeIfAbsent(resourceClass, GroupVersionKind::computeGVK);
32+
}
33+
34+
private static GroupVersionKind computeGVK(Class<? extends HasMetadata> rc) {
35+
return new GroupVersionKind(HasMetadata.getGroup(rc),
36+
HasMetadata.getVersion(rc), HasMetadata.getKind(rc));
3337
}
3438

35-
/**
36-
* @deprecated Use {@link GroupVersionKindPlural#gvkFor(String, String, String)} instead
37-
*/
38-
@Deprecated(forRemoval = true)
3939
public GroupVersionKind(String group, String version, String kind) {
4040
this.group = group;
4141
this.version = version;

‎operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class GenericKubernetesDependentResource<P extends HasMetadata>
1111
private final GroupVersionKindPlural groupVersionKind;
1212

1313
public GenericKubernetesDependentResource(GroupVersionKind groupVersionKind) {
14-
this(new GroupVersionKindPlural(groupVersionKind));
14+
this(GroupVersionKindPlural.from(groupVersionKind));
1515
}
1616

1717
public GenericKubernetesDependentResource(GroupVersionKindPlural groupVersionKind) {

‎operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GroupVersionKindPlural.java

+65-12
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,83 @@
66
import io.fabric8.kubernetes.api.model.HasMetadata;
77
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
88

9+
/**
10+
* An extension of {@link GroupVersionKind} that also records the associated plural form which is
11+
* useful when dealing with Kubernetes RBACs. Downstream projects might leverage that information.
12+
*/
913
public class GroupVersionKindPlural extends GroupVersionKind {
1014
private final String plural;
1115

12-
public GroupVersionKindPlural(String group, String version, String kind, String plural) {
16+
protected GroupVersionKindPlural(String group, String version, String kind, String plural) {
1317
super(group, version, kind);
1418
this.plural = plural;
1519
}
1620

17-
public GroupVersionKindPlural(GroupVersionKind gvk) {
21+
protected GroupVersionKindPlural(String apiVersion, String kind, String plural) {
22+
super(apiVersion, kind);
23+
this.plural = plural;
24+
}
25+
26+
protected GroupVersionKindPlural(GroupVersionKind gvk, String plural) {
1827
this(gvk.getGroup(), gvk.getVersion(), gvk.getKind(),
19-
gvk instanceof GroupVersionKindPlural ? ((GroupVersionKindPlural) gvk).plural : null);
28+
plural != null ? plural
29+
: (gvk instanceof GroupVersionKindPlural ? ((GroupVersionKindPlural) gvk).plural
30+
: null));
2031
}
2132

22-
public static GroupVersionKind gvkFor(String group, String version, String kind) {
23-
return new GroupVersionKind(group, version, kind);
33+
/**
34+
* Creates a new GroupVersionKindPlural from the specified {@link GroupVersionKind}.
35+
*
36+
* @param gvk a {@link GroupVersionKind} from which to create a new GroupVersionKindPlural object
37+
* @return a new GroupVersionKindPlural object matching the specified {@link GroupVersionKind}
38+
*/
39+
public static GroupVersionKindPlural from(GroupVersionKind gvk) {
40+
return gvk instanceof GroupVersionKindPlural ? ((GroupVersionKindPlural) gvk)
41+
: gvkWithPlural(gvk, null);
2442
}
2543

26-
public static GroupVersionKind gvkFor(String apiVersion, String kind) {
27-
return new GroupVersionKind(apiVersion, kind);
44+
/**
45+
* Creates a new GroupVersionKindPlural based on the specified {@link GroupVersionKind} instance
46+
* but specifying a plural form to use as well.
47+
*
48+
* @param gvk the base {@link GroupVersionKind} from which to derive a new GroupVersionKindPlural
49+
* @param plural the plural form to use for the new instance or {@code null} if the default plural
50+
* form is desired. Note that the specified plural form will override any existing plural
51+
* form for the specified {@link GroupVersionKind} (in particular, if the specified
52+
* {@link GroupVersionKind} was already an instance of GroupVersionKindPlural, its plural
53+
* form will only be considered in the new instance if the specified plural form is
54+
* {@code null}
55+
* @return a new GroupVersionKindPlural derived from the specified {@link GroupVersionKind} and
56+
* plural form
57+
*/
58+
public static GroupVersionKindPlural gvkWithPlural(GroupVersionKind gvk, String plural) {
59+
return new GroupVersionKindPlural(gvk, plural);
2860
}
2961

62+
/**
63+
* Creates a new GroupVersionKindPlural instance extracting the information from the specified
64+
* {@link HasMetadata} implementation
65+
*
66+
* @param resourceClass the {@link HasMetadata} from which group, version, kind and plural form
67+
* are extracted
68+
* @return a new GroupVersionKindPlural instance based on the specified {@link HasMetadata}
69+
* implementation
70+
*/
3071
public static GroupVersionKindPlural gvkFor(Class<? extends HasMetadata> resourceClass) {
31-
return new GroupVersionKindPlural(HasMetadata.getGroup(resourceClass),
32-
HasMetadata.getVersion(resourceClass), HasMetadata.getKind(resourceClass),
33-
HasMetadata.getPlural(resourceClass));
72+
final var gvk = GroupVersionKind.gvkFor(resourceClass);
73+
return gvkWithPlural(gvk, HasMetadata.getPlural(resourceClass));
74+
}
75+
76+
/**
77+
* Retrieves the default plural form for the specified kind.
78+
*
79+
* @param kind the kind for which we want to get the default plural form
80+
* @return the default plural form for the specified kind
81+
*/
82+
public static String getDefaultPluralFor(String kind) {
83+
// todo: replace by Fabric8 version when available, see
84+
// https://github.com/fabric8io/kubernetes-client/pull/6314
85+
return kind != null ? Pluralize.toPlural(kind.toLowerCase()) : null;
3486
}
3587

3688
/**
@@ -46,13 +98,14 @@ public Optional<String> getPlural() {
4698

4799
/**
48100
* Returns the plural form associated with the kind if it was provided or a default, computed form
49-
* via {@link Pluralize#toPlural(String)} (which should correspond to the actual plural form in
101+
* via {@link #getDefaultPluralFor(String)} (which should correspond to the actual plural form in
50102
* most cases but might not always be correct, especially if the resource's creator defined an
51103
* exotic plural form via the CRD.
52104
*
53105
* @return the plural form associated with the kind if provided or a default plural form otherwise
54106
*/
107+
@SuppressWarnings("unused")
55108
public String getPluralOrDefault() {
56-
return getPlural().orElse(Pluralize.toPlural(getKind()));
109+
return getPlural().orElse(getDefaultPluralFor(getKind()));
57110
}
58111
}

‎operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/GroupVersionKindTest.java

+32-3
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,48 @@ class GroupVersionKindTest {
1212

1313
@Test
1414
void testInitFromApiVersion() {
15-
var gvk = GroupVersionKindPlural.gvkFor("v1", "ConfigMap");
15+
var gvk = new GroupVersionKind("v1", "ConfigMap");
1616
assertThat(gvk.getGroup()).isNull();
1717
assertThat(gvk.getVersion()).isEqualTo("v1");
1818

19-
gvk = GroupVersionKindPlural.gvkFor("apps/v1", "Deployment");
19+
gvk = new GroupVersionKind("apps/v1", "Deployment");
2020
assertThat(gvk.getGroup()).isEqualTo("apps");
2121
assertThat(gvk.getVersion()).isEqualTo("v1");
2222
}
2323

2424
@Test
2525
void pluralShouldOnlyBeProvidedIfExplicitlySet() {
26-
final var gvk = GroupVersionKindPlural.gvkFor(ConfigMap.class);
26+
final var kind = "ConfigMap";
27+
var gvk = GroupVersionKindPlural.from(new GroupVersionKind("v1", kind));
28+
assertThat(gvk.getPlural()).isEmpty();
29+
assertThat(gvk.getPluralOrDefault())
30+
.isEqualTo(GroupVersionKindPlural.getDefaultPluralFor(kind));
31+
32+
gvk = GroupVersionKindPlural.from(GroupVersionKind.gvkFor(ConfigMap.class));
33+
assertThat(gvk.getPlural()).isEmpty();
34+
assertThat(gvk.getPluralOrDefault()).isEqualTo(HasMetadata.getPlural(ConfigMap.class));
35+
36+
gvk = GroupVersionKindPlural.gvkFor(ConfigMap.class);
37+
assertThat(gvk.getPlural()).hasValue(HasMetadata.getPlural(ConfigMap.class));
38+
39+
gvk = GroupVersionKindPlural.from(gvk);
2740
assertThat(gvk.getPlural()).hasValue(HasMetadata.getPlural(ConfigMap.class));
2841
}
2942

43+
@Test
44+
void pluralShouldBeEmptyIfNotProvided() {
45+
final var kind = "MyKind";
46+
var gvk =
47+
GroupVersionKindPlural.gvkWithPlural(new GroupVersionKind("josdk.io", "v1", kind), null);
48+
assertThat(gvk.getPlural()).isEmpty();
49+
assertThat(gvk.getPluralOrDefault())
50+
.isEqualTo(GroupVersionKindPlural.getDefaultPluralFor(kind));
51+
}
52+
53+
@Test
54+
void pluralShouldOverrideDefaultComputedVersionIfProvided() {
55+
var gvk = GroupVersionKindPlural.gvkWithPlural(new GroupVersionKind("josdk.io", "v1", "MyKind"),
56+
"MyPlural");
57+
assertThat(gvk.getPlural()).hasValue("MyPlural");
58+
}
3059
}

‎operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/generickubernetesresource/generickubernetesdependentresourcemanaged/ConfigMapGenericKubernetesDependent.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.io.InputStream;
55
import java.util.Map;
66

7-
import io.fabric8.kubernetes.api.model.ConfigMap;
87
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
98
import io.javaoperatorsdk.operator.api.reconciler.Context;
109
import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected;
@@ -25,7 +24,7 @@ public class ConfigMapGenericKubernetesDependent extends
2524
public static final String KEY = "key";
2625

2726
public ConfigMapGenericKubernetesDependent() {
28-
super(GroupVersionKind.gvkFor(ConfigMap.class));
27+
super(new GroupVersionKind("", VERSION, KIND));
2928
}
3029

3130
@Override

‎operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/generickubernetesresource/generickubernetesdependentstandalone/ConfigMapGenericKubernetesDependent.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.io.InputStream;
55
import java.util.Map;
66

7-
import io.fabric8.kubernetes.api.model.ConfigMap;
87
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
98
import io.javaoperatorsdk.operator.api.reconciler.Context;
109
import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected;
@@ -25,7 +24,7 @@ public class ConfigMapGenericKubernetesDependent extends
2524
public static final String KEY = "key";
2625

2726
public ConfigMapGenericKubernetesDependent() {
28-
super(GroupVersionKind.gvkFor(ConfigMap.class));
27+
super(new GroupVersionKind("", VERSION, KIND));
2928
}
3029

3130
@Override

0 commit comments

Comments
 (0)
Please sign in to comment.