-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Expected Behavior
Using Informer to fetch Custom Resources has limitations.
When naming classes that will represent Custom Resource, one must prepend them with the version number.
This is a nice design choice, but the current implementation in not correct.
It will be nice to specify this design choice in the official documentation.
Correct examples:
V1MySettings
V1alpha1Operation
Incorrect examples:
MyCustomResource
V2Example
The library should support multiple versions, and not be limited to the predefined versions list (io.micronaut.kubernetes.client.ModelMapper.preBuiltApiVersions
).
Now it is not possible to define Custom Resource using any other version other than one specified in the predefined versions list.
Actual Behaviour
Naming java class for custom resource will influence instantiation of shared index informer.
If not named correctly (ex: V2CustomResource) the following exception will be thrown:
18:50:34.229 [main] ERROR io.micronaut.runtime.Micronaut - Error starting Micronaut server: Bean definition [org.foo.bar.V2CustomResourceInformer] could not be loaded: version must not be null
io.micronaut.context.exceptions.BeanInstantiationException: Bean definition [org.foo.bar.V2CustomResourceInformer] could not be loaded: version must not be null
at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1979)
at io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:290)
at io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:3340)
at io.micronaut.context.DefaultBeanContext.finalizeConfiguration(DefaultBeanContext.java:3693)
at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:345)
at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:198)
at io.micronaut.runtime.Micronaut.start(Micronaut.java:73)
at io.micronaut.runtime.Micronaut.run(Micronaut.java:322)
at io.micronaut.runtime.Micronaut.run(Micronaut.java:308)
at org.foo.bar.Application.main(Application.java:37)
Caused by: java.lang.IllegalArgumentException: version must not be null
at io.kubernetes.client.util.Preconditions.precondition(Preconditions.java:41)
at io.kubernetes.client.apimachinery.GroupVersion.<init>(GroupVersion.java:42)
at io.kubernetes.client.apimachinery.GroupVersionKind.<init>(GroupVersionKind.java:24)
at io.micronaut.kubernetes.client.ModelMapper.getGroupVersionKindByClass(ModelMapper.java:114)
at io.micronaut.kubernetes.client.informer.DefaultSharedIndexInformerFactory.sharedIndexInformerFor(DefaultSharedIndexInformerFactory.java:116)
at io.micronaut.kubernetes.client.informer.DefaultSharedIndexInformerFactory.sharedIndexInformersFor(DefaultSharedIndexInformerFactory.java:226)
at io.micronaut.kubernetes.client.informer.ResourceEventHandlerBeanListener.onCreated(ResourceEventHandlerBeanListener.java:97)
at io.micronaut.kubernetes.client.informer.ResourceEventHandlerBeanListener.onCreated(ResourceEventHandlerBeanListener.java:50)
at io.micronaut.context.DefaultBeanContext.triggerBeanCreatedEventListener(DefaultBeanContext.java:2360)
at io.micronaut.context.DefaultBeanContext.postBeanCreated(DefaultBeanContext.java:2337)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2281)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2289)
at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3056)
at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:81)
at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2958)
at io.micronaut.context.DefaultBeanContext.initializeEagerBean(DefaultBeanContext.java:2676)
at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1973)
... 9 common frames omitted
Using either @Informer annotation, or calling sharedIndexInformerFor method on DefaultSharedIndexInformerFactory class will result in exception.
The problem can be traced to line 116 in DefaultSharedIndexInformerFactory class.
The internal class ModelMapper will try to parse class name and extract group, kind and version from it.
Unfortunately, if class representing custom resource doesn't start with one of the prebuild versions, the null will be used for the version.
This will cause validation to fail in io.kubernetes.client.apimachinery.GroupVersion
.
Steps To Reproduce
Write a class representing Custom Resource and use the "unsupported" version in the class name.
Examples of problematic class names:
V2Setting
V1beta3Operation
V3Customer
Make a class implements KubernetesObject and try to instantiate new Informer for the class.
@Informer(
apiType = V2Setting.class,
apiListType = V2SettingList.class,
apiGroup = "org.foo.bar",
resourcePlural = "settings",
namespace = "default")
or directly using SharedInformerFactory
factory.sharedIndexInformerFor(
V2Setting.class,
V2SettingList.class,
"settings",
"org.foo.bar",
"default",
null,
null,
true
);
Environment Information
OS: Windows 11 / WSL 2 (Ubuntu)
$ java -version
openjdk version "17.0.8.1" 2023-08-24
OpenJDK Runtime Environment Temurin-17.0.8.1+1 (build 17.0.8.1+1)
OpenJDK 64-Bit Server VM Temurin-17.0.8.1+1 (build 17.0.8.1+1, mixed mode, sharing)
mvn --version
Apache Maven 3.9.4 (dfbb324ad4a7c8fb0bf182e6d91b0ae20e3d2dd9)
Maven home: /home/user/.sdkman/candidates/maven/current
Java version: 17.0.8.1, vendor: Eclipse Adoptium, runtime: /home/user/.sdkman/candidates/java/17.0.8.1-tem
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "5.15.90.1-microsoft-standard-wsl2", arch: "amd64", family: "unix"
mn --version
Micronaut Version: 4.1.1
Example Application
No response
Version
4.1.1