From cd11a374a115ee8efd7c927c16c24869a405535e Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 24 Nov 2021 10:17:37 +0100 Subject: [PATCH 1/5] docs: readme and java doc --- README.md | 234 ++++++++---------- docs/documentation/use-samples.md | 176 +++++++------ .../api/reconciler/ErrorStatusHandler.java | 8 +- .../reconciler/EventSourceInitializer.java | 4 +- .../operator/api/reconciler/RetryInfo.java | 8 +- .../api/reconciler/UpdateControl.java | 7 +- 6 files changed, 213 insertions(+), 224 deletions(-) diff --git a/README.md b/README.md index 790169d036..b211f563d8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Build Kubernetes Operators in Java without hassle. Inspired by [operator-sdk](https://github.com/operator-framework/operator-sdk). -Our webpage with documentation is getting better every day: https://javaoperatorsdk.io/ +Our webpage with documentation is getting better every day: https://javaoperatorsdk.io/ Table of Contents ========== @@ -23,11 +23,13 @@ Table of Contents * Automatic registration of Custom Resource watches * Retry action on failure * Smart event scheduling (only handle the latest event for the same resource) +* Handling Observed Generations automatically +* for all see [features](https://javaoperatorsdk.io/docs/features) section on the webpage Check out this [blog post](https://csviri.medium.com/deep-dive-building-a-kubernetes-operator-sdk-for-java-developers-5008218822cb) -about the non-trivial yet common problems needed to be solved for every operator. In case you are -interested how to handle more complex scenarios take a look +about the non-trivial yet common problems needed to be solved for every operator. In case you are interested how to +handle more complex scenarios take a look on [event sources](https://csviri.medium.com/java-operator-sdk-introduction-to-event-sources-a1aab5af4b7b) . @@ -40,22 +42,16 @@ on [event sources](https://csviri.medium.com/java-operator-sdk-introduction-to-e * Integration with Cloud services - e.g. Secret stores * Safer deployment of applications - only expose cluster to users by Custom Resources -## Roadmap and Release Notes - -* Testing of the framework and all samples while running on a real cluster. -* Generate a project skeleton -* Generate Java classes from CRD -* Integrate with OLM (Operator Lifecycle Manager) - #### Overview of the 1.9.0 changes - The Spring Boot starters have been moved to their own repositories and are now found at: - https://github.com/java-operator-sdk/operator-framework-spring-boot-starter - https://github.com/java-operator-sdk/operator-framework-spring-boot-starter-test - Updated Fabric8 client to version 5.4.0 -- It is now possible to configure the controllers to not automatically add finalizers to resources. - See the `Controller` annotation documentation for more details. -- Added the possibility to configure how many seconds the SDK will wait before terminating reconciliation threads when a shut down is requested +- It is now possible to configure the controllers to not automatically add finalizers to resources. See the `Controller` + annotation documentation for more details. +- Added the possibility to configure how many seconds the SDK will wait before terminating reconciliation threads when a + shut down is requested #### Overview of the 1.8.0 changes @@ -65,28 +61,26 @@ on [event sources](https://csviri.medium.com/java-operator-sdk-introduction-to-e ##### Overview of the 1.7.0 changes - `Doneable` classes have been removed along with all the involved complexity -- `Controller` annotation has been simplified: the `crdName` field has been removed as that value is - computed from the associated custom resource implementation +- `Controller` annotation has been simplified: the `crdName` field has been removed as that value is computed from the + associated custom resource implementation - Custom Resource implementation classes now need to be annotated with `Group` and `Version` annotations so that they can be identified properly. Optionally, they can also be annotated with - `Kind` (if the name of the implementation class doesn't match the desired kind) and `Plural` if - the plural version cannot be automatically computed (or the default computed version doesn't match - your expectations). -- The `CustomResource` class that needs to be extended is now parameterized with spec and status - types, so you can have an empty default implementation that does what you'd expect. If you don't - need a status, using `Void` for the associated type should work. -- Custom Resources that are namespace-scoped need to implement the `Namespaced` interface so that - the client can generate the proper URLs. This means, in particular, that `CustomResource` - implementations that do **not** implement `Namespaced` are considered cluster-scoped. As a - consequence, the `isClusterScoped` method/field has been removed from the appropriate - classes (`Controller` annotation, in particular) as this is now inferred from the `CustomResource` + `Kind` (if the name of the implementation class doesn't match the desired kind) and `Plural` if the plural version + cannot be automatically computed (or the default computed version doesn't match your expectations). +- The `CustomResource` class that needs to be extended is now parameterized with spec and status types, so you can have + an empty default implementation that does what you'd expect. If you don't need a status, using `Void` for the + associated type should work. +- Custom Resources that are namespace-scoped need to implement the `Namespaced` interface so that the client can + generate the proper URLs. This means, in particular, that `CustomResource` + implementations that do **not** implement `Namespaced` are considered cluster-scoped. As a consequence, + the `isClusterScoped` method/field has been removed from the appropriate classes (`Controller` annotation, in + particular) as this is now inferred from the `CustomResource` type associated with your `Controller`. -Many of these changes might not be immediately apparent but will result in `404` errors when -connecting to the cluster. Please check that the Custom Resource implementations are properly -annotated and that the value corresponds to your CRD manifest. If the namespace appear to be missing -in your request URL, don't forget that namespace-scoped Custom Resources need to implement -the `Namescaped` interface. +Many of these changes might not be immediately apparent but will result in `404` errors when connecting to the cluster. +Please check that the Custom Resource implementations are properly annotated and that the value corresponds to your CRD +manifest. If the namespace appear to be missing in your request URL, don't forget that namespace-scoped Custom Resources +need to implement the `Namescaped` interface. ## Join us on Discord! @@ -94,17 +88,15 @@ the `Namescaped` interface. ## Usage -We have several sample Operators under the [samples](samples) directory: +We have several simple Operators under the [smoke-test-samples](smoke-test-samples) directory: -* *pure-java*: Minimal Operator implementation which only parses the Custom Resource and prints to - stdout. Implemented with and without Spring Boot support. The two samples share the common module. +* *pure-java*: Minimal Operator implementation which only parses the Custom Resource and prints to stdout. Implemented + with and without Spring Boot support. The two samples share the common module. * *spring-boot-plain*: Sample showing integration with Spring Boot. -There are also more samples in the -standalone [samples repo](https://github.com/java-operator-sdk/samples): +There are also more complete samples in the standalone [sample-operators](sample-operators): -* *webserver*: Simple example creating an NGINX webserver from a Custom Resource containing HTML - code. +* *webserver*: Simple example creating an NGINX webserver from a Custom Resource containing HTML code. * *mysql-schema*: Operator managing schemas in a MySQL database. * *tomcat*: Operator with two controllers, managing Tomcat instances and Webapps for these. @@ -113,14 +105,14 @@ Add [dependency](https://search.maven.org/search?q=a:operator-framework) to your ```xml - io.javaoperatorsdk - operator-framework - {see https://search.maven.org/search?q=a:operator-framework for latest version} + io.javaoperatorsdk + operator-framework + {see https://search.maven.org/search?q=a:operator-framework for latest version} ``` -Or alternatively with Gradle, which also requires declaring the SDK as an annotation processor to -generate the mappings between controllers and custom resource classes: +Or alternatively with Gradle, which also requires declaring the SDK as an annotation processor to generate the mappings +between controllers and custom resource classes: ```groovy dependencies { @@ -129,16 +121,16 @@ dependencies { } ``` -Once you've added the dependency, define a main method initializing the Operator and registering a -controller. +Once you've added the dependency, define a main method initializing the Operator and registering a controller. ```java public class Runner { - public static void main(String[] args) { - Operator operator = new Operator(DefaultConfigurationService.instance()); - operator.register(new WebServerController()); - } + public static void main(String[] args) { + Operator operator = new Operator(DefaultConfigurationService.instance()); + operator.register(new WebPageReconciler()); + operator.start(); + } } ``` @@ -147,15 +139,15 @@ The Controller implements the business logic and describes all the classes neede ```java @ControllerConfiguration -public class WebServerController implements ResourceController { - - // Return the changed resource, so it gets updated. See javadoc for details. - @Override - public UpdateControl createOrUpdateResource(CustomService resource, - Context context) { - // ... your logic ... - return UpdateControl.updateStatusSubResource(resource); - } +public class WebServerController implements Reconciler { + + // Return the changed resource, so it gets updated. See javadoc for details. + @Override + public UpdateControl reconcile(CustomService resource, + Context context) { + // ... your logic ... + return UpdateControl.updateStatus(resource); + } } ``` @@ -165,52 +157,50 @@ A sample custom resource POJO representation @Group("sample.javaoperatorsdk") @Version("v1") -public class WebServer extends CustomResource implements - Namespaced { +public class WebPage extends CustomResource implements + Namespaced { } -public class WebServerSpec { +public class WebPageSpec { - private String html; + private String html; - public String getHtml() { - return html; - } + public String getHtml() { + return html; + } - public void setHtml(String html) { - this.html = html; - } + public void setHtml(String html) { + this.html = html; + } } ``` ### Deactivating CustomResource implementations validation The operator will, by default, query the deployed CRDs to check that the `CustomResource` -implementations match what is known to the cluster. This requires an additional query to the cluster -and, sometimes, elevated privileges for the operator to be able to read the CRDs from the cluster. -This validation is mostly meant to help users new to operator development get started and avoid -common mistakes. Advanced users or production deployments might want to skip this step. This is done -by setting the `CHECK_CRD_ENV_KEY` environment variable to `false`. +implementations match what is known to the cluster. This requires an additional query to the cluster and, sometimes, +elevated privileges for the operator to be able to read the CRDs from the cluster. This validation is mostly meant to +help users new to operator development get started and avoid common mistakes. Advanced users or production deployments +might want to skip this step. This is done by setting the `CHECK_CRD_ENV_KEY` environment variable to `false`. ### Automatic generation of CRDs -To automatically generate CRD manifests from your annotated Custom Resource classes, you only need -to add the following dependencies to your project: +To automatically generate CRD manifests from your annotated Custom Resource classes, you only need to add the following +dependencies to your project: ```xml - io.fabric8 - crd-generator-apt - provided + io.fabric8 + crd-generator-apt + provided ``` -The CRD will be generated in `target/classes/META-INF/fabric8` (or -in `target/test-classes/META-INF/fabric8`, if you use the `test` scope) with the CRD name suffixed -by the generated spec version. For example, a CR using the `java-operator-sdk.io` group with -a `mycrs` plural form will result in 2 files: +The CRD will be generated in `target/classes/META-INF/fabric8` (or in `target/test-classes/META-INF/fabric8`, if you use +the `test` scope) with the CRD name suffixed by the generated spec version. For example, a CR using +the `java-operator-sdk.io` group with a `mycrs` plural form will result in 2 files: - `mycrs.java-operator-sdk.io-v1.yml` - `mycrs.java-operator-sdk.io-v1beta1.yml` @@ -220,8 +210,7 @@ a `mycrs` plural form will result in 2 files: ### Quarkus -A [Quarkus](https://quarkus.io) extension is also provided to ease the development of Quarkus-based -operators. +A [Quarkus](https://quarkus.io) extension is also provided to ease the development of Quarkus-based operators. Add [this dependency](https://search.maven.org/search?q=a:quarkus-operator-sdk) to your project: @@ -229,55 +218,52 @@ to your project: ```xml - io.quarkiverse.operatorsdk - quarkus-operator-sdk - {see https://search.maven.org/search?q=a:quarkus-operator-sdk for latest version} - + io.quarkiverse.operatorsdk + quarkus-operator-sdk + {see https://search.maven.org/search?q=a:quarkus-operator-sdk for latest version} + ``` Create an Application, Quarkus will automatically create and inject a `KubernetesClient` ( -or `OpenShiftClient`), `Operator`, `ConfigurationService` and `ResourceController` instances that -your application can use. Below, you can see the minimal code you need to write to get your operator -and controllers up and running: +or `OpenShiftClient`), `Operator`, `ConfigurationService` and `ResourceController` instances that your application can +use. Below, you can see the minimal code you need to write to get your operator and controllers up and running: ```java @QuarkusMain public class QuarkusOperator implements QuarkusApplication { - @Inject - Operator operator; + @Inject + Operator operator; - public static void main(String... args) { - Quarkus.run(QuarkusOperator.class, args); - } + public static void main(String... args) { + Quarkus.run(QuarkusOperator.class, args); + } - @Override - public int run(String... args) throws Exception { - operator.start(); - Quarkus.waitForExit(); - return 0; - } + @Override + public int run(String... args) throws Exception { + operator.start(); + Quarkus.waitForExit(); + return 0; + } } ``` ### Spring Boot -You can also let Spring Boot wire your application together and automatically register the -controllers. +You can also let Spring Boot wire your application together and automatically register the controllers. -Add [this dependency](https://search.maven.org/search?q=a:operator-framework-spring-boot-starter) to -your project: +Add [this dependency](https://search.maven.org/search?q=a:operator-framework-spring-boot-starter) to your project: ```xml - io.javaoperatorsdk - operator-framework-spring-boot-starter - {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for - latest version} - + io.javaoperatorsdk + operator-framework-spring-boot-starter + {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for + latest version} + ``` @@ -288,25 +274,25 @@ Create an Application @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } ``` #### Spring Boot test support -Adding the following dependency would let you mock the operator for the tests where loading the -spring container is necessary, but it doesn't need real access to a Kubernetes cluster. +Adding the following dependency would let you mock the operator for the tests where loading the spring container is +necessary, but it doesn't need real access to a Kubernetes cluster. ```xml - io.javaoperatorsdk - operator-framework-spring-boot-starter-test - {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for - latest version} - + io.javaoperatorsdk + operator-framework-spring-boot-starter-test + {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for + latest version} + ``` @@ -318,8 +304,8 @@ Mock the operator: @EnableMockOperator public class SpringBootStarterSampleApplicationTest { - @Test - void contextLoads() { - } + @Test + void contextLoads() { + } } ``` diff --git a/docs/documentation/use-samples.md b/docs/documentation/use-samples.md index a736aabe49..c4d6f99533 100644 --- a/docs/documentation/use-samples.md +++ b/docs/documentation/use-samples.md @@ -5,20 +5,18 @@ layout: docs permalink: /docs/using-samples --- - # How to use sample Operators -We have several sample Operators under the [samples](https://github.com/java-operator-sdk/java-operator-sdk/tree/master/samples) directory: +We have several sample Operators under +the [samples](https://github.com/java-operator-sdk/java-operator-sdk/tree/master/smoke-test-samples) directory: -* *pure-java*: Minimal Operator implementation which only parses the Custom Resource and prints to - stdout. Implemented with and without Spring Boot support. The two samples share the common module. +* *pure-java*: Minimal Operator implementation which only parses the Custom Resource and prints to stdout. Implemented + with and without Spring Boot support. The two samples share the common module. * *spring-boot-plain*: Sample showing integration with Spring Boot. -There are also more samples in the -standalone [samples repo](https://github.com/java-operator-sdk/samples): +There are also more samples in the standalone [samples repo](https://github.com/java-operator-sdk/samples): -* *webserver*: Simple example creating an NGINX webserver from a Custom Resource containing HTML - code. +* *webserver*: Simple example creating an NGINX webserver from a Custom Resource containing HTML code. * *mysql-schema*: Operator managing schemas in a MySQL database. * *tomcat*: Operator with two controllers, managing Tomcat instances and Webapps for these. @@ -27,14 +25,14 @@ Add [dependency](https://search.maven.org/search?q=a:operator-framework) to your ```xml - io.javaoperatorsdk - operator-framework - {see https://search.maven.org/search?q=a:operator-framework for latest version} + io.javaoperatorsdk + operator-framework + {see https://search.maven.org/search?q=a:operator-framework for latest version} ``` -Or alternatively with Gradle, which also requires declaring the SDK as an annotation processor to -generate the mappings between controllers and custom resource classes: +Or alternatively with Gradle, which also requires declaring the SDK as an annotation processor to generate the mappings +between controllers and custom resource classes: ```groovy dependencies { @@ -43,16 +41,16 @@ dependencies { } ``` -Once you've added the dependency, define a main method initializing the Operator and registering a -controller. +Once you've added the dependency, define a main method initializing the Operator and registering a controller. ```java public class Runner { - public static void main(String[] args) { - Operator operator = new Operator(DefaultConfigurationService.instance()); - operator.register(new WebServerController()); - } + public static void main(String[] args) { + Operator operator = new Operator(DefaultConfigurationService.instance()); + operator.register(new WebServerController()); + operator.start(); + } } ``` @@ -61,15 +59,15 @@ The Controller implements the business logic and describes all the classes neede ```java @Controller -public class WebServerController implements ResourceController { - - // Return the changed resource, so it gets updated. See javadoc for details. - @Override - public UpdateControl createOrUpdateResource(CustomService resource, - Context context) { - // ... your logic ... - return UpdateControl.updateStatusSubResource(resource); - } +public class WebServerController implements Reconciler { + + // Return the changed resource, so it gets updated. See javadoc for details. + @Override + public UpdateControl reconcile(CustomService resource, + Context context) { + // ... your logic ... + return UpdateControl.updateStatus(resource); + } } ``` @@ -80,51 +78,49 @@ A sample custom resource POJO representation @Group("sample.javaoperatorsdk") @Version("v1") public class WebServer extends CustomResource implements - Namespaced { + Namespaced { } public class WebServerSpec { - private String html; + private String html; - public String getHtml() { - return html; - } + public String getHtml() { + return html; + } - public void setHtml(String html) { - this.html = html; - } + public void setHtml(String html) { + this.html = html; + } } ``` ### Deactivating CustomResource implementations validation The operator will, by default, query the deployed CRDs to check that the `CustomResource` -implementations match what is known to the cluster. This requires an additional query to the cluster -and, sometimes, elevated privileges for the operator to be able to read the CRDs from the cluster. -This validation is mostly meant to help users new to operator development get started and avoid -common mistakes. Advanced users or production deployments might want to skip this step. This is done -by setting the `CHECK_CRD_ENV_KEY` environment variable to `false`. +implementations match what is known to the cluster. This requires an additional query to the cluster and, sometimes, +elevated privileges for the operator to be able to read the CRDs from the cluster. This validation is mostly meant to +help users new to operator development get started and avoid common mistakes. Advanced users or production deployments +might want to skip this step. This is done by setting the `CHECK_CRD_ENV_KEY` environment variable to `false`. ### Automatic generation of CRDs -To automatically generate CRD manifests from your annotated Custom Resource classes, you only need -to add the following dependencies to your project: +To automatically generate CRD manifests from your annotated Custom Resource classes, you only need to add the following +dependencies to your project: ```xml - io.fabric8 - crd-generator-apt - provided + io.fabric8 + crd-generator-apt + provided ``` -The CRD will be generated in `target/classes/META-INF/fabric8` (or -in `target/test-classes/META-INF/fabric8`, if you use the `test` scope) with the CRD name suffixed -by the generated spec version. For example, a CR using the `java-operator-sdk.io` group with -a `mycrs` plural form will result in 2 files: +The CRD will be generated in `target/classes/META-INF/fabric8` (or in `target/test-classes/META-INF/fabric8`, if you use +the `test` scope) with the CRD name suffixed by the generated spec version. For example, a CR using +the `java-operator-sdk.io` group with a `mycrs` plural form will result in 2 files: - `mycrs.java-operator-sdk.io-v1.yml` - `mycrs.java-operator-sdk.io-v1beta1.yml` @@ -134,8 +130,7 @@ a `mycrs` plural form will result in 2 files: ### Quarkus -A [Quarkus](https://quarkus.io) extension is also provided to ease the development of Quarkus-based -operators. +A [Quarkus](https://quarkus.io) extension is also provided to ease the development of Quarkus-based operators. Add [this dependency](https://search.maven.org/search?q=a:quarkus-operator-sdk) to your project: @@ -143,55 +138,52 @@ to your project: ```xml - io.quarkiverse.operatorsdk - quarkus-operator-sdk - {see https://search.maven.org/search?q=a:quarkus-operator-sdk for latest version} - + io.quarkiverse.operatorsdk + quarkus-operator-sdk + {see https://search.maven.org/search?q=a:quarkus-operator-sdk for latest version} + ``` Create an Application, Quarkus will automatically create and inject a `KubernetesClient` ( -or `OpenShiftClient`), `Operator`, `ConfigurationService` and `ResourceController` instances that -your application can use. Below, you can see the minimal code you need to write to get your operator -and controllers up and running: +or `OpenShiftClient`), `Operator`, `ConfigurationService` and `ResourceController` instances that your application can +use. Below, you can see the minimal code you need to write to get your operator and controllers up and running: ```java @QuarkusMain public class QuarkusOperator implements QuarkusApplication { - @Inject - Operator operator; + @Inject + Operator operator; - public static void main(String... args) { - Quarkus.run(QuarkusOperator.class, args); - } + public static void main(String... args) { + Quarkus.run(QuarkusOperator.class, args); + } - @Override - public int run(String... args) throws Exception { - operator.start(); - Quarkus.waitForExit(); - return 0; - } + @Override + public int run(String... args) throws Exception { + operator.start(); + Quarkus.waitForExit(); + return 0; + } } ``` ### Spring Boot -You can also let Spring Boot wire your application together and automatically register the -controllers. +You can also let Spring Boot wire your application together and automatically register the controllers. -Add [this dependency](https://search.maven.org/search?q=a:operator-framework-spring-boot-starter) to -your project: +Add [this dependency](https://search.maven.org/search?q=a:operator-framework-spring-boot-starter) to your project: ```xml - io.javaoperatorsdk - operator-framework-spring-boot-starter - {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for - latest version} - + io.javaoperatorsdk + operator-framework-spring-boot-starter + {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for + latest version} + ``` @@ -202,25 +194,25 @@ Create an Application @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } ``` #### Spring Boot test support -Adding the following dependency would let you mock the operator for the tests where loading the -spring container is necessary, but it doesn't need real access to a Kubernetes cluster. +Adding the following dependency would let you mock the operator for the tests where loading the spring container is +necessary, but it doesn't need real access to a Kubernetes cluster. ```xml - io.javaoperatorsdk - operator-framework-spring-boot-starter-test - {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for - latest version} - + io.javaoperatorsdk + operator-framework-spring-boot-starter-test + {see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter for + latest version} + ``` @@ -232,8 +224,8 @@ Mock the operator: @EnableMockOperator public class SpringBootStarterSampleApplicationTest { - @Test - void contextLoads() { - } + @Test + void contextLoads() { + } } ``` diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusHandler.java index 578d3ff8a6..2d5592053b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusHandler.java @@ -10,10 +10,10 @@ public interface ErrorStatusHandler { * when the last reconciliation retry attempt is failed on the Reconciler. In that case the * updateErrorStatus is called automatically. *

- * The result of the method call is used to make a status sub-resource update on the custom - * resource. This is always a sub-resource update request, so no update on custom resource itself - * (like spec of metadata) happens. Note that this update request will also produce an event, and - * will result in a reconciliation if the controller is not generation aware. + * The result of the method call is used to make a status update on the custom resource. This is + * always a sub-resource update request, so no update on custom resource itself (like spec of + * metadata) happens. Note that this update request will also produce an event, and will result in + * a reconciliation if the controller is not generation aware. *

* Note that the scope of this feature is only the reconcile method of the reconciler, since there * should not be updates on custom resource after it is marked for deletion. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java index b568814739..5a23e0da16 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java @@ -6,8 +6,8 @@ public interface EventSourceInitializer { /** - * In this typically you might want to register event sources. But can access - * CustomResourceEventSource, what might be handy for some edge cases. + * Reconciler can implement this interface typically to register event sources. But can access + * CustomResourceEventSource, what might be useful for some edge cases. * * @param eventSourceRegistry the {@link EventSourceRegistry} where event sources can be * registered. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java index 2525bde192..f746c20dce 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java @@ -1,8 +1,14 @@ package io.javaoperatorsdk.operator.api.reconciler; public interface RetryInfo { - + /** + * @return current retry attempt count. 0 if the current execution is not a retry. + */ int getAttemptCount(); + /** + * @return true, if the current attempt is the last one in regard to the retry limit + * configuration. + */ boolean isLastAttempt(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java index 1affc25abd..c388958a8a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java @@ -19,6 +19,11 @@ private UpdateControl( this.updateResource = updateResource; } + /** + * Creates an update control instance that instructs the framework to do an update on resource + * itself, not on the status. Note that usually as a results of a reconciliation should be a + * status update not an update to the resource itself. + */ public static UpdateControl updateResource(T customResource) { return new UpdateControl<>(customResource, false, true); } @@ -31,7 +36,7 @@ public static UpdateControl updateStatus( /** * As a results of this there will be two call to K8S API. First the custom resource will be * updates then the status sub-resource. - * + * * @param resource type * @param customResource - custom resource to use in both API calls * @return UpdateControl instance From ea98383df851cac0f6eacaae75e53be592ddb2ee Mon Sep 17 00:00:00 2001 From: csviri Date: Thu, 25 Nov 2021 14:43:55 +0100 Subject: [PATCH 2/5] docs: features improvements for v2 --- docs/documentation/features.md | 133 ++++++++++++++++---------- docs/documentation/getting-started.md | 2 +- 2 files changed, 83 insertions(+), 52 deletions(-) diff --git a/docs/documentation/features.md b/docs/documentation/features.md index d281fd1a22..194effb36e 100644 --- a/docs/documentation/features.md +++ b/docs/documentation/features.md @@ -11,21 +11,21 @@ Java Operator SDK is a high level framework and related tooling in order to faci operators. The features are by default following the best practices in an opinionated way. However, feature flags and other configuration options are provided to fine tune or turn off these features. -## Controller Execution in a Nutshell +## Reconciliation Execution in a Nutshell -Controller execution is always triggered by an event. Events typically come from the custom resource +Reconciliation execution is always triggered by an event. Events typically come from the custom resource (i.e. custom resource is created, updated or deleted) that the controller is watching, but also from different sources (see event sources). When an event is received reconciliation is executed, unless there is already a reconciliation happening for a particular custom resource. In other words it is guaranteed by the framework that no concurrent reconciliation happens for a custom resource. After a reconciliation ( -i.e. [ResourceController](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java) +i.e. [Reconciler](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java) called, a post-processing phase follows, where typically framework checks if: - an exception was thrown during execution, if yes schedules a retry. - there are new events received during the controller execution, if yes schedule the execution again. -- there is an instruction to re-schedule the execution for the future, if yes schedule a timer event with the specified +- there is an instruction to re-schedule the execution for the future, if yes schedules a timer event with the specified delay. - if none above, the reconciliation is finished. @@ -36,108 +36,138 @@ execution. [Kubernetes finalizers](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/) make sure that a reconciliation happens when a custom resource is instructed to be deleted. Typical case when it's -useful, when an operator is down (pod not running). Without a finalizer the reconciliation - thus the cleanup -i.e. [`Reconciler.cleanup(...)`](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java) +useful, when an operator is down (pod not running). Without a finalizer the reconciliation - thus the cleanup - +i.e. [`Reconciler.cleanup(...)`](https://github.com/java-operator-sdk/java-operator-sdk/blob/b91221bb54af19761a617bf18eef381e8ceb3b4c/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java#L31) +would not happen if a custom resource is deleted. -- would not happen if a custom resource is deleted. - -Finalizers are automatically added by the framework as the first step, thus when a custom resource is created, but -before the first reconciliation, the custom resource is updated via a Kubernetes API call. As a result of this update, +Finalizers are automatically added by the framework as the first step, thus after a custom resource is created, but +before the first reconciliation. The finalizer is added via a separate Kubernetes API call. As a result of this update, the finalizer will be present. The subsequent event will be received, which will trigger the first reconciliation. -The finalizer that is automatically added will be also removed after the `deleteResource` is executed on the -controllerConfiguration. However, the removal behavior can be further customized, and can be instructed to "not remove -yet" - this is useful just in some specific corner cases, when there would be a long waiting period for some dependent -resource cleanup. +The finalizer that is automatically added will be also removed after the `cleanup` is executed on the reconciler. +However, the removal behavior can be further customized, and can be instructed to "not remove yet" - this is useful just +in some specific corner cases, when there would be a long waiting period for some dependent resource cleanup. The name of the finalizers can be specified, in case it is not, a name will be generated. -This behavior can be turned off, so when configured no finalizer will be added or removed. +Automatic finalizer handling can be turned off, so when configured no finalizer will be added or removed. See [`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ControllerConfiguration.java) annotation for more details. ### When not to Use Finalizers? -Typically, automated finalizer handling should be turned off, in case **all** the cleanup of the dependent resources is +Typically, automated finalizer handling should be turned off, in case the cleanup of **all** the dependent resources is handled by Kubernetes itself. This is handled by Kubernetes [garbage collection](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#owners-dependents). -Setting the owner reference and related fields are not in the scope of the SDK for now, it's up to the user to have them -configured properly when creating the objects. +Setting the owner reference and related fields are not in the scope of the SDK, it's up to the user to have them set +properly when creating the objects. -When automatic finalizer handling is turned off, the `ResourceController.deleteResource(...)` method is not called, in -case of a delete event received. So it does not make sense to implement this method and turn off finalizer at the same +When automatic finalizer handling is turned off, the `Reconciler.cleanup(...)` method is not called at all. Not even in +case when a delete event received. So it does not make sense to implement this method and turn off finalizer at the same time. ## The `reconcile` and `cleanup` Methods of `Reconciler` The lifecycle of a custom resource can be clearly separated to two phases from a perspective of an operator. When a -custom resource is created or update, or on the other hand when the custom resource is deleted - or rater marked for +custom resource is created or update, or on the other hand when the custom resource is deleted - or rather marked for deletion in case a finalizer is used. -There is no point to make a distinction between create and update, since the reconciliation logic typically would be -very similar or identical in most of the cases. - -This separation related logic is automatically handled by framework. The framework will always -call `createOrUpdateResource` -function, unless the custom resource is +This separation related logic is automatically handled by framework. The framework will always call `reconcile` +method, unless the custom resource is [marked from deletion](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/#how-finalizers-work) -. From the point when the custom resource is marked from deletion, only the `deleteResource` method is called. +. From the point when the custom resource is marked from deletion, only the `cleanup` method is called. -If there is **no finalizer** in place (see Finalizer Support section), the `deleteResource` method is **not called**. +If there is **no finalizer** in place (see Finalizer Support section), the `cleanup` method is **not called**. ### Using `UpdateControl` and `DeleteControl` -These two methods are used to control the outcome or the desired behavior after the reconciliation. +These two classes are used to control the outcome or the desired behavior after the reconciliation. -The `UpdateControl` can instruct the framework to update the custom resource status sub-resource and/or re-schedule a +The `UpdateControl` can instruct the framework to update the status sub-resource of the resource and/or re-schedule a reconciliation with a desired time delay. Those are the typical use cases, however in some cases there it can happen that the controller wants to update the custom resource itself (like adding annotations) or not to do any updates, which -are also supported. +is also supported. It is also possible to update both the status and the custom resource with `updateCustomResourceAndStatus` method. In this case first the custom resource is updated then the status in two separate requests to K8S API. Always update the custom resource with `UpdateControl`, not with the actual kubernetes client if possible. -On custom resource updates there is always an optimistic version control in place, to make sure that another update is -not overwritten (by setting `resourceVersion` ) . +On resource updates there is always an optimistic version control in place, to make sure that another update is not +overwritten (by setting `resourceVersion` ) . The `DeleteControl` typically instructs the framework to remove the finalizer after the dependent resource are cleaned -up in `deleteResource` implementation. +up in `cleanup` implementation. However, there is a possibility to not remove the finalizer, this allows to clean up the resources in a more async way, mostly for the cases when there is a long waiting period after a delete operation is initiated. Note that in this case you might want to either schedule a timed event to make sure the `deleteResource` is executed again or use event sources get notified about the state changes of a deleted resource. -## Automatic Observed Generation Handling +## Generation Awareness and Automatic Observed Generation Handling + +Having `.observedGeneration` value on the status of the resource is a best practice to indicate the last generation of +the resource reconciled successfully by the controller. This helps the users / administrators to check if the custom +resource was reconciled, but it is used to decide if a reconciliation should happen or not. Filtering events based on +generation is supported by the framework and turned on by default. There are two modes. + +The first and the **preferred** one is to check after a resource event received, if the generation of the resource is +larger than the `.observedGeneration` field on status. In order to have this feature working: + +- the **status class** (not the resource) must implement the + [`ObservedGenerationAware`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAware.java) + interface. See also + the [`ObservedGenerationAwareStatus`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAwareStatus.java) + which can be also extended. +- The other condition is that the `CustomResource.getStatus()` method should not return `null` + , but an instance of the class representing `status`. The best way to achieve this is to + override [`CustomResource.initStatus()`](https://github.com/fabric8io/kubernetes-client/blob/865e0ddf67b99f954aa55ab14e5806d53ae149ec/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/CustomResource.java#L139). + +If these conditions are fulfilled and generation awareness not turned off, the observed generation is automatically set +by the framework after the `reconcile` method is called. There is just one exception, when the reconciler returns +with `UpdateControl.updateResource`, in this case the status is not updated, just the custom resource - however, this +update will lead to a new reconciliation. Note that the observed generation is updated also +when `UpdateControl.noUpdate()` is returned from the reconciler. See this feature working in +the [WebPage example](https://github.com/java-operator-sdk/java-operator-sdk/blob/b91221bb54af19761a617bf18eef381e8ceb3b4c/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStatus.java#L5) +. + +The second, fallback mode is (when the conditions from above are not met to handle the observed generation automatically +in status) to handled generation filtering in memory. Thus, if an event is received, the generation of the received +resource is compared with the resource in the cache. + +Note that the **first approach has significant benefits** in the situation when the operator is restarted and there is +no cached resource anymore. In case two this leads to a reconciliation of every resource, event if the resource is not +changed while the operator was not running. ## Support for Well Known (non-custom) Kubernetes Resources A Controller can be registered for a non-custom resource, so well known Kubernetes resources like ( -Ingress,Deployment,...). Note that automatic observed generation handling is not supported for these resources. +Ingress,Deployment,...). Note that automatic observed generation handling is not supported for these resources. Although +in case adding a secondary controller for well known k8s resource, probably the observed generation should be handled by +the primary controller. ## Automatic Retries on Error When an exception is thrown from a controller, the framework will schedule an automatic retry of the reconciliation. The retry is behavior is configurable, an implementation is provided that should cover most of the use-cases, see [GenericRetry](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetry.java) -But it is possible to provide a custom implementation. +. But it is possible to provide a custom implementation. It is possible to set a limit on the number of retries. In the [Context](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Context.java) -object information is provided about the retry, particularly interesting is the `isLastAttempt`, since a behavior could -be implemented bases on this flag. Like setting an error message in the status in case of a last attempt; +object information is provided about the retry, particularly interesting is the `isLastAttempt`, since a different +behavior could be implemented bases on this flag. Like setting an error message in the status in case of a last attempt; Event if the retry reached a limit, in case of a new event is received the reconciliation would happen again, it's just -won't be a result of a retry, but the new event. +won't be a result of a retry, but the new event. However, in case of an error happens also in this case, it won't +schedule a retry is at this point the retry limit is already reached. A successful execution resets the retry. ### Setting Error Status After Last Retry Attempt In order to facilitate error reporting in case a last retry attempt fails, Reconciler can implement the following -interface: +[interface](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusHandler.java): ```java public interface ErrorStatusHandler> { @@ -150,13 +180,12 @@ public interface ErrorStatusHandler> { The `updateErrorStatus` resource is called when it's the last retry attempt according the retry configuration and the reconciler execution still resulted in a runtime exception. -The result of the method call is used to make a status sub-resource update on the custom resource. This is always a -sub-resource update request, so no update on custom resource itself (like spec of metadata) happens. Note that this -update request will also produce an event, and will result in a reconciliation if the controller is not generation -aware. +The result of the method call is used to make a status update on the custom resource. This is always a sub-resource +update request, so no update on custom resource itself (like spec of metadata) happens. Note that this update request +will also produce an event, and will result in a reconciliation if the controller is not generation aware. -Note that the scope of this feature is only the `reconcile` method of the reconciler, since there should not be updates -on custom resource after it is marked for deletion. +The scope of this feature is only the `reconcile` method of the reconciler, since there should not be updates on custom +resource after it is marked for deletion. ### Correctness and Automatic Retries @@ -175,7 +204,7 @@ explicitly by `UpdateControl`, see method: `public UpdateControl rescheduleAfter(long delay, TimeUnit timeUnit)`. This would schedule a reconciliation for the future. -## Retry and Rescheduling and Unrelated Event Handling Common Behavior +## Retry and Rescheduling and Event Handling Common Behavior Retry, reschedule and standard event processing forms a relatively complex system, where these functionalities are not independent of each other. In the following we describe the behavior in this section, so it is easier to understand the @@ -183,11 +212,11 @@ intersections: 1. A successful execution resets a retry and the rescheduled executions which were present before the reconciliation. However, a new rescheduling can be instructed from the reconciliation outcome (`UpdateControl` or `DeleteControl`). -2. In case an exception happened, and a retry is initiated, but an event received meanwhile the reconciliation will be +2. In case an exception happened, and a retry is initiated, but an event received meanwhile, then reconciliation will be executed instantly, and this execution won't count as a retry attempt. 3. If the retry limit is reached (so no more automatic retry would happen), but a new event received, the reconciliation will still happen, but won't reset the retry, will be still marked as the last attempt in the retry info. The point - 1. holds, but in case of an error, no retry will happen. + (1) still holds, but in case of an error, no retry will happen. ## Handling Related Events with Event Sources @@ -220,6 +249,8 @@ we could read the object again from Kubernetes API. However since we watch for t receive the most up-to-date version in the Event Source. So naturally, what we can do is cache the latest received objects (in the Event Source) and read it from there if needed. +### Implementing and EventSource + ### Built-in Event Sources 1. InformerEventSource - used to get event about other K8S resources, also provides a local cache for them. diff --git a/docs/documentation/getting-started.md b/docs/documentation/getting-started.md index 3ca64df871..04f9b68b7d 100644 --- a/docs/documentation/getting-started.md +++ b/docs/documentation/getting-started.md @@ -10,7 +10,7 @@ permalink: /docs/getting-started ## Introduction & Resources on Operators Operators are easy and simple way to manage resource on Kubernetes clusters but -also outside of the cluster. The goal of this SDK is to allow writing operators in Java by +also outside the cluster. The goal of this SDK is to allow writing operators in Java by providing a nice API and handling common issues regarding the operators on framework level. For an introduction, what is an operator see this [blog post](https://blog.container-solutions.com/kubernetes-operators-explained). From dfa164c30b6b407262db363282b3e06e302d7026 Mon Sep 17 00:00:00 2001 From: csviri Date: Thu, 25 Nov 2021 15:31:48 +0100 Subject: [PATCH 3/5] docs: migration to v2 --- docs/_data/sidebar.yml | 2 ++ docs/documentation/patterns-best-practices.md | 4 ++-- docs/documentation/v2-migration.md | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 docs/documentation/v2-migration.md diff --git a/docs/_data/sidebar.yml b/docs/_data/sidebar.yml index a9a43907a2..3304718cc5 100644 --- a/docs/_data/sidebar.yml +++ b/docs/_data/sidebar.yml @@ -13,4 +13,6 @@ url: /docs/faq - title: Contributing url: /docs/contributing + - title: Migrating to v2 + url: /docs/v2-migration diff --git a/docs/documentation/patterns-best-practices.md b/docs/documentation/patterns-best-practices.md index c5103de3ff..13de8ae910 100644 --- a/docs/documentation/patterns-best-practices.md +++ b/docs/documentation/patterns-best-practices.md @@ -12,10 +12,10 @@ of Java Operator SDK. ## Implementing a Controller -### Sync of Async Way of Resource Handling - ### Idempotency +### Sync of Async Way of Resource Handling + ## Why to Have Automated Retries? ## Managing State diff --git a/docs/documentation/v2-migration.md b/docs/documentation/v2-migration.md new file mode 100644 index 0000000000..ca1895b4da --- /dev/null +++ b/docs/documentation/v2-migration.md @@ -0,0 +1,9 @@ +--- +title: Migrating to v2 +description: Migration to v2 +layout: docs +permalink: /docs/v2-migration +--- + +# Migrating to v2 + From 49a534a3d953cf00b738c5be78adc7e6e64be172 Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 26 Nov 2021 11:44:04 +0100 Subject: [PATCH 4/5] docs: migration guide --- docs/_data/sidebar.yml | 2 +- docs/documentation/use-samples.md | 2 +- docs/documentation/v2-migration.md | 50 ++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/docs/_data/sidebar.yml b/docs/_data/sidebar.yml index 3304718cc5..4963e97be1 100644 --- a/docs/_data/sidebar.yml +++ b/docs/_data/sidebar.yml @@ -13,6 +13,6 @@ url: /docs/faq - title: Contributing url: /docs/contributing - - title: Migrating to v2 + - title: Migrating from v1 to v2 url: /docs/v2-migration diff --git a/docs/documentation/use-samples.md b/docs/documentation/use-samples.md index c4d6f99533..04988c076e 100644 --- a/docs/documentation/use-samples.md +++ b/docs/documentation/use-samples.md @@ -58,7 +58,7 @@ The Controller implements the business logic and describes all the classes neede ```java -@Controller +@ControllerConfiguration public class WebServerController implements Reconciler { // Return the changed resource, so it gets updated. See javadoc for details. diff --git a/docs/documentation/v2-migration.md b/docs/documentation/v2-migration.md index ca1895b4da..5a63a7b9ca 100644 --- a/docs/documentation/v2-migration.md +++ b/docs/documentation/v2-migration.md @@ -1,9 +1,53 @@ --- -title: Migrating to v2 -description: Migration to v2 +title: Migrating from v1 to v2 +description: Migrating from v1 to v2 layout: docs permalink: /docs/v2-migration --- -# Migrating to v2 +# Migrating from v1 to v2 +Version 2 of the framework introduces improvements, features and breaking changes for the APIs both internal and user +facing ones. The migration should be however trivial in most of the cases. For detailed overview of all major issues +until the release of +v`2.0.0` [see milestone on GitHub](https://github.com/java-operator-sdk/java-operator-sdk/milestone/1). For a summary +and reasoning behind some naming changes +see [this issue](https://github.com/java-operator-sdk/java-operator-sdk/issues/655) + +## User Facing API Changes + +The following items are renamed and slightly changed: + +- [`ResourceController`](https://github.com/java-operator-sdk/java-operator-sdk/blob/v1/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java) + interface is renamed + to [`Reconciler`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java) + . In addition, methods: + - `createOrUpdate` renamed to `reconcile` + - `delete` renamed to `cleanup` +- Events are removed from + the [`Context`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java) + of `Reconciler` methods . The rationale behind this, is that there is a consensus now on the pattern that the events + should not be used to implement a reconciliation logic. +- The `init` method is extracted from `ResourceController` / `Reconciler` to a separate interface + called [EventSourceInitializer](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java) + that `Reconcile` should implement in order to register event sources. See + also [sample](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java) + for usage. Here also + the [`EventSourceManager`](https://github.com/java-operator-sdk/java-operator-sdk/blob/v1/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java) + is renamed + to [`EventSourceRegistry`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSourceRegistry.java) + , and it's interface refined. +- [`@Controller`](https://github.com/java-operator-sdk/java-operator-sdk/blob/v1/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java) + annotation renamed + to [`@ControllerConfiguration`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java) + +### Event Sources + +- Addressing resources within event sources (and in the framework internally) is now changed from `.metadata.uid` to a + pair of `.metadata.name` and optional `.metadata.namespace` of resource. Represented + by [`ResourceID.`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java) +- The [`Event`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/Event.java) + API is simplified. Now if an event source produces an event it needs to just produce an instance of this class. +- [`EventSource`](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java) + is refactored, but the changes are trivial. + From ee7257305ab9cca45375fc5ce9d33a33ed3d138f Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 26 Nov 2021 12:03:02 +0100 Subject: [PATCH 5/5] docs: comment for v2 vs v1 branch --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b211f563d8..1aba79d50c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ by [operator-sdk](https://github.com/operator-framework/operator-sdk). Our webpage with documentation is getting better every day: https://javaoperatorsdk.io/ +**!! NOTE the main branch now contains source code for v2, which is under development, for actual +version see [v1 branch](https://github.com/java-operator-sdk/java-operator-sdk/tree/v1) !!** + Table of Contents ==========