diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java index 229d5e5223..e17fea7b6c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java @@ -12,6 +12,7 @@ import io.fabric8.kubernetes.api.builder.Builder; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.utils.Serialization; import io.javaoperatorsdk.operator.api.reconciler.Constants; @@ -103,7 +104,9 @@ public static Object getSpec(HasMetadata resource) { public static Object setSpec(HasMetadata resource, Object spec) { try { - Method setSpecMethod = resource.getClass().getMethod("setSpec", spec.getClass()); + Class resourceClass = resource.getClass(); + Method setSpecMethod = + resource.getClass().getMethod("setSpec", getSpecClass(resourceClass, spec)); return setSpecMethod.invoke(resource, spec); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw new IllegalStateException("No spec found on resource", e); @@ -167,4 +170,13 @@ private static boolean matchesResourceType(String resourceTypeName, return false; } + // CustomResouce has a parameterized parameter type + private static Class getSpecClass(Class resourceClass, Object spec) { + if (CustomResource.class.isAssignableFrom(resourceClass)) { + return Object.class; + } else { + return spec.getClass(); + } + } + } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ReconcilerUtilsTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ReconcilerUtilsTest.java index 1bdad72c76..ebce136775 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ReconcilerUtilsTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ReconcilerUtilsTest.java @@ -98,6 +98,19 @@ void setsSpecWithReflection() { assertThat(deployment.getSpec().getReplicas()).isEqualTo(1); } + @Test + void setsSpecCustomResourceWithReflection() { + Tomcat tomcat = new Tomcat(); + tomcat.setSpec(new TomcatSpec()); + tomcat.getSpec().setReplicas(5); + TomcatSpec newSpec = new TomcatSpec(); + newSpec.setReplicas(1); + + ReconcilerUtils.setSpec(tomcat, newSpec); + + assertThat(tomcat.getSpec().getReplicas()).isEqualTo(1); + } + @Test void loadYamlAsBuilder() { DeploymentBuilder builder = @@ -134,7 +147,19 @@ void handleKubernetesExceptionShouldThrowMissingCRDExceptionWhenAppropriate() { @Group("tomcatoperator.io") @Version("v1") @ShortNames("tc") - private static class Tomcat extends CustomResource implements Namespaced { + private static class Tomcat extends CustomResource implements Namespaced { + + } + + private class TomcatSpec { + private Integer replicas; + + public Integer getReplicas() { + return replicas; + } + public void setReplicas(Integer replicas) { + this.replicas = replicas; + } } }