Project: Fabric8 Kubernetes Client (App Definition and Development / Application Definition & Image Build)
File: MIGRATION-v5.md

[!NOTE] If you encounter any problems with the following "Migration from 4.x to 5.x" instructions, please let us know by creating an issue in our . We value your feedback and will work to address your issue promptly. Your contribution is essential to improving our documentation, making our migration process smoother for everyone! To reduce the number of classes generated by the client and the overall size of packages, interface, implementations, and implementation generator tasks have been removed. Provided `Doneable` implementations (especially for CustomResources) are no longer needed and can be safely removed. As a result of the `Doneable` interface removal, `createNew()` and `createOrReplaceWithNew()` methods are no longer available. Usages of these methods should be refactored to use the `create(Resource... item)` or `createOrReplace(Resource... item)` methods instead. ```java // Deprecated client.configMaps().inNamespace("default").createNew() .withNewMetadata().withName("config-map-name").endMetadata() .addToData("key", "value") .done(); // Alternative client.configMaps().inNamespace("default").create( new ConfigMapBuilder() .withNewMetadata().withName("config-map-name").endMetadata() .addToData("key", "value") .done(); ); // Deprecated client.configMaps().inNamespace("default").createOrReplaceWithNew() .withNewMetadata().withName("config-map-name").endMetadata() .addToData("key", "value") .done(); // Alternative client.configMaps().inNamespace("default").createOrReplaceWithNew( new ConfigMapBuilder() .withNewMetadata().withName("config-map-name").endMetadata() .addToData("key", "value") .done(); ); ``` As a result of the `Doneable` interface removal, `edit()` method is no longer available. The lambda "friendly" or the visitable approach methods should be used instead. ```java // Deprecated client.configMaps().inNamespace("default").withName("config-map-name").edit() .addToData("key-2", "value-2") done(); // Alternative client.configMaps().inNamespace("default").withName("config-map-name").edit( c -> new ConfigMapBuilder(c).addToData("key-2", "value-2").build() ); // Alternative with visitable approach client.configMaps().inNamespace("default").withName("config-map-name").edit( ObjectMetaBuilder.class, omb -> omb.addToAnnotations("key", "value") ); ``` `Watcher#onClose(KubernetesClientException cause)` method has been replaced by `Watcher#onClose(WatcherException cause)` and a new default `Watcher#onClose()` method has been added. The argument-less onClose method is always invoked upon Watcher completion, regardless if there is an exception or not. The `onClose` with exception argument is only invoked in case an exception occurs during the Watcher life-cycle (once the watch connection is open and established). For migration purposes, any onClose implementations resembling the following: ```java void onClose(KubernetesClientException cause) { if (cause != null) { // Do in case of exception } // Clean-up operations } ``` Should be refactored to: ```java void onClose(WatcherException cause) { // Do in case of exception } void onClose() { // Clean-up operations } ``` This release should be a drop-in replacement for v4 in terms of breaking changes. However, the new release includes many improvements that simplifies the usage of Custom Resources and Custom Resource Definitions in the client. Allows to specify which version of the API the annotated class is defined under. Together with `@Group`, this allows to determine the `apiVersion` field associated with the annotated resource. See https://kubernetes.io/docs/reference/using-api/#api-versioning for more details. Allows to specify which API group the annotated class is defined under. Together with `@Version`, this allows to determine the `apiVersion` field associated with the annotated resource. See https://kubernetes.io/docs/reference/using-api/#api-groups for more details. Allows to specify which `Kind` value should be used to refer to instance of the annotated class. If not provided, a default value is computed based on the annotated class name. See for more details. Allows to specify the singular name of the

Allows to specify the plural name of the resource to serve. The custom resources are served under `/apis/<group>/<version>/.../<plural>` The abstract class provides a default implementation for the convention fields `spec` and `status`. The class is now parameterized and the Types for these fields can be specified through the new Type parameters in the class. New `v1CRDFromCustomResourceType` and `v1beta1CRDFromCustomResourceType` methods have been introduced on `CustomResourceDefinitionContext` to initialize a `CustomResourceDefinitionBuilder` with the information provided by a specific `CustomResource` implementation. These methods simplify the creation of `CustomResourceDefinition`s by inferring the boiler-plate spec values from the annotations and other information already provided in the `CustomResource` implementation. We have added some minor improvements in shared informer APIs. Changes are as follows: No List type required in `SharedInformerFactory.sharedIndexInformerFor` and `SharedInformerFactory.sharedIndexInformerForCustomResource` methods. Now you don't need to provide any List type for creatinga new SharedIndexInformer. Now the method only accepts Type and resyncPeriod as parameter. Here is an example of 4.x and 5.x versions to give you a clear idea: 4.x: ```java SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor(Pod.class, PodList.class, resyncPeriod); ``` 5.x: ```java SharedIndexInformer<Pod> podInformer = factory.sharedIndexInformerFor(Pod.class, resyncPeriod); ``` `SharedInformerFactory.sharedIndexInformerForCustomResource` uses `CustomResource` as base type rather than `HasMetadata`. Although we're already enforcing this in our CustomResource API for your CustomResource POJOs to extend `CustomResource`; we've made this change more explicit in SharedInformer API. Utility methods for creating Namespaced Informers. Now you don't have to provide an explicit `OperationContext` for creating a Namespaced Informer. You can simply use `inNamespace()` method for configuring namespace in `SharedInformerFactory`. Here is an example: 4.x: ```java SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor( Pod.class, PodList.class, new OperationContext().withNamespace("default"), RESYNC_PERIOD); ``` 5.x: ```java SharedIndexInformer<Pod> podInformer = factory.inNamespace("default").sharedIndexInformerFor(Pod.class, RESYNC_PERIOD); ``` No need to provide `CustomResourceDefinitionContext` in `SharedInformerFactory.sharedIndexInformerForCustomResource`. `CustomResourceDefinition` related information is now discovered automatically from CustomResource annotations or opinionated defaults. Here is an example of 4.x and 5.x versions for a `CustomResource` called `Dummy`, we're trying to create SharedIndexInformers. 4.x Dummy.java ```java import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.CustomResource; public class Dummy extends CustomResource implements Namespaced { private DummySpec spec; @Override public String toString() { return "Dummy{" + "apiVersion='" + getApiVersion() + '\'' + ", metadata=" + getMetadata() + ", spec=" + spec + '}'; } public DummySpec getSpec() { return spec; } public void setSpec(DummySpec spec) { this.spec = spec; } @Override public ObjectMeta getMetadata() { return super.getMetadata(); } } ``` Create SharedIndexInformer for `Dummy`: ```java CustomResourceDefinitionContext crdContext = new CustomResourceDefinitionContext.Builder() .withVersion("v1") .withScope("Namespaced") .withGroup("demo.fabric8.io") .withPlural("dummies") .build(); SharedIndexInformer<Dummy> dummyInformer = sharedInformerFactory.sharedIndexInformerForCustomResource(crdContext, Dummy.class, DummyList.class, 60 * 1000L); ``` 5.x: Dummy.java ```java import io.fabric8.kubernetes.api.model.KubernetesResource; import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.model.annotation.Group; import io.fabric8.kubernetes.model.annotation.Version; @Version(Dummy.VERSION) @Group(Dummy.GROUP) public class Dummy extends CustomResource<DummySpec, KubernetesResource> implements Namespaced { public static final String GROUP = "demo.fabric8.io"; public static final String VERSION = "v1"; } ``` Create SharedIndexInformer for `Dummy`: ```java SharedIndexInformer<Dummy> dummyInformer = sharedInformerFactory.sharedIndexInformerForCustomResource(Dummy.class, 60 * 1000L); ``` `kube-validation-schema.json` files are no longer included in our model packaged. The equivalent file is now named `validation-schema.json`. The URL has been updated to the latest compatible (`http://json-schema.org/draft-05/schema#`)