halkyonio / primaza-poc

Quarkus Primaza Application - POC
1 stars 7 forks source link

FluentBuilder enum error: string to class cast exception #476

Open cmoulliard opened 4 months ago

cmoulliard commented 4 months ago

Issue

When we try to create a Crossplane Helm Release CR which is what the Primaza service (KubernetesClientService -> method: createCrossplaneHelmRelease(Cluster cluster, io.halkyon.model.Service service) do during the binding, then we got an error HTTP 500 from Primaza log

./scripts/data/bind_application.sh application_name=atomic-fruits claim_name=fruits-claim
  shell: /usr/bin/bash -e {0}
  env:
    PSEUDO_TTY: false
    JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/17.0.10-7/x6[4](https://github.com/halkyonio/primaza-poc/actions/runs/8923233395/job/24507035138?pr=475#step:13:4)
    JAVA_HOME_17_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/17.0.10-7/x64
    KIND_REGISTRY: kind-registry:[5](https://github.com/halkyonio/primaza-poc/actions/runs/8923233395/job/24507035138?pr=475#step:13:5)000
    PRIMAZA_URL: primaza.127.0.0.1.nip.io
    PRIMAZA_NAMESPACE: primaza
NOTE: Searching about the application to be bound ...
NOTE: curl -H 'Accept: application/json' -s primaza.12[7](https://github.com/halkyonio/primaza-poc/actions/runs/8923233395/job/24507035138?pr=475#step:13:7).0.0.1.nip.io/applications/name/atomic-fruits
NOTE: Application ID to be bound: 1
NOTE: Searching about the claim ...
NOTE: Claim ID to be bound: 1
NOTE: curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d "claimId=1" -s -i primaza.[12](https://github.com/halkyonio/primaza-poc/actions/runs/8923233395/job/24507035138?pr=475#step:13:13)7.0.0.1.nip.io/applications/claim/1
ERROR: Application failed to be bound in Primaza: 500 Internal Server Error
Error: Process completed with exit code 1.

The error reported is

Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class io.crossplane.helm.v1beta1.ReleaseSpec$ManagementPolicies (java.lang.String is in module java.base of loader 'b
ootstrap'; io.crossplane.helm.v1beta1.ReleaseSpec$ManagementPolicies is in unnamed module of loader io.quarkus.bootstrap.runner.RunnerClassLoader @475530b9)
    at io.crossplane.helm.v1beta1.ReleaseSpecFluent.withManagementPolicies(ReleaseSpecFluent.java:337)
    at io.crossplane.helm.v1beta1.ReleaseSpecFluent.copyInstance(ReleaseSpecFluent.java:57)
    at io.crossplane.helm.v1beta1.ReleaseSpecBuilder.<init>(ReleaseSpecBuilder.java:15)
    at io.crossplane.helm.v1beta1.ReleaseFluent$SpecNested.<init>(ReleaseFluent.java:232)
    at io.crossplane.helm.v1beta1.ReleaseFluent.withNewSpec(ReleaseFluent.java:101)
    at io.halkyon.services.KubernetesClientService.createCrossplaneHelmRelease(KubernetesClientService.java:247)

Code: https://github.com/halkyonio/primaza-poc/blob/ecf2f80da0f48b010b2ceef29c69a7c7a30cfb35/app/src/main/java/io/halkyon/services/KubernetesClientService.java#L246

Remark: I dont really understand why it complains about the ManagementPolicies - https://github.com/crossplane/crossplane-runtime/blob/master/apis/common/v1/policies.go as the object that we are creating which is a Release do not include it: https://github.com/crossplane-contrib/provider-helm/blob/master/apis/release/v1beta1/types.go

From @iocanel

"Ioannis Canellos: It seems to me that this is an issue with the generator. TBH, I've used that in that past (quarkus-kubevirt) and didn't have issues with enums.

The problem with the code is that it deserizes some code into a List however it doesn't populate the list with ManagementPolicies but with strings instead. So eventually it causes a class cast exception later on as this is unexpected."

public class ReleaseSpec implements io.fabric8.kubernetes.api.model.KubernetesResource {
...
    /**
     * THIS IS A BETA FIELD. It is on by default but can be opted out through a Crossplane feature flag. ManagementPolicies specify the array of actions Crossplane is allowed to take on the managed and external resources. This field is planned to replace the DeletionPolicy field in a future release. Currently, both could be set independently and non-default values would be honored if the feature flag is enabled. If both are custom, the DeletionPolicy field will be ignored. See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md
     */
    @com.fasterxml.jackson.annotation.JsonProperty("managementPolicies")
    @com.fasterxml.jackson.annotation.JsonPropertyDescription("THIS IS A BETA FIELD. It is on by default but can be opted out through a Crossplane feature flag. ManagementPolicies specify the array of actions Crossplane is allowed to take on the managed and external resources. This field is planned to replace the DeletionPolicy field in a future release. Currently, both could be set independently and non-default values would be honored if the feature flag is enabled. If both are custom, the DeletionPolicy field will be ignored. See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md")
    @com.fasterxml.jackson.annotation.JsonSetter(nulls = com.fasterxml.jackson.annotation.Nulls.SKIP)
    private java.util.List<ManagementPolicies> managementPolicies = io.fabric8.kubernetes.client.utils.Serialization.unmarshal("[\"*\"]", java.util.List.class);

Originally posted by @cmoulliard in https://github.com/halkyonio/primaza-poc/issues/475#issuecomment-2090306748

cmoulliard commented 4 months ago

The error is coming from the * value of the CRD ManagementPolicies enums that f8/sundrio tries to map to a class.

If we remove from the CRD the *, that works but now we got another error as no values are declared:

Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `io.crossplane.helm.v1beta1.ReleaseSpec$ManagementPolicies` from String "*": not one of the valu
es accepted for Enum class: [Update, Delete, Create, LateInitialize, Observe]
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 996] (through reference chain: io.crossplane.helm.v1beta1.Release["spec"]->io.crossplane.helm.v1beta1
.ReleaseSpec["managementPolicies"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1958)
    at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1245)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeAltString(EnumDeserializer.java:440)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._fromString(EnumDeserializer.java:304)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:273)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:359)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at io.fabric8.kubernetes.model.jackson.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:134)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at io.fabric8.kubernetes.model.jackson.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:134)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2125)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1501)
    at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:254)
    ... 62 more

Is there a trick ?

@aureamunoz @iocanel

iocanel commented 4 months ago

The error message still mentions '*'. So, it seems that it does creep in from somewhere. Maybe the CR? To be more specific I need more context about the error and ideally a full stack trace.

cmoulliard commented 4 months ago

a full stack trace.

Comment updated with fullstack trace.

cmoulliard commented 4 months ago

Maybe the CR?

https://github.com/halkyonio/primaza-poc/blob/ec9876695fea393228a6dbea18c2983b08ddc6b9/app/src/main/crds/helm.crossplane.io_releases.yaml

cmoulliard commented 4 months ago

So the issue is coming from the Release CRD definition: https://github.com/halkyonio/primaza-poc/blob/fecbea0bd9eb8e7907001878a29f341a68d78632/app/src/main/crds/helm.crossplane.io_releases.yaml and more specially the field ManagementPolicies

No matter if you set the default value as - '*' or - Create:

managementPolicies:
  default:
   - '*'

or

managementPolicies:
  default:
   - Create

we got the error:

Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class io.crossplane.helm.v1beta1.ReleaseSpec$ManagementPolicies (java.lang.String is in module java.base of loader 'b
ootstrap'; io.crossplane.helm.v1beta1.ReleaseSpec$ManagementPolicies is in unnamed module of loader io.quarkus.bootstrap.runner.RunnerClassLoader @475530b9)
    at io.crossplane.helm.v1beta1.ReleaseSpecFluent.withManagementPolicies(ReleaseSpecFluent.java:337)