diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a1ee4de399..936c95fb10 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -35,7 +35,7 @@ jobs: - name: Set up Minikube uses: manusa/actions-setup-minikube@v2.4.2 with: - minikube version: 'v1.22.0' + minikube version: 'v1.24.0' kubernetes version: ${{ matrix.kubernetes }} driver: 'docker' - name: Run integration tests diff --git a/DECISION_LOG.md b/DECISION_LOG.md deleted file mode 100644 index a81ad81d3b..0000000000 --- a/DECISION_LOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# Decision Log - - -## Event Sources - -### 1. Move Retries to an Abstract Controller. - -The original idea was to explicitly support retry in the scheduler. However, this turned out to complicate the algorithm -in case of event sources. Mostly it would be harder to manage the buffer, and the other event sources, thus what -does it mean for other event sources that there was a failed controller execution? Probably it would be better to -manage this in an abstract controller, and just use the "reprocess event-source" source in case of an error. - diff --git a/README.md b/README.md index d42c45b7a0..790169d036 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ The Controller implements the business logic and describes all the classes neede ```java -@Controller +@ControllerConfiguration public class WebServerController implements ResourceController { // Return the changed resource, so it gets updated. See javadoc for details. diff --git a/docs/documentation/features.md b/docs/documentation/features.md index 9913529c58..e89b5a5a0f 100644 --- a/docs/documentation/features.md +++ b/docs/documentation/features.md @@ -45,14 +45,14 @@ Finalizers are automatically added by the framework as the first step, thus when before the first reconciliation, the custom resource is updated via a 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 controller. +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 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. -See [`@Controller`](https://github.com/java-operator-sdk/java-operator-sdk/blob/master/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java) +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? diff --git a/docs/etc/v1_model.drawio.svg b/docs/etc/v1_model.drawio.svg new file mode 100644 index 0000000000..162e573db2 --- /dev/null +++ b/docs/etc/v1_model.drawio.svg @@ -0,0 +1,4 @@ + + + +
Operator
Operator
ConfiguredController
ConfiguredController
DefaultEventSourceManager
DefaultEventSourceManager
DefaultEventHandler
DefaultEventHandler
EventDispatcher
EventDispatcher
ResourceController
ResourceController
EventSource
EventSource
EventHandler
EventHandler
1
1
1..*
1..*
1
1
1..*
1..*
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/etc/v2_model.drawio.svg b/docs/etc/v2_model.drawio.svg new file mode 100644 index 0000000000..9670b7d747 --- /dev/null +++ b/docs/etc/v2_model.drawio.svg @@ -0,0 +1,4 @@ + + + +
Operator
Operator
Controller
Controller
EventSourceManager
EventSourceManager
EventProcessor
EventProcessor
EventSource
EventSource
ReconcilationDispatcher
ReconcilationDispatcher
Reconciler
Reconciler
1
1
1..*
1..*
1..*
1..*
Label
Label
1
1
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java index a90460d825..19f4f78bf7 100644 --- a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java +++ b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Map; -import io.javaoperatorsdk.operator.api.RetryInfo; import io.javaoperatorsdk.operator.api.monitoring.Metrics; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; import io.javaoperatorsdk.operator.processing.event.Event; import io.micrometer.core.instrument.MeterRegistry; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java index b525055a81..cd3ca8f916 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java @@ -2,8 +2,8 @@ import java.util.Locale; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @SuppressWarnings("rawtypes") public class ControllerUtils { @@ -14,33 +14,32 @@ public static String getDefaultFinalizerName(String crdName) { return crdName + FINALIZER_NAME_SUFFIX; } - public static String getNameFor(Class controllerClass) { + public static String getNameFor(Class controllerClass) { // if the controller annotation has a name attribute, use it - final var annotation = controllerClass.getAnnotation(Controller.class); + final var annotation = controllerClass.getAnnotation(ControllerConfiguration.class); if (annotation != null) { final var name = annotation.name(); - if (!Controller.EMPTY_STRING.equals(name)) { + if (!ControllerConfiguration.EMPTY_STRING.equals(name)) { return name; } } - // otherwise, use the lower-cased full class name return getDefaultNameFor(controllerClass); } - public static String getNameFor(ResourceController controller) { + public static String getNameFor(Reconciler controller) { return getNameFor(controller.getClass()); } - public static String getDefaultNameFor(ResourceController controller) { + public static String getDefaultNameFor(Reconciler controller) { return getDefaultNameFor(controller.getClass()); } - public static String getDefaultNameFor(Class controllerClass) { - return getDefaultResourceControllerName(controllerClass.getSimpleName()); + public static String getDefaultNameFor(Class reconcilerClass) { + return getDefaultReconcilerName(reconcilerClass.getSimpleName()); } - public static String getDefaultResourceControllerName(String rcControllerClassName) { + public static String getDefaultReconcilerName(String rcControllerClassName) { // if the name is fully qualified, extract the simple class name final var lastDot = rcControllerClassName.lastIndexOf('.'); if (lastDot > 0) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 60fe670a36..405f4b6927 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -14,11 +14,11 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.Version; import io.javaoperatorsdk.operator.api.LifecycleAware; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.processing.Controller; @SuppressWarnings("rawtypes") public class Operator implements AutoCloseable, LifecycleAware { @@ -49,7 +49,7 @@ public ConfigurationService getConfigurationService() { return configurationService; } - public List getControllers() { + public List getControllers() { return new ArrayList<>(controllers.controllers.values()); } @@ -114,7 +114,7 @@ public void close() { * @param the {@code CustomResource} type associated with the controller * @throws OperatorException if a problem occurred during the registration process */ - public > void register(ResourceController controller) + public > void register(Reconciler controller) throws OperatorException { register(controller, null); } @@ -126,29 +126,29 @@ public void close() { * passing it the controller's original configuration. The effective registration of the * controller is delayed till the operator is started. * - * @param controller the controller to register + * @param reconciler part of the controller to register * @param configuration the configuration with which we want to register the controller, if {@code * null}, the controller's original configuration is used * @param the {@code CustomResource} type associated with the controller * @throws OperatorException if a problem occurred during the registration process */ public > void register( - ResourceController controller, ControllerConfiguration configuration) + Reconciler reconciler, ControllerConfiguration configuration) throws OperatorException { - final var existing = configurationService.getConfigurationFor(controller); + final var existing = configurationService.getConfigurationFor(reconciler); if (existing == null) { throw new OperatorException( - "Cannot register controller with name " + controller.getClass().getCanonicalName() + - " controller named " + ControllerUtils.getNameFor(controller) + "Cannot register controller with name " + reconciler.getClass().getCanonicalName() + + " controller named " + ControllerUtils.getNameFor(reconciler) + " because its configuration cannot be found.\n" + " Known controllers are: " + configurationService.getKnownControllerNames()); } else { if (configuration == null) { configuration = existing; } - final var configuredController = - new ConfiguredController<>(controller, configuration, kubernetesClient); - controllers.add(configuredController); + final var controller = + new Controller<>(reconciler, configuration, kubernetesClient); + controllers.add(controller); final var watchedNS = configuration.watchAllNamespaces() @@ -163,7 +163,7 @@ public void close() { } static class ControllerManager implements LifecycleAware { - private final Map controllers = new HashMap<>(); + private final Map controllers = new HashMap<>(); private boolean started = false; public synchronized void shouldStart() { @@ -176,7 +176,7 @@ public synchronized void shouldStart() { } public synchronized void start() { - controllers.values().parallelStream().forEach(ConfiguredController::start); + controllers.values().parallelStream().forEach(Controller::start); started = true; } @@ -193,8 +193,8 @@ public synchronized void stop() { started = false; } - public synchronized void add(ConfiguredController configuredController) { - final var configuration = configuredController.getConfiguration(); + public synchronized void add(Controller controller) { + final var configuration = controller.getConfiguration(); final var crdName = configuration.getCRDName(); final var existing = controllers.get(crdName); if (existing != null) { @@ -202,9 +202,9 @@ public synchronized void add(ConfiguredController configuredController) { + "': another controller named '" + existing.getConfiguration().getName() + "' is already registered for CRD '" + crdName + "'"); } - this.controllers.put(crdName, configuredController); + this.controllers.put(crdName, controller); if (started) { - configuredController.start(); + controller.start(); } } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/EventSourceInitializer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/EventSourceInitializer.java deleted file mode 100644 index e7500b9e47..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/EventSourceInitializer.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.javaoperatorsdk.operator.api; - -import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.processing.event.EventSourceManager; - -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. - * - * @param eventSourceManager the {@link EventSourceManager} where event sources can be registered. - */ - void prepareEventSources(EventSourceManager eventSourceManager); - -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAware.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAware.java index 946fde48a3..e0a05a6b6c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAware.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ObservedGenerationAware.java @@ -3,6 +3,7 @@ import java.util.Optional; import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; /** * If the custom resource's status implements this interface, the observed generation will be diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java index af9c7856b8..b2eae5bbc2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java @@ -7,7 +7,7 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @SuppressWarnings("rawtypes") public class AbstractConfigurationService implements ConfigurationService { @@ -32,7 +32,7 @@ public AbstractConfigurationService(Version version) { if (failIfExisting) { final var existing = configurations.get(name); if (existing != null) { - throwExceptionOnNameCollision(config.getAssociatedControllerClassName(), existing); + throwExceptionOnNameCollision(config.getAssociatedReconcilerClassName(), existing); } } configurations.put(name, config); @@ -45,14 +45,14 @@ public AbstractConfigurationService(Version version) { "Controller name '" + existing.getName() + "' is used by both " - + existing.getAssociatedControllerClassName() + + existing.getAssociatedReconcilerClassName() + " and " + newControllerClassName); } @Override public > ControllerConfiguration getConfigurationFor( - ResourceController controller) { + Reconciler controller) { final var key = keyFor(controller); final var configuration = configurations.get(key); if (configuration == null) { @@ -73,7 +73,7 @@ private String getControllersNameMessage() { + "."; } - protected > String keyFor(ResourceController controller) { + protected > String keyFor(Reconciler controller) { return ControllerUtils.getNameFor(controller); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index b65115ec56..24e0605955 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -6,8 +6,8 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.monitoring.Metrics; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -37,7 +37,7 @@ public interface ConfigurationService { * null} if no configuration exists for the controller */ > ControllerConfiguration getConfigurationFor( - ResourceController controller); + Reconciler controller); /** * Retrieves the Kubernetes client configuration diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java index 62630f3ce2..3c223cd23f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java @@ -4,8 +4,8 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.monitoring.Metrics; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; public class ConfigurationServiceOverrider { private final ConfigurationService original; @@ -62,7 +62,7 @@ public ConfigurationService build() { return new ConfigurationService() { @Override public > ControllerConfiguration getConfigurationFor( - ResourceController controller) { + Reconciler controller) { return original.getConfigurationFor(controller); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java index 65ec26964b..70187b104c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java @@ -6,14 +6,13 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilters; public interface ControllerConfiguration> { default String getName() { - return ControllerUtils.getDefaultResourceControllerName(getAssociatedControllerClassName()); + return ControllerUtils.getDefaultReconcilerName(getAssociatedReconcilerClassName()); } default String getCRDName() { @@ -45,7 +44,7 @@ default Class getCustomResourceClass() { return (Class) type.getActualTypeArguments()[0]; } - String getAssociatedControllerClassName(); + String getAssociatedReconcilerClassName(); default Set getNamespaces() { return Collections.emptySet(); @@ -66,7 +65,8 @@ default boolean watchCurrentNamespace() { static boolean currentNamespaceWatched(Set namespaces) { return namespaces != null && namespaces.size() == 1 - && namespaces.contains(Controller.WATCH_CURRENT_NAMESPACE); + && namespaces.contains( + io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.WATCH_CURRENT_NAMESPACE); } /** @@ -98,7 +98,8 @@ default RetryConfiguration getRetryConfiguration() { default void setConfigurationService(ConfigurationService service) {} default boolean useFinalizer() { - return !Controller.NO_FINALIZER.equals(getFinalizer()); + return !io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.NO_FINALIZER + .equals(getFinalizer()); } /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java index b9e4f9b7e6..006d707803 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java @@ -76,7 +76,7 @@ public ControllerConfigurationOverrider withCustomResourcePredicate( public ControllerConfiguration build() { return new DefaultControllerConfiguration<>( - original.getAssociatedControllerClassName(), + original.getAssociatedReconcilerClassName(), original.getName(), original.getCRDName(), finalizer, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultControllerConfiguration.java index 672704f3c4..a0336eb92c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultControllerConfiguration.java @@ -75,7 +75,7 @@ public boolean isGenerationAware() { } @Override - public String getAssociatedControllerClassName() { + public String getAssociatedReconcilerClassName() { return associatedControllerClassName; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java index 5544bc542e..efb99cc0ae 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java @@ -2,7 +2,7 @@ import java.util.Map; -import io.javaoperatorsdk.operator.api.RetryInfo; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; import io.javaoperatorsdk.operator.processing.event.Event; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/BaseControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java similarity index 90% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/BaseControl.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java index aeca177cae..0fdcab7a56 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/BaseControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import java.util.Optional; import java.util.concurrent.TimeUnit; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java similarity index 65% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Context.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index 3651414c16..bc8966f31c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import java.util.Optional; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java similarity index 95% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java index bf03b03309..199a4985f8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -9,7 +9,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) -public @interface Controller { +public @interface ControllerConfiguration { String EMPTY_STRING = ""; String WATCH_CURRENT_NAMESPACE = "JOSDK_WATCH_CURRENT"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java similarity index 85% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DefaultContext.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index b74793d25c..8f73af29e7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import java.util.Optional; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DeleteControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java similarity index 93% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DeleteControl.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java index 0c2c3c87e5..5f41192c60 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/DeleteControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; public class DeleteControl extends BaseControl { 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 new file mode 100644 index 0000000000..f782b8bec7 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java @@ -0,0 +1,17 @@ +package io.javaoperatorsdk.operator.api.reconciler; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.processing.event.EventSourceRegistry; + +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. + * + * @param eventSourceRegistry the {@link EventSourceRegistry} where event sources can be + * registered. + */ + void prepareEventSources(EventSourceRegistry eventSourceRegistry); + +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java similarity index 91% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java index 7fe27ec908..937969126f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/ResourceController.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java @@ -1,8 +1,8 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import io.fabric8.kubernetes.client.CustomResource; -public interface ResourceController> { +public interface Reconciler> { /** * Note that this method is used in combination of finalizers. If automatic finalizer handling is @@ -28,7 +28,7 @@ public interface ResourceController> { * finalizer to indicate that the resource should not be deleted after all, in which case * the controller should restore the resource's state appropriately. */ - default DeleteControl deleteResource(R resource, Context context) { + default DeleteControl cleanup(R resource, Context context) { return DeleteControl.defaultDelete(); } @@ -46,6 +46,6 @@ default DeleteControl deleteResource(R resource, Context context) { * be skipped. However we will always call an update if there is no finalizer on object * and it's not marked for deletion. */ - UpdateControl createOrUpdateResource(R resource, Context context); + UpdateControl reconcile(R resource, Context context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/RetryInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java similarity index 62% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/RetryInfo.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java index 92149012a7..2525bde192 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/RetryInfo.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; public interface RetryInfo { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/UpdateControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java similarity index 97% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/UpdateControl.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java index 2c9531ca06..7d7b6b6e0b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/UpdateControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api; +package io.javaoperatorsdk.operator.api.reconciler; import io.fabric8.kubernetes.client.CustomResource; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ConfiguredController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java similarity index 68% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ConfiguredController.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java index a22d135317..cb0cef3b90 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ConfiguredController.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java @@ -11,34 +11,35 @@ import io.javaoperatorsdk.operator.CustomResourceUtils; import io.javaoperatorsdk.operator.MissingCRDException; import io.javaoperatorsdk.operator.OperatorException; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.EventSourceInitializer; import io.javaoperatorsdk.operator.api.LifecycleAware; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.monitoring.Metrics.ControllerExecution; -import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.processing.event.EventSourceManager; +import io.javaoperatorsdk.operator.processing.event.EventSourceRegistry; -public class ConfiguredController> implements ResourceController, +public class Controller> implements Reconciler, LifecycleAware, EventSourceInitializer { - private final ResourceController controller; + private final Reconciler reconciler; private final ControllerConfiguration configuration; private final KubernetesClient kubernetesClient; - private DefaultEventSourceManager eventSourceManager; + private EventSourceManager eventSourceManager; + private EventProcessor eventProcessor; - public ConfiguredController(ResourceController controller, + public Controller(Reconciler reconciler, ControllerConfiguration configuration, KubernetesClient kubernetesClient) { - this.controller = controller; + this.reconciler = reconciler; this.configuration = configuration; this.kubernetesClient = kubernetesClient; } @Override - public DeleteControl deleteResource(R resource, Context context) { + public DeleteControl cleanup(R resource, Context context) { return configuration.getConfigurationService().getMetrics().timeControllerExecution( new ControllerExecution<>() { @Override @@ -58,13 +59,13 @@ public String successTypeName(DeleteControl deleteControl) { @Override public DeleteControl execute() { - return controller.deleteResource(resource, context); + return reconciler.cleanup(resource, context); } }); } @Override - public UpdateControl createOrUpdateResource(R resource, Context context) { + public UpdateControl reconcile(R resource, Context context) { return configuration.getConfigurationService().getMetrics().timeControllerExecution( new ControllerExecution<>() { @Override @@ -91,13 +92,13 @@ public String successTypeName(UpdateControl result) { @Override public UpdateControl execute() { - return controller.createOrUpdateResource(resource, context); + return reconciler.reconcile(resource, context); } }); } @Override - public void prepareEventSources(EventSourceManager eventSourceManager) { + public void prepareEventSources(EventSourceRegistry eventSourceRegistry) { throw new UnsupportedOperationException("This method should never be called directly"); } @@ -110,7 +111,7 @@ public boolean equals(Object o) { return false; } - ConfiguredController that = (ConfiguredController) o; + Controller that = (Controller) o; return configuration.getName().equals(that.configuration.getName()); } @@ -124,8 +125,8 @@ public String toString() { return "'" + configuration.getName() + "' Controller"; } - public ResourceController getController() { - return controller; + public Reconciler getReconciler() { + return reconciler; } public ControllerConfiguration getConfiguration() { @@ -153,35 +154,40 @@ public void start() throws OperatorException { final String controllerName = configuration.getName(); final var crdName = configuration.getCRDName(); final var specVersion = "v1"; - - // check that the custom resource is known by the cluster if configured that way - final CustomResourceDefinition crd; // todo: check proper CRD spec version based on config - if (configuration.getConfigurationService().checkCRDAndValidateLocalModel()) { - crd = - kubernetesClient.apiextensions().v1().customResourceDefinitions().withName(crdName).get(); - if (crd == null) { - throwMissingCRDException(crdName, specVersion, controllerName); + try { + // check that the custom resource is known by the cluster if configured that way + final CustomResourceDefinition crd; // todo: check proper CRD spec version based on config + if (configuration.getConfigurationService().checkCRDAndValidateLocalModel()) { + crd = + kubernetesClient.apiextensions().v1().customResourceDefinitions().withName(crdName) + .get(); + if (crd == null) { + throwMissingCRDException(crdName, specVersion, controllerName); + } + + // Apply validations that are not handled by fabric8 + CustomResourceUtils.assertCustomResource(resClass, crd); } - // Apply validations that are not handled by fabric8 - CustomResourceUtils.assertCustomResource(resClass, crd); - } - - try { - eventSourceManager = new DefaultEventSourceManager<>(this); - if (controller instanceof EventSourceInitializer) { - ((EventSourceInitializer) controller).prepareEventSources(eventSourceManager); + eventSourceManager = new EventSourceManager<>(this); + eventProcessor = + new EventProcessor<>(this, eventSourceManager.getCustomResourceEventSource()); + eventProcessor.setEventSourceManager(eventSourceManager); + eventSourceManager.setEventProcessor(eventProcessor); + if (reconciler instanceof EventSourceInitializer) { + ((EventSourceInitializer) reconciler).prepareEventSources(eventSourceManager); + } + if (failOnMissingCurrentNS()) { + throw new OperatorException( + "Controller '" + + controllerName + + "' is configured to watch the current namespace but it couldn't be inferred from the current configuration."); } + eventProcessor.start(); + eventSourceManager.start(); } catch (MissingCRDException e) { throwMissingCRDException(crdName, specVersion, controllerName); } - - if (failOnMissingCurrentNS()) { - throw new OperatorException( - "Controller '" - + controllerName - + "' is configured to watch the current namespace but it couldn't be inferred from the current configuration."); - } } private void throwMissingCRDException(String crdName, String specVersion, String controllerName) { @@ -213,13 +219,12 @@ private boolean failOnMissingCurrentNS() { return false; } - public EventSourceManager getEventSourceManager() { - return eventSourceManager; - } - public void stop() { if (eventSourceManager != null) { eventSourceManager.stop(); } + if (eventProcessor != null) { + eventProcessor.stop(); + } } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventProcessor.java similarity index 92% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventProcessor.java index 9b5c10d877..1fd8952ebf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/DefaultEventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventProcessor.java @@ -15,14 +15,14 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.api.LifecycleAware; -import io.javaoperatorsdk.operator.api.RetryInfo; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager; import io.javaoperatorsdk.operator.api.monitoring.Metrics; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; -import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.EventHandler; +import io.javaoperatorsdk.operator.processing.event.EventSourceManager; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; import io.javaoperatorsdk.operator.processing.event.internal.ResourceAction; import io.javaoperatorsdk.operator.processing.retry.GenericRetry; @@ -36,13 +36,13 @@ * Event handler that makes sure that events are processed in a "single threaded" way per resource * UID, while buffering events which are received during an execution. */ -public class DefaultEventHandler> +public class EventProcessor> implements EventHandler, LifecycleAware { - private static final Logger log = LoggerFactory.getLogger(DefaultEventHandler.class); + private static final Logger log = LoggerFactory.getLogger(EventProcessor.class); private final Set underProcessing = new HashSet<>(); - private final EventDispatcher eventDispatcher; + private final ReconciliationDispatcher reconciliationDispatcher; private final Retry retry; private final Map retryState = new HashMap<>(); private final ExecutorService executor; @@ -51,29 +51,31 @@ public class DefaultEventHandler> private final Metrics metrics; private volatile boolean running; private final ResourceCache resourceCache; - private DefaultEventSourceManager eventSourceManager; + private EventSourceManager eventSourceManager; private final EventMarker eventMarker; - public DefaultEventHandler(ConfiguredController controller, ResourceCache resourceCache) { + public EventProcessor(Controller controller, ResourceCache resourceCache) { this( resourceCache, ExecutorServiceManager.instance().executorService(), controller.getConfiguration().getName(), - new EventDispatcher<>(controller), + new ReconciliationDispatcher<>(controller), GenericRetry.fromConfiguration(controller.getConfiguration().getRetryConfiguration()), controller.getConfiguration().getConfigurationService().getMetrics(), new EventMarker()); } - DefaultEventHandler(EventDispatcher eventDispatcher, ResourceCache resourceCache, + EventProcessor(ReconciliationDispatcher reconciliationDispatcher, + ResourceCache resourceCache, String relatedControllerName, Retry retry, EventMarker eventMarker) { - this(resourceCache, null, relatedControllerName, eventDispatcher, retry, null, eventMarker); + this(resourceCache, null, relatedControllerName, reconciliationDispatcher, retry, null, + eventMarker); } - private DefaultEventHandler(ResourceCache resourceCache, ExecutorService executor, + private EventProcessor(ResourceCache resourceCache, ExecutorService executor, String relatedControllerName, - EventDispatcher eventDispatcher, Retry retry, Metrics metrics, + ReconciliationDispatcher reconciliationDispatcher, Retry retry, Metrics metrics, EventMarker eventMarker) { this.running = true; this.executor = @@ -82,14 +84,14 @@ private DefaultEventHandler(ResourceCache resourceCache, ExecutorService exec ConfigurationService.DEFAULT_RECONCILIATION_THREADS_NUMBER) : executor; this.controllerName = relatedControllerName; - this.eventDispatcher = eventDispatcher; + this.reconciliationDispatcher = reconciliationDispatcher; this.retry = retry; this.resourceCache = resourceCache; this.metrics = metrics != null ? metrics : Metrics.NOOP; this.eventMarker = eventMarker; } - public void setEventSourceManager(DefaultEventSourceManager eventSourceManager) { + public void setEventSourceManager(EventSourceManager eventSourceManager) { this.eventSourceManager = eventSourceManager; } @@ -359,7 +361,7 @@ public void run() { MDCUtils.addCustomResourceInfo(executionScope.getCustomResource()); thread.setName("EventHandler-" + controllerName); PostExecutionControl postExecutionControl = - eventDispatcher.handleExecution(executionScope); + reconciliationDispatcher.handleExecution(executionScope); eventProcessingFinished(executionScope, postExecutionControl); } finally { // restore original name diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ExecutionScope.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ExecutionScope.java index 6cf05e9308..a24f3461c7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ExecutionScope.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ExecutionScope.java @@ -1,7 +1,7 @@ package io.javaoperatorsdk.operator.processing; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.RetryInfo; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; public class ExecutionScope> { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcher.java similarity index 90% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcher.java index 3764667288..fa01bce577 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/EventDispatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcher.java @@ -8,36 +8,36 @@ import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; -import io.javaoperatorsdk.operator.api.BaseControl; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.DefaultContext; -import io.javaoperatorsdk.operator.api.DeleteControl; import io.javaoperatorsdk.operator.api.ObservedGenerationAware; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.BaseControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.DefaultContext; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getName; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion; /** - * Dispatches events to the Controller and handles Finalizers for a single type of Custom Resource. + * Handles calls and results of a Reconciler and finalizer related logic */ -public class EventDispatcher> { +public class ReconciliationDispatcher> { - private static final Logger log = LoggerFactory.getLogger(EventDispatcher.class); + private static final Logger log = LoggerFactory.getLogger(ReconciliationDispatcher.class); - private final ConfiguredController controller; + private final Controller controller; private final CustomResourceFacade customResourceFacade; - EventDispatcher(ConfiguredController controller, + ReconciliationDispatcher(Controller controller, CustomResourceFacade customResourceFacade) { this.controller = controller; this.customResourceFacade = customResourceFacade; } - public EventDispatcher(ConfiguredController controller) { + public ReconciliationDispatcher(Controller controller) { this(controller, new CustomResourceFacade<>(controller.getCRClient())); } @@ -85,7 +85,7 @@ private ControllerConfiguration configuration() { /** * Determines whether the given resource should be dispatched to the controller's - * {@link ResourceController#deleteResource(CustomResource, Context)} method + * {@link Reconciler#cleanup(CustomResource, Context)} method * * @param resource the resource to be potentially deleted * @return {@code true} if the resource should be handed to the controller's {@code @@ -115,7 +115,7 @@ private PostExecutionControl handleCreateOrUpdate( getVersion(resource), executionScope); - UpdateControl updateControl = controller.createOrUpdateResource(resource, context); + UpdateControl updateControl = controller.reconcile(resource, context); R updatedCustomResource = null; if (updateControl.isUpdateCustomResourceAndStatusSubResource()) { updatedCustomResource = updateCustomResource(updateControl.getCustomResource()); @@ -173,7 +173,7 @@ private PostExecutionControl handleDelete(R resource, Context context) { getName(resource), getVersion(resource)); - DeleteControl deleteControl = controller.deleteResource(resource, context); + DeleteControl deleteControl = controller.cleanup(resource, context); final var useFinalizer = configuration().useFinalizer(); if (useFinalizer) { // note that we don't reschedule here even if instructed. Removing finalizer means that diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManager.java deleted file mode 100644 index dd8e7f19ce..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManager.java +++ /dev/null @@ -1,124 +0,0 @@ -package io.javaoperatorsdk.operator.processing.event; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.MissingCRDException; -import io.javaoperatorsdk.operator.OperatorException; -import io.javaoperatorsdk.operator.api.LifecycleAware; -import io.javaoperatorsdk.operator.processing.ConfiguredController; -import io.javaoperatorsdk.operator.processing.DefaultEventHandler; -import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventSource; -import io.javaoperatorsdk.operator.processing.event.internal.TimerEventSource; - -public class DefaultEventSourceManager> - implements EventSourceManager, LifecycleAware { - - private static final Logger log = LoggerFactory.getLogger(DefaultEventSourceManager.class); - - private final ReentrantLock lock = new ReentrantLock(); - private final Set eventSources = Collections.synchronizedSet(new HashSet<>()); - private DefaultEventHandler defaultEventHandler; - private TimerEventSource retryAndRescheduleTimerEventSource; - private CustomResourceEventSource customResourceEventSource; - - DefaultEventSourceManager(DefaultEventHandler defaultEventHandler) { - init(defaultEventHandler); - } - - public DefaultEventSourceManager(ConfiguredController controller) { - customResourceEventSource = new CustomResourceEventSource<>(controller); - init(new DefaultEventHandler<>(controller, customResourceEventSource)); - registerEventSource(customResourceEventSource); - } - - private void init(DefaultEventHandler defaultEventHandler) { - this.defaultEventHandler = defaultEventHandler; - defaultEventHandler.setEventSourceManager(this); - - this.retryAndRescheduleTimerEventSource = new TimerEventSource<>(); - registerEventSource(retryAndRescheduleTimerEventSource); - } - - @Override - public void start() throws OperatorException { - defaultEventHandler.start(); - } - - @Override - public void stop() { - lock.lock(); - try { - try { - defaultEventHandler.stop(); - } catch (Exception e) { - log.warn("Error closing event handler", e); - } - log.debug("Closing event sources."); - for (var eventSource : eventSources) { - try { - eventSource.stop(); - } catch (Exception e) { - log.warn("Error closing {} -> {}", eventSource, e); - } - } - eventSources.clear(); - } finally { - lock.unlock(); - } - } - - @Override - public final void registerEventSource(EventSource eventSource) - throws OperatorException { - Objects.requireNonNull(eventSource, "EventSource must not be null"); - lock.lock(); - try { - eventSources.add(eventSource); - eventSource.setEventHandler(defaultEventHandler); - eventSource.start(); - } catch (Throwable e) { - if (e instanceof IllegalStateException || e instanceof MissingCRDException) { - // leave untouched - throw e; - } - throw new OperatorException( - "Couldn't register event source: " + eventSource.getClass().getName(), e); - } finally { - lock.unlock(); - } - } - - public void cleanupForCustomResource(CustomResourceID customResourceUid) { - lock.lock(); - try { - for (EventSource eventSource : this.eventSources) { - eventSource.cleanupForCustomResource(customResourceUid); - } - } finally { - lock.unlock(); - } - } - - public TimerEventSource getRetryAndRescheduleTimerEventSource() { - return retryAndRescheduleTimerEventSource; - } - - @Override - public Set getRegisteredEventSources() { - return Collections.unmodifiableSet(eventSources); - } - - @Override - public CustomResourceEventSource getCustomResourceEventSource() { - return customResourceEventSource; - } - -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java index e06ab2e3d1..b1d941d4e4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java @@ -1,26 +1,138 @@ package io.javaoperatorsdk.operator.processing.event; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.MissingCRDException; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.LifecycleAware; +import io.javaoperatorsdk.operator.processing.Controller; +import io.javaoperatorsdk.operator.processing.EventProcessor; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventSource; +import io.javaoperatorsdk.operator.processing.event.internal.TimerEventSource; + +public class EventSourceManager> + implements EventSourceRegistry, LifecycleAware { + + private static final Logger log = LoggerFactory.getLogger(EventSourceManager.class); + + private final ReentrantLock lock = new ReentrantLock(); + private final Set eventSources = Collections.synchronizedSet(new HashSet<>()); + private EventProcessor eventProcessor; + private TimerEventSource retryAndRescheduleTimerEventSource; + private CustomResourceEventSource customResourceEventSource; + + EventSourceManager() { + init(); + } + + public EventSourceManager(Controller controller) { + init(); + customResourceEventSource = new CustomResourceEventSource<>(controller); + registerEventSource(customResourceEventSource); + } + + private void init() { + this.retryAndRescheduleTimerEventSource = new TimerEventSource<>(); + registerEventSource(retryAndRescheduleTimerEventSource); + } + + public EventSourceManager setEventProcessor(EventProcessor eventProcessor) { + this.eventProcessor = eventProcessor; + if (customResourceEventSource != null) { + customResourceEventSource.setEventHandler(eventProcessor); + } + if (retryAndRescheduleTimerEventSource != null) { + retryAndRescheduleTimerEventSource.setEventHandler(eventProcessor); + } + return this; + } + + @Override + public void start() throws OperatorException { + lock.lock(); + try { + log.debug("Starting event sources."); + for (var eventSource : eventSources) { + try { + eventSource.start(); + } catch (Exception e) { + log.warn("Error closing {} -> {}", eventSource, e); + } + } + } finally { + lock.unlock(); + } + } + + @Override + public void stop() { + lock.lock(); + try { + log.debug("Closing event sources."); + for (var eventSource : eventSources) { + try { + eventSource.stop(); + } catch (Exception e) { + log.warn("Error closing {} -> {}", eventSource, e); + } + } + eventSources.clear(); + } finally { + lock.unlock(); + } + } + + @Override + public final void registerEventSource(EventSource eventSource) + throws OperatorException { + Objects.requireNonNull(eventSource, "EventSource must not be null"); + lock.lock(); + try { + eventSources.add(eventSource); + eventSource.setEventHandler(eventProcessor); + } catch (Throwable e) { + if (e instanceof IllegalStateException || e instanceof MissingCRDException) { + // leave untouched + throw e; + } + throw new OperatorException( + "Couldn't register event source: " + eventSource.getClass().getName(), e); + } finally { + lock.unlock(); + } + } -public interface EventSourceManager> { + public void cleanupForCustomResource(CustomResourceID customResourceUid) { + lock.lock(); + try { + for (EventSource eventSource : this.eventSources) { + eventSource.cleanupForCustomResource(customResourceUid); + } + } finally { + lock.unlock(); + } + } - /** - * Add the {@link EventSource} identified by the given name to the event manager. - * - * @param eventSource the {@link EventSource} to register - * @throws IllegalStateException if an {@link EventSource} with the same name is already - * registered. - * @throws OperatorException if an error occurred during the registration process - */ - void registerEventSource(EventSource eventSource) - throws IllegalStateException, OperatorException; + public TimerEventSource getRetryAndRescheduleTimerEventSource() { + return retryAndRescheduleTimerEventSource; + } - Set getRegisteredEventSources(); + @Override + public Set getRegisteredEventSources() { + return Collections.unmodifiableSet(eventSources); + } - CustomResourceEventSource getCustomResourceEventSource(); + @Override + public CustomResourceEventSource getCustomResourceEventSource() { + return customResourceEventSource; + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRegistry.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRegistry.java new file mode 100644 index 0000000000..95de04976e --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRegistry.java @@ -0,0 +1,26 @@ +package io.javaoperatorsdk.operator.processing.event; + +import java.util.Set; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventSource; + +public interface EventSourceRegistry> { + + /** + * Add the {@link EventSource} identified by the given name to the event manager. + * + * @param eventSource the {@link EventSource} to register + * @throws IllegalStateException if an {@link EventSource} with the same name is already + * registered. + * @throws OperatorException if an error occurred during the registration process + */ + void registerEventSource(EventSource eventSource) + throws IllegalStateException, OperatorException; + + Set getRegisteredEventSources(); + + CustomResourceEventSource getCustomResourceEventSource(); + +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java index 8845c599c6..c1391b92c7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java @@ -14,7 +14,7 @@ import io.javaoperatorsdk.operator.MissingCRDException; import io.javaoperatorsdk.operator.api.config.Cloner; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.MDCUtils; import io.javaoperatorsdk.operator.processing.ResourceCache; import io.javaoperatorsdk.operator.processing.event.AbstractEventSource; @@ -35,7 +35,7 @@ public class CustomResourceEventSource> extends A private static final Logger log = LoggerFactory.getLogger(CustomResourceEventSource.class); - private final ConfiguredController controller; + private final Controller controller; private final Map> sharedIndexInformers = new ConcurrentHashMap<>(); @@ -43,7 +43,7 @@ public class CustomResourceEventSource> extends A private final OnceWhitelistEventFilterEventFilter onceWhitelistEventFilterEventFilter; private final Cloner cloner; - public CustomResourceEventSource(ConfiguredController controller) { + public CustomResourceEventSource(Controller controller) { this.controller = controller; this.cloner = controller.getConfiguration().getConfigurationService().getResourceCloner(); @@ -89,14 +89,13 @@ public void start() { }); } } catch (Exception e) { - // todo double check this if still applies for informers if (e instanceof KubernetesClientException) { KubernetesClientException ke = (KubernetesClientException) e; if (404 == ke.getCode()) { // only throw MissingCRDException if the 404 error occurs on the target CRD final var targetCRDName = controller.getConfiguration().getCRDName(); if (targetCRDName.equals(ke.getFullResourceName())) { - throw new MissingCRDException(targetCRDName, null); + throw new MissingCRDException(targetCRDName, null, e.getMessage(), e); } } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java index 9326d225d6..814a85b7d3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java @@ -2,7 +2,7 @@ import java.util.Optional; -import io.javaoperatorsdk.operator.api.RetryInfo; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; public interface RetryExecution extends RetryInfo { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerManagerTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerManagerTest.java index d25378499e..6db84b45e3 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerManagerTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerManagerTest.java @@ -4,13 +4,13 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.Operator.ControllerManager; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.DefaultControllerConfiguration; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.sample.simple.DuplicateCRController; +import io.javaoperatorsdk.operator.sample.simple.TestCustomReconciler; +import io.javaoperatorsdk.operator.sample.simple.TestCustomReconcilerV2; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; -import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController; -import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceControllerV2; import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceV2; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -20,7 +20,7 @@ public class ControllerManagerTest { @Test public void shouldNotAddMultipleControllersForSameCustomResource() { - final var registered = new TestControllerConfiguration<>(new TestCustomResourceController(null), + final var registered = new TestControllerConfiguration<>(new TestCustomReconciler(null), TestCustomResource.class); final var duplicated = new TestControllerConfiguration<>(new DuplicateCRController(), TestCustomResource.class); @@ -30,9 +30,9 @@ public void shouldNotAddMultipleControllersForSameCustomResource() { @Test public void addingMultipleControllersForCustomResourcesWithDifferentVersionsShouldNotWork() { - final var registered = new TestControllerConfiguration<>(new TestCustomResourceController(null), + final var registered = new TestControllerConfiguration<>(new TestCustomReconciler(null), TestCustomResource.class); - final var duplicated = new TestControllerConfiguration<>(new TestCustomResourceControllerV2(), + final var duplicated = new TestControllerConfiguration<>(new TestCustomReconcilerV2(), TestCustomResourceV2.class); checkException(registered, duplicated); @@ -44,8 +44,8 @@ public void addingMultipleControllersForCustomResourcesWithDifferentVersionsShou TestControllerConfiguration duplicated) { final var exception = assertThrows(OperatorException.class, () -> { final var controllerManager = new ControllerManager(); - controllerManager.add(new ConfiguredController<>(registered.controller, registered, null)); - controllerManager.add(new ConfiguredController<>(duplicated.controller, duplicated, null)); + controllerManager.add(new Controller<>(registered.controller, registered, null)); + controllerManager.add(new Controller<>(duplicated.controller, duplicated, null)); }); final var msg = exception.getMessage(); assertTrue( @@ -56,16 +56,16 @@ public void addingMultipleControllersForCustomResourcesWithDifferentVersionsShou private static class TestControllerConfiguration> extends DefaultControllerConfiguration { - private final ResourceController controller; + private final Reconciler controller; - public TestControllerConfiguration(ResourceController controller, Class crClass) { + public TestControllerConfiguration(Reconciler controller, Class crClass) { super(null, getControllerName(controller), CustomResource.getCRDName(crClass), null, false, null, null, null, null, crClass, null); this.controller = controller; } static > String getControllerName( - ResourceController controller) { + Reconciler controller) { return controller.getClass().getSimpleName() + "Controller"; } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java index cfc390f9c7..b8db81c2e9 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/ControllerUtilsTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController; +import io.javaoperatorsdk.operator.sample.simple.TestCustomReconciler; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -11,8 +11,8 @@ class ControllerUtilsTest { @Test void getDefaultResourceControllerName() { assertEquals( - "testcustomresourcecontroller", - ControllerUtils.getDefaultResourceControllerName( - TestCustomResourceController.class.getCanonicalName())); + "testcustomreconciler", + ControllerUtils.getDefaultReconcilerName( + TestCustomReconciler.class.getCanonicalName())); } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/DeleteControlTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/DeleteControlTest.java index eb0fddd849..9907c0405e 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/DeleteControlTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/DeleteControlTest.java @@ -3,6 +3,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; + class DeleteControlTest { @Test diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java index 7e404e0223..7f8698d81b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationTest.java @@ -12,7 +12,7 @@ class ControllerConfigurationTest { void getCustomResourceClass() { final ControllerConfiguration conf = new ControllerConfiguration<>() { @Override - public String getAssociatedControllerClassName() { + public String getAssociatedReconcilerClassName() { return null; } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventProcessorTest.java similarity index 75% rename from operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java rename to operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventProcessorTest.java index 9be173e41b..2c10a37ddc 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/DefaultEventHandlerTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventProcessorTest.java @@ -13,8 +13,8 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; -import io.javaoperatorsdk.operator.processing.event.DefaultEventSourceManager; import io.javaoperatorsdk.operator.processing.event.Event; +import io.javaoperatorsdk.operator.processing.event.EventSourceManager; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventSource; import io.javaoperatorsdk.operator.processing.event.internal.ResourceAction; @@ -28,41 +28,43 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; -class DefaultEventHandlerTest { +class EventProcessorTest { - private static final Logger log = LoggerFactory.getLogger(DefaultEventHandlerTest.class); + private static final Logger log = LoggerFactory.getLogger(EventProcessorTest.class); public static final int FAKE_CONTROLLER_EXECUTION_DURATION = 250; public static final int SEPARATE_EXECUTION_TIMEOUT = 450; public static final String TEST_NAMESPACE = "default-event-handler-test"; private EventMarker eventMarker = new EventMarker(); - private EventDispatcher eventDispatcherMock = mock(EventDispatcher.class); - private DefaultEventSourceManager defaultEventSourceManagerMock = - mock(DefaultEventSourceManager.class); + private ReconciliationDispatcher reconciliationDispatcherMock = + mock(ReconciliationDispatcher.class); + private EventSourceManager eventSourceManagerMock = + mock(EventSourceManager.class); private ResourceCache resourceCacheMock = mock(ResourceCache.class); private TimerEventSource retryTimerEventSourceMock = mock(TimerEventSource.class); - private DefaultEventHandler defaultEventHandler = - new DefaultEventHandler(eventDispatcherMock, resourceCacheMock, "Test", null, eventMarker); + private EventProcessor eventProcessor = + new EventProcessor(reconciliationDispatcherMock, resourceCacheMock, "Test", null, + eventMarker); - private DefaultEventHandler defaultEventHandlerWithRetry = - new DefaultEventHandler(eventDispatcherMock, resourceCacheMock, "Test", + private EventProcessor eventProcessorWithRetry = + new EventProcessor(reconciliationDispatcherMock, resourceCacheMock, "Test", GenericRetry.defaultLimitedExponentialRetry(), eventMarker); @BeforeEach public void setup() { - when(defaultEventSourceManagerMock.getRetryAndRescheduleTimerEventSource()) + when(eventSourceManagerMock.getRetryAndRescheduleTimerEventSource()) .thenReturn(retryTimerEventSourceMock); - defaultEventHandler.setEventSourceManager(defaultEventSourceManagerMock); - defaultEventHandlerWithRetry.setEventSourceManager(defaultEventSourceManagerMock); + eventProcessor.setEventSourceManager(eventSourceManagerMock); + eventProcessorWithRetry.setEventSourceManager(eventSourceManagerMock); } @Test public void dispatchesEventsIfNoExecutionInProgress() { - defaultEventHandler.handleEvent(prepareCREvent()); + eventProcessor.handleEvent(prepareCREvent()); - verify(eventDispatcherMock, timeout(50).times(1)).handleExecution(any()); + verify(reconciliationDispatcherMock, timeout(50).times(1)).handleExecution(any()); } @Test @@ -71,18 +73,18 @@ public void skipProcessingIfLatestCustomResourceNotInCache() { when(resourceCacheMock.getCustomResource(event.getRelatedCustomResourceID())) .thenReturn(Optional.empty()); - defaultEventHandler.handleEvent(event); + eventProcessor.handleEvent(event); - verify(eventDispatcherMock, timeout(50).times(0)).handleExecution(any()); + verify(reconciliationDispatcherMock, timeout(50).times(0)).handleExecution(any()); } @Test public void ifExecutionInProgressWaitsUntilItsFinished() throws InterruptedException { CustomResourceID resourceUid = eventAlreadyUnderProcessing(); - defaultEventHandler.handleEvent(nonCREvent(resourceUid)); + eventProcessor.handleEvent(nonCREvent(resourceUid)); - verify(eventDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(1)) + verify(reconciliationDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(1)) .handleExecution(any()); } @@ -94,7 +96,7 @@ public void schedulesAnEventRetryOnException() { PostExecutionControl postExecutionControl = PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); - defaultEventHandlerWithRetry.eventProcessingFinished(executionScope, postExecutionControl); + eventProcessorWithRetry.eventProcessingFinished(executionScope, postExecutionControl); verify(retryTimerEventSourceMock, times(1)) .scheduleOnce(eq(customResource), eq(GenericRetry.DEFAULT_INITIAL_INTERVAL)); @@ -108,18 +110,18 @@ public void executesTheControllerInstantlyAfterErrorIfNewEventsReceived() { PostExecutionControl postExecutionControl = PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); - when(eventDispatcherMock.handleExecution(any())) + when(reconciliationDispatcherMock.handleExecution(any())) .thenReturn(postExecutionControl) .thenReturn(PostExecutionControl.defaultDispatch()); // start processing an event - defaultEventHandlerWithRetry.handleEvent(event); + eventProcessorWithRetry.handleEvent(event); // handle another event - defaultEventHandlerWithRetry.handleEvent(event); + eventProcessorWithRetry.handleEvent(event); ArgumentCaptor executionScopeArgumentCaptor = ArgumentCaptor.forClass(ExecutionScope.class); - verify(eventDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(2)) + verify(reconciliationDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(2)) .handleExecution(executionScopeArgumentCaptor.capture()); List allValues = executionScopeArgumentCaptor.getAllValues(); assertThat(allValues).hasSize(2); @@ -138,23 +140,23 @@ public void successfulExecutionResetsTheRetry() { PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); PostExecutionControl defaultDispatchControl = PostExecutionControl.defaultDispatch(); - when(eventDispatcherMock.handleExecution(any())) + when(reconciliationDispatcherMock.handleExecution(any())) .thenReturn(postExecutionControlWithException) .thenReturn(defaultDispatchControl); ArgumentCaptor executionScopeArgumentCaptor = ArgumentCaptor.forClass(ExecutionScope.class); - defaultEventHandlerWithRetry.handleEvent(event); - verify(eventDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(1)) + eventProcessorWithRetry.handleEvent(event); + verify(reconciliationDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(1)) .handleExecution(any()); - defaultEventHandlerWithRetry.handleEvent(event); - verify(eventDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(2)) + eventProcessorWithRetry.handleEvent(event); + verify(reconciliationDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(2)) .handleExecution(any()); - defaultEventHandlerWithRetry.handleEvent(event); - verify(eventDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(3)) + eventProcessorWithRetry.handleEvent(event); + verify(reconciliationDispatcherMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(3)) .handleExecution(executionScopeArgumentCaptor.capture()); log.info("Finished successfulExecutionResetsTheRetry"); @@ -170,10 +172,10 @@ public void successfulExecutionResetsTheRetry() { @Test public void scheduleTimedEventIfInstructedByPostExecutionControl() { var testDelay = 10000L; - when(eventDispatcherMock.handleExecution(any())) + when(reconciliationDispatcherMock.handleExecution(any())) .thenReturn(PostExecutionControl.defaultDispatch().withReSchedule(testDelay)); - defaultEventHandler.handleEvent(prepareCREvent()); + eventProcessor.handleEvent(prepareCREvent()); verify(retryTimerEventSourceMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(1)) .scheduleOnce(any(), eq(testDelay)); @@ -182,11 +184,11 @@ public void scheduleTimedEventIfInstructedByPostExecutionControl() { @Test public void reScheduleOnlyIfNotExecutedEventsReceivedMeanwhile() { var testDelay = 10000L; - when(eventDispatcherMock.handleExecution(any())) + when(reconciliationDispatcherMock.handleExecution(any())) .thenReturn(PostExecutionControl.defaultDispatch().withReSchedule(testDelay)); - defaultEventHandler.handleEvent(prepareCREvent()); - defaultEventHandler.handleEvent(prepareCREvent()); + eventProcessor.handleEvent(prepareCREvent()); + eventProcessor.handleEvent(prepareCREvent()); verify(retryTimerEventSourceMock, timeout(SEPARATE_EXECUTION_TIMEOUT).times(0)) .scheduleOnce(any(), eq(testDelay)); @@ -194,10 +196,10 @@ public void reScheduleOnlyIfNotExecutedEventsReceivedMeanwhile() { @Test public void doNotFireEventsIfClosing() { - defaultEventHandler.stop(); - defaultEventHandler.handleEvent(prepareCREvent()); + eventProcessor.stop(); + eventProcessor.handleEvent(prepareCREvent()); - verify(eventDispatcherMock, timeout(50).times(0)).handleExecution(any()); + verify(reconciliationDispatcherMock, timeout(50).times(0)).handleExecution(any()); } @Test @@ -205,9 +207,9 @@ public void cleansUpWhenDeleteEventReceivedAndNoEventPresent() { Event deleteEvent = new CustomResourceEvent(DELETED, prepareCREvent().getRelatedCustomResourceID()); - defaultEventHandler.handleEvent(deleteEvent); + eventProcessor.handleEvent(deleteEvent); - verify(defaultEventSourceManagerMock, times(1)) + verify(eventSourceManagerMock, times(1)) .cleanupForCustomResource(eq(deleteEvent.getRelatedCustomResourceID())); } @@ -218,10 +220,10 @@ public void cleansUpAfterExecutionIfOnlyDeleteEventMarkLeft() { eventMarker.markDeleteEventReceived(crEvent.getRelatedCustomResourceID()); var executionScope = new ExecutionScope(cr, null); - defaultEventHandler.eventProcessingFinished(executionScope, + eventProcessor.eventProcessingFinished(executionScope, PostExecutionControl.defaultDispatch()); - verify(defaultEventSourceManagerMock, times(1)) + verify(eventSourceManagerMock, times(1)) .cleanupForCustomResource(eq(crEvent.getRelatedCustomResourceID())); } @@ -234,10 +236,10 @@ public void whitelistNextEventIfTheCacheIsNotPropagatedAfterAnUpdate() { var mockCREventSource = mock(CustomResourceEventSource.class); eventMarker.markEventReceived(crID); when(resourceCacheMock.getCustomResource(eq(crID))).thenReturn(Optional.of(cr)); - when(defaultEventSourceManagerMock.getCustomResourceEventSource()) + when(eventSourceManagerMock.getCustomResourceEventSource()) .thenReturn(mockCREventSource); - defaultEventHandler.eventProcessingFinished(new ExecutionScope(cr, null), + eventProcessor.eventProcessingFinished(new ExecutionScope(cr, null), PostExecutionControl.customResourceUpdated(updatedCr)); verify(mockCREventSource, times(1)).whitelistNextEvent(eq(crID)); @@ -254,10 +256,10 @@ public void dontWhitelistsEventWhenOtherChangeDuringExecution() { var mockCREventSource = mock(CustomResourceEventSource.class); eventMarker.markEventReceived(crID); when(resourceCacheMock.getCustomResource(eq(crID))).thenReturn(Optional.of(otherChangeCR)); - when(defaultEventSourceManagerMock.getCustomResourceEventSource()) + when(eventSourceManagerMock.getCustomResourceEventSource()) .thenReturn(mockCREventSource); - defaultEventHandler.eventProcessingFinished(new ExecutionScope(cr, null), + eventProcessor.eventProcessingFinished(new ExecutionScope(cr, null), PostExecutionControl.customResourceUpdated(updatedCr)); verify(mockCREventSource, times(0)).whitelistNextEvent(eq(crID)); @@ -270,10 +272,10 @@ public void dontWhitelistsEventIfUpdatedEventInCache() { var mockCREventSource = mock(CustomResourceEventSource.class); eventMarker.markEventReceived(crID); when(resourceCacheMock.getCustomResource(eq(crID))).thenReturn(Optional.of(cr)); - when(defaultEventSourceManagerMock.getCustomResourceEventSource()) + when(eventSourceManagerMock.getCustomResourceEventSource()) .thenReturn(mockCREventSource); - defaultEventHandler.eventProcessingFinished(new ExecutionScope(cr, null), + eventProcessor.eventProcessingFinished(new ExecutionScope(cr, null), PostExecutionControl.customResourceUpdated(cr)); verify(mockCREventSource, times(0)).whitelistNextEvent(eq(crID)); @@ -284,21 +286,21 @@ public void cancelScheduleOnceEventsOnSuccessfulExecution() { var crID = new CustomResourceID("test-cr", TEST_NAMESPACE); var cr = testCustomResource(crID); - defaultEventHandler.eventProcessingFinished(new ExecutionScope(cr, null), + eventProcessor.eventProcessingFinished(new ExecutionScope(cr, null), PostExecutionControl.defaultDispatch()); verify(retryTimerEventSourceMock, times(1)).cancelOnceSchedule(eq(crID)); } private CustomResourceID eventAlreadyUnderProcessing() { - when(eventDispatcherMock.handleExecution(any())) + when(reconciliationDispatcherMock.handleExecution(any())) .then( (Answer) invocationOnMock -> { Thread.sleep(FAKE_CONTROLLER_EXECUTION_DURATION); return PostExecutionControl.defaultDispatch(); }); Event event = prepareCREvent(); - defaultEventHandler.handleEvent(event); + eventProcessor.handleEvent(event); return event.getRelatedCustomResourceID(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcherTest.java similarity index 70% rename from operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java rename to operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcherTest.java index 1c651afa60..05b4b68ff4 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/EventDispatcherTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/ReconciliationDispatcherTest.java @@ -10,15 +10,15 @@ import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.TestUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.RetryInfo; -import io.javaoperatorsdk.operator.api.UpdateControl; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.monitoring.Metrics; -import io.javaoperatorsdk.operator.processing.EventDispatcher.CustomResourceFacade; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.processing.ReconciliationDispatcher.CustomResourceFacade; import io.javaoperatorsdk.operator.sample.observedgeneration.ObservedGenCustomResource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -35,49 +35,50 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class EventDispatcherTest { +class ReconciliationDispatcherTest { private static final String DEFAULT_FINALIZER = "javaoperatorsdk.io/finalizer"; private TestCustomResource testCustomResource; - private EventDispatcher eventDispatcher; - private final ResourceController controller = mock(ResourceController.class); + private ReconciliationDispatcher reconciliationDispatcher; + private final Reconciler controller = mock(Reconciler.class); private final ControllerConfiguration configuration = mock(ControllerConfiguration.class); private final ConfigurationService configService = mock(ConfigurationService.class); private final CustomResourceFacade customResourceFacade = - mock(EventDispatcher.CustomResourceFacade.class); + mock(ReconciliationDispatcher.CustomResourceFacade.class); @BeforeEach void setup() { testCustomResource = TestUtils.testCustomResource(); - eventDispatcher = init(testCustomResource, controller, configuration, customResourceFacade); + reconciliationDispatcher = + init(testCustomResource, controller, configuration, customResourceFacade); } - private > EventDispatcher init(R customResource, - ResourceController controller, ControllerConfiguration configuration, + private > ReconciliationDispatcher init(R customResource, + Reconciler reconciler, ControllerConfiguration configuration, CustomResourceFacade customResourceFacade) { when(configuration.getFinalizer()).thenReturn(DEFAULT_FINALIZER); when(configuration.useFinalizer()).thenCallRealMethod(); when(configuration.getName()).thenReturn("EventDispatcherTestController"); when(configService.getMetrics()).thenReturn(Metrics.NOOP); when(configuration.getConfigurationService()).thenReturn(configService); - when(controller.createOrUpdateResource(eq(customResource), any())) + when(reconciler.reconcile(eq(customResource), any())) .thenReturn(UpdateControl.updateCustomResource(customResource)); - when(controller.deleteResource(eq(customResource), any())) + when(reconciler.cleanup(eq(customResource), any())) .thenReturn(DeleteControl.defaultDelete()); when(customResourceFacade.replaceWithLock(any())).thenReturn(null); - ConfiguredController configuredController = - new ConfiguredController<>(controller, configuration, null); + Controller controller = + new Controller<>(reconciler, configuration, null); - return new EventDispatcher<>(configuredController, customResourceFacade); + return new ReconciliationDispatcher<>(controller, customResourceFacade); } @Test void addFinalizerOnNewResource() { assertFalse(testCustomResource.hasFinalizer(DEFAULT_FINALIZER)); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(controller, never()) - .createOrUpdateResource(ArgumentMatchers.eq(testCustomResource), any()); + .reconcile(ArgumentMatchers.eq(testCustomResource), any()); verify(customResourceFacade, times(1)) .replaceWithLock( argThat(testCustomResource -> testCustomResource.hasFinalizer(DEFAULT_FINALIZER))); @@ -87,19 +88,19 @@ void addFinalizerOnNewResource() { @Test void callCreateOrUpdateOnNewResourceIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(controller, times(1)) - .createOrUpdateResource(ArgumentMatchers.eq(testCustomResource), any()); + .reconcile(ArgumentMatchers.eq(testCustomResource), any()); } @Test void updatesOnlyStatusSubResourceIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - when(controller.createOrUpdateResource(eq(testCustomResource), any())) + when(controller.reconcile(eq(testCustomResource), any())) .thenReturn(UpdateControl.updateStatusSubResource(testCustomResource)); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(customResourceFacade, times(1)).updateStatus(testCustomResource); verify(customResourceFacade, never()).replaceWithLock(any()); @@ -109,11 +110,11 @@ void updatesOnlyStatusSubResourceIfFinalizerSet() { void updatesBothResourceAndStatusIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - when(controller.createOrUpdateResource(eq(testCustomResource), any())) + when(controller.reconcile(eq(testCustomResource), any())) .thenReturn(UpdateControl.updateCustomResourceAndStatus(testCustomResource)); when(customResourceFacade.replaceWithLock(testCustomResource)).thenReturn(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(customResourceFacade, times(1)).replaceWithLock(testCustomResource); verify(customResourceFacade, times(1)).updateStatus(testCustomResource); @@ -123,9 +124,9 @@ void updatesBothResourceAndStatusIfFinalizerSet() { void callCreateOrUpdateOnModifiedResourceIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(controller, times(1)) - .createOrUpdateResource(ArgumentMatchers.eq(testCustomResource), any()); + .reconcile(ArgumentMatchers.eq(testCustomResource), any()); } @Test @@ -134,9 +135,9 @@ void callsDeleteIfObjectHasFinalizerAndMarkedForDelete() { assertTrue(testCustomResource.addFinalizer(DEFAULT_FINALIZER)); markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); - verify(controller, times(1)).deleteResource(eq(testCustomResource), any()); + verify(controller, times(1)).cleanup(eq(testCustomResource), any()); } /** @@ -147,18 +148,18 @@ void callDeleteOnControllerIfMarkedForDeletionWhenNoFinalizerIsConfigured() { configureToNotUseFinalizer(); markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); - verify(controller).deleteResource(eq(testCustomResource), any()); + verify(controller).cleanup(eq(testCustomResource), any()); } @Test void doNotCallDeleteIfMarkedForDeletionWhenFinalizerHasAlreadyBeenRemoved() { markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); - verify(controller, never()).deleteResource(eq(testCustomResource), any()); + verify(controller, never()).cleanup(eq(testCustomResource), any()); } private void configureToNotUseFinalizer() { @@ -168,15 +169,16 @@ private void configureToNotUseFinalizer() { when(configService.getMetrics()).thenReturn(Metrics.NOOP); when(configuration.getConfigurationService()).thenReturn(configService); when(configuration.useFinalizer()).thenReturn(false); - eventDispatcher = new EventDispatcher(new ConfiguredController(controller, configuration, null), - customResourceFacade); + reconciliationDispatcher = + new ReconciliationDispatcher(new Controller(controller, configuration, null), + customResourceFacade); } @Test void doesNotAddFinalizerIfConfiguredNotTo() { configureToNotUseFinalizer(); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertEquals(0, testCustomResource.getMetadata().getFinalizers().size()); } @@ -186,7 +188,7 @@ void removesDefaultFinalizerOnDeleteIfSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertEquals(0, testCustomResource.getMetadata().getFinalizers().size()); verify(customResourceFacade, times(1)).replaceWithLock(any()); @@ -196,11 +198,11 @@ void removesDefaultFinalizerOnDeleteIfSet() { void doesNotRemovesTheSetFinalizerIfTheDeleteNotMethodInstructsIt() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - when(controller.deleteResource(eq(testCustomResource), any())) + when(controller.cleanup(eq(testCustomResource), any())) .thenReturn(DeleteControl.noFinalizerRemoval()); markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertEquals(1, testCustomResource.getMetadata().getFinalizers().size()); verify(customResourceFacade, never()).replaceWithLock(any()); @@ -210,10 +212,10 @@ void doesNotRemovesTheSetFinalizerIfTheDeleteNotMethodInstructsIt() { void doesNotUpdateTheResourceIfNoUpdateUpdateControlIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - when(controller.createOrUpdateResource(eq(testCustomResource), any())) + when(controller.reconcile(eq(testCustomResource), any())) .thenReturn(UpdateControl.noUpdate()); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(customResourceFacade, never()).replaceWithLock(any()); verify(customResourceFacade, never()).updateStatus(testCustomResource); } @@ -221,10 +223,10 @@ void doesNotUpdateTheResourceIfNoUpdateUpdateControlIfFinalizerSet() { @Test void addsFinalizerIfNotMarkedForDeletionAndEmptyCustomResourceReturned() { removeFinalizers(testCustomResource); - when(controller.createOrUpdateResource(eq(testCustomResource), any())) + when(controller.reconcile(eq(testCustomResource), any())) .thenReturn(UpdateControl.noUpdate()); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertEquals(1, testCustomResource.getMetadata().getFinalizers().size()); verify(customResourceFacade, times(1)).replaceWithLock(any()); @@ -235,26 +237,26 @@ void doesNotCallDeleteIfMarkedForDeletionButNotOurFinalizer() { removeFinalizers(testCustomResource); markForDeletion(testCustomResource); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); verify(customResourceFacade, never()).replaceWithLock(any()); - verify(controller, never()).deleteResource(eq(testCustomResource), any()); + verify(controller, never()).cleanup(eq(testCustomResource), any()); } @Test void executeControllerRegardlessGenerationInNonGenerationAwareModeIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); - verify(controller, times(2)).createOrUpdateResource(eq(testCustomResource), any()); + verify(controller, times(2)).reconcile(eq(testCustomResource), any()); } @Test void propagatesRetryInfoToContextIfFinalizerSet() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - eventDispatcher.handleExecution( + reconciliationDispatcher.handleExecution( new ExecutionScope( testCustomResource, new RetryInfo() { @@ -272,7 +274,7 @@ public boolean isLastAttempt() { ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); verify(controller, times(1)) - .createOrUpdateResource(eq(testCustomResource), contextArgumentCaptor.capture()); + .reconcile(eq(testCustomResource), contextArgumentCaptor.capture()); Context context = contextArgumentCaptor.getValue(); final var retryInfo = context.getRetryInfo().get(); assertThat(retryInfo.getAttemptCount()).isEqualTo(2); @@ -283,12 +285,12 @@ public boolean isLastAttempt() { void setReScheduleToPostExecutionControlFromUpdateControl() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); - when(controller.createOrUpdateResource(eq(testCustomResource), any())) + when(controller.reconcile(eq(testCustomResource), any())) .thenReturn( UpdateControl.updateStatusSubResource(testCustomResource).rescheduleAfter(1000L)); PostExecutionControl control = - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertThat(control.getReScheduleDelay().get()).isEqualTo(1000L); } @@ -298,11 +300,11 @@ void reScheduleOnDeleteWithoutFinalizerRemoval() { testCustomResource.addFinalizer(DEFAULT_FINALIZER); markForDeletion(testCustomResource); - when(controller.deleteResource(eq(testCustomResource), any())) + when(controller.cleanup(eq(testCustomResource), any())) .thenReturn(DeleteControl.noFinalizerRemoval().rescheduleAfter(1000L)); PostExecutionControl control = - eventDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); + reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource)); assertThat(control.getReScheduleDelay().get()).isEqualTo(1000L); } @@ -311,14 +313,14 @@ void reScheduleOnDeleteWithoutFinalizerRemoval() { void setObservedGenerationForStatusIfNeeded() { var observedGenResource = createObservedGenCustomResource(); - ResourceController lController = mock(ResourceController.class); + Reconciler lController = mock(Reconciler.class); ControllerConfiguration lConfiguration = mock(ControllerConfiguration.class); CustomResourceFacade lFacade = mock(CustomResourceFacade.class); var lDispatcher = init(observedGenResource, lController, lConfiguration, lFacade); when(lConfiguration.isGenerationAware()).thenReturn(true); - when(lController.createOrUpdateResource(eq(observedGenResource), any())) + when(lController.reconcile(eq(observedGenResource), any())) .thenReturn(UpdateControl.updateStatusSubResource(observedGenResource)); when(lFacade.updateStatus(observedGenResource)).thenReturn(observedGenResource); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManagerTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java similarity index 53% rename from operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManagerTest.java rename to operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java index d5b87bb5b5..76dc7e3411 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/DefaultEventSourceManagerTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java @@ -3,11 +3,12 @@ import java.io.IOException; import java.util.Set; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.TestUtils; -import io.javaoperatorsdk.operator.processing.DefaultEventHandler; +import io.javaoperatorsdk.operator.processing.EventProcessor; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.eq; @@ -15,46 +16,63 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -class DefaultEventSourceManagerTest { +class EventSourceManagerTest { - private DefaultEventHandler defaultEventHandlerMock = mock(DefaultEventHandler.class); - private DefaultEventSourceManager defaultEventSourceManager = - new DefaultEventSourceManager(defaultEventHandlerMock); + private EventProcessor eventProcessorMock = mock(EventProcessor.class); + private EventSourceManager eventSourceManager = + new EventSourceManager(); + + @BeforeEach + public void setup() { + eventSourceManager.setEventProcessor(eventProcessorMock); + } @Test public void registersEventSource() { EventSource eventSource = mock(EventSource.class); - defaultEventSourceManager.registerEventSource(eventSource); + eventSourceManager.registerEventSource(eventSource); Set registeredSources = - defaultEventSourceManager.getRegisteredEventSources(); + eventSourceManager.getRegisteredEventSources(); assertThat(registeredSources).hasSize(2); - verify(eventSource, times(1)).setEventHandler(eq(defaultEventHandlerMock)); - verify(eventSource, times(1)).start(); + verify(eventSource, times(1)).setEventHandler(eq(eventProcessorMock)); } @Test public void closeShouldCascadeToEventSources() throws IOException { EventSource eventSource = mock(EventSource.class); EventSource eventSource2 = mock(EventSource.class); - defaultEventSourceManager.registerEventSource(eventSource); - defaultEventSourceManager.registerEventSource(eventSource2); + eventSourceManager.registerEventSource(eventSource); + eventSourceManager.registerEventSource(eventSource2); - defaultEventSourceManager.stop(); + eventSourceManager.stop(); verify(eventSource, times(1)).stop(); verify(eventSource2, times(1)).stop(); } + @Test + public void startCascadesToEventSources() { + EventSource eventSource = mock(EventSource.class); + EventSource eventSource2 = mock(EventSource.class); + eventSourceManager.registerEventSource(eventSource); + eventSourceManager.registerEventSource(eventSource2); + + eventSourceManager.start(); + + verify(eventSource, times(1)).start(); + verify(eventSource2, times(1)).start(); + } + @Test public void deRegistersEventSources() { CustomResource customResource = TestUtils.testCustomResource(); EventSource eventSource = mock(EventSource.class); - defaultEventSourceManager.registerEventSource(eventSource); + eventSourceManager.registerEventSource(eventSource); - defaultEventSourceManager + eventSourceManager .cleanupForCustomResource(CustomResourceID.fromResource(customResource)); verify(eventSource, times(1)) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventFilterTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventFilterTest.java index 86081e4af1..119d683880 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventFilterTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventFilterTest.java @@ -15,7 +15,7 @@ import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.DefaultControllerConfiguration; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.event.EventHandler; import io.javaoperatorsdk.operator.sample.observedgeneration.ObservedGenCustomResource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -45,7 +45,7 @@ public void eventFilteredByCustomPredicate() { oldResource.getStatus().getConfigMapStatus(), newResource.getStatus().getConfigMapStatus())); - var controller = new TestConfiguredController(config); + var controller = new TestController(config); var eventSource = new CustomResourceEventSource<>(controller); eventSource.setEventHandler(eventHandler); @@ -73,7 +73,7 @@ public void eventFilteredByCustomPredicateAndGenerationAware() { oldResource.getStatus().getConfigMapStatus(), newResource.getStatus().getConfigMapStatus())); - var controller = new TestConfiguredController(config); + var controller = new TestController(config); var eventSource = new CustomResourceEventSource<>(controller); eventSource.setEventHandler(eventHandler); @@ -103,7 +103,7 @@ public void observedGenerationFiltering() { when(config.getConfigurationService().getResourceCloner()) .thenReturn(ConfigurationService.DEFAULT_CLONER); - var controller = new ObservedGenConfiguredController(config); + var controller = new ObservedGenController(config); var eventSource = new CustomResourceEventSource<>(controller); eventSource.setEventHandler(eventHandler); @@ -134,7 +134,7 @@ public void eventNotFilteredByCustomPredicateIfFinalizerIsRequired() { when(config.getConfigurationService().getResourceCloner()) .thenReturn(ConfigurationService.DEFAULT_CLONER); - var controller = new TestConfiguredController(config); + var controller = new TestController(config); var eventSource = new CustomResourceEventSource<>(controller); eventSource.setEventHandler(eventHandler); @@ -189,9 +189,9 @@ public ControllerConfig(String finalizer, boolean generationAware, } } - private static class TestConfiguredController extends ConfiguredController { + private static class TestController extends Controller { - public TestConfiguredController(ControllerConfiguration configuration) { + public TestController(ControllerConfiguration configuration) { super(null, configuration, null); } @@ -201,10 +201,10 @@ public MixedOperation { + private static class ObservedGenController + extends Controller { - public ObservedGenConfiguredController( + public ObservedGenController( ControllerConfiguration configuration) { super(null, configuration, null); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java index b8e4381f3b..61a550a652 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSourceTest.java @@ -13,7 +13,7 @@ import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.DefaultControllerConfiguration; import io.javaoperatorsdk.operator.api.monitoring.Metrics; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.event.CustomResourceID; import io.javaoperatorsdk.operator.processing.event.EventHandler; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -32,7 +32,7 @@ class CustomResourceEventSourceTest { EventHandler eventHandler = mock(EventHandler.class); private CustomResourceEventSource customResourceEventSource = - new CustomResourceEventSource<>(new TestConfiguredController(true)); + new CustomResourceEventSource<>(new TestController(true)); @BeforeEach public void setup() { @@ -89,7 +89,7 @@ public void normalExecutionIfGenerationChanges() { @Test public void handlesAllEventIfNotGenerationAware() { customResourceEventSource = - new CustomResourceEventSource<>(new TestConfiguredController(false)); + new CustomResourceEventSource<>(new TestController(false)); setup(); TestCustomResource customResource1 = TestUtils.testCustomResource(); @@ -136,9 +136,9 @@ public void notHandlesNextEventIfNotWhitelisted() { verify(eventHandler, times(0)).handleEvent(any()); } - private static class TestConfiguredController extends ConfiguredController { + private static class TestController extends Controller { - public TestConfiguredController(boolean generationAware) { + public TestController(boolean generationAware) { super(null, new TestConfiguration(generationAware), null); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceSelectorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceSelectorTest.java index 7fcda72bb4..6a1e5144e0 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceSelectorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceSelectorTest.java @@ -22,13 +22,12 @@ import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.javaoperatorsdk.operator.Operator; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; import io.javaoperatorsdk.operator.api.config.ConfigurationService; -import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.Version; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; import static org.assertj.core.api.Assertions.assertThat; @@ -121,7 +120,7 @@ void resourceWatchedByLabel() { NAMESPACE)); await() - .atMost(325, TimeUnit.SECONDS) + .atMost(5, TimeUnit.SECONDS) .pollInterval(100, TimeUnit.MILLISECONDS) .until(() -> c1.get() == 1 && c1err.get() == 0); await() @@ -145,7 +144,9 @@ public TestCustomResource newMyResource(String app, String namespace) { return resource; } - public static class MyConfiguration implements ControllerConfiguration { + public static class MyConfiguration + implements + io.javaoperatorsdk.operator.api.config.ControllerConfiguration { private final String labelSelector; private final ConfigurationService service; @@ -161,7 +162,7 @@ public String getLabelSelector() { } @Override - public String getAssociatedControllerClassName() { + public String getAssociatedReconcilerClassName() { return MyController.class.getCanonicalName(); } @@ -176,8 +177,8 @@ public ConfigurationService getConfigurationService() { } } - @Controller(namespaces = NAMESPACE) - public static class MyController implements ResourceController { + @ControllerConfiguration(namespaces = NAMESPACE) + public static class MyController implements Reconciler { private final Consumer consumer; @@ -186,7 +187,7 @@ public MyController(Consumer consumer) { } @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( TestCustomResource resource, Context context) { LOGGER.info("Received event on: {}", resource); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/DuplicateCRController.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/DuplicateCRController.java index 443c4c21cc..86f0c36261 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/DuplicateCRController.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/DuplicateCRController.java @@ -1,15 +1,15 @@ package io.javaoperatorsdk.operator.sample.simple; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -@Controller -public class DuplicateCRController implements ResourceController { +@ControllerConfiguration +public class DuplicateCRController implements Reconciler { @Override - public UpdateControl createOrUpdateResource(TestCustomResource resource, + public UpdateControl reconcile(TestCustomResource resource, Context context) { return UpdateControl.noUpdate(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconciler.java similarity index 81% rename from operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java rename to operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconciler.java index eba0859a9c..10b76b8cdc 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconciler.java @@ -11,16 +11,13 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -@Controller(generationAwareEventProcessing = false) -public class TestCustomResourceController implements ResourceController { +@ControllerConfiguration(generationAwareEventProcessing = false) +public class TestCustomReconciler implements Reconciler { - private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); + private static final Logger log = LoggerFactory.getLogger(TestCustomReconciler.class); public static final String CRD_NAME = CustomResource.getCRDName(TestCustomResource.class); public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; @@ -28,17 +25,17 @@ public class TestCustomResourceController implements ResourceController createOrUpdateResource( + public UpdateControl reconcile( TestCustomResource resource, Context context) { if (!resource.getMetadata().getFinalizers().contains(FINALIZER_NAME)) { throw new IllegalStateException("Finalizer is not present."); @@ -84,7 +81,7 @@ public UpdateControl createOrUpdateResource( .createOrReplace(existingConfigMap); } else { Map labels = new HashMap<>(); - labels.put("managedBy", TestCustomResourceController.class.getSimpleName()); + labels.put("managedBy", TestCustomReconciler.class.getSimpleName()); ConfigMap newConfigMap = new ConfigMapBuilder() .withMetadata( diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconcilerV2.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconcilerV2.java new file mode 100644 index 0000000000..bab22f309a --- /dev/null +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomReconcilerV2.java @@ -0,0 +1,16 @@ +package io.javaoperatorsdk.operator.sample.simple; + +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; + +@ControllerConfiguration +public class TestCustomReconcilerV2 implements Reconciler { + + @Override + public UpdateControl reconcile(TestCustomResourceV2 resource, + Context context) { + return UpdateControl.noUpdate(); + } +} diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceControllerV2.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceControllerV2.java deleted file mode 100644 index 29a89381e2..0000000000 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceControllerV2.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.javaoperatorsdk.operator.sample.simple; - -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; - -@Controller -public class TestCustomResourceControllerV2 implements ResourceController { - - @Override - public UpdateControl createOrUpdateResource(TestCustomResourceV2 resource, - Context context) { - return UpdateControl.noUpdate(); - } -} diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java index b48aca918b..5fed85dc67 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java @@ -26,11 +26,11 @@ import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; import io.fabric8.kubernetes.client.utils.Utils; import io.javaoperatorsdk.operator.Operator; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.BaseConfigurationService; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.Version; -import io.javaoperatorsdk.operator.processing.ConfiguredController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.retry.Retry; import static io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider.override; @@ -106,16 +106,16 @@ public String getNamespace() { } @SuppressWarnings({"rawtypes"}) - public List getControllers() { + public List getControllers() { return operator.getControllers().stream() - .map(ConfiguredController::getController) + .map(Controller::getReconciler) .collect(Collectors.toUnmodifiableList()); } @SuppressWarnings({"rawtypes"}) - public T getControllerOfType(Class type) { + public T getControllerOfType(Class type) { return operator.getControllers().stream() - .map(ConfiguredController::getController) + .map(Controller::getReconciler) .filter(type::isInstance) .map(type::cast) .findFirst() @@ -167,6 +167,12 @@ protected void before(ExtensionContext context) { try (InputStream is = getClass().getResourceAsStream(path)) { kubernetesClient.load(is).createOrReplace(); + // this fixes an issue with CRD registration, integration tests were failing, since the CRD + // was not found yet + // when the operator started. This seems to be fixing this issue (maybe a problem with + // minikube?) + Thread.sleep(2000); + LOGGER.debug("Applied CRD with name: {}", config.getCRDName()); } catch (Exception ex) { throw new IllegalStateException("Cannot apply CRD yaml: " + path, ex); } @@ -242,19 +248,19 @@ public Builder withConfigurationService(ConfigurationService value) { } @SuppressWarnings("rawtypes") - public Builder withController(ResourceController value) { + public Builder withReconciler(Reconciler value) { controllers.add(new ControllerSpec(value, null)); return this; } @SuppressWarnings("rawtypes") - public Builder withController(ResourceController value, Retry retry) { + public Builder withReconciler(Reconciler value, Retry retry) { controllers.add(new ControllerSpec(value, retry)); return this; } @SuppressWarnings("rawtypes") - public Builder withController(Class value) { + public Builder withReconciler(Class value) { try { controllers.add(new ControllerSpec(value.getConstructor().newInstance(), null)); } catch (Exception e) { @@ -274,11 +280,11 @@ public OperatorExtension build() { @SuppressWarnings("rawtypes") private static class ControllerSpec { - final ResourceController controller; + final Reconciler controller; final Retry retry; public ControllerSpec( - ResourceController controller, + Reconciler controller, Retry retry) { this.controller = controller; this.retry = retry; diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java index 34ca56378f..4539873955 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java @@ -5,28 +5,27 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.ConfigurationService; -import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEventFilters; public class AnnotationConfiguration> - implements ControllerConfiguration { + implements io.javaoperatorsdk.operator.api.config.ControllerConfiguration { - private final ResourceController controller; - private final Controller annotation; + private final Reconciler reconciler; + private final ControllerConfiguration annotation; private ConfigurationService service; - public AnnotationConfiguration(ResourceController controller) { - this.controller = controller; - this.annotation = controller.getClass().getAnnotation(Controller.class); + public AnnotationConfiguration(Reconciler reconciler) { + this.reconciler = reconciler; + this.annotation = reconciler.getClass().getAnnotation(ControllerConfiguration.class); } @Override public String getName() { - return ControllerUtils.getNameFor(controller); + return ControllerUtils.getNameFor(reconciler); } @Override @@ -40,22 +39,23 @@ public String getFinalizer() { @Override public boolean isGenerationAware() { - return valueOrDefault(annotation, Controller::generationAwareEventProcessing, true); + return valueOrDefault(annotation, ControllerConfiguration::generationAwareEventProcessing, + true); } @Override public Class getCustomResourceClass() { - return RuntimeControllerMetadata.getCustomResourceClass(controller); + return RuntimeControllerMetadata.getCustomResourceClass(reconciler); } @Override public Set getNamespaces() { - return Set.of(valueOrDefault(annotation, Controller::namespaces, new String[] {})); + return Set.of(valueOrDefault(annotation, ControllerConfiguration::namespaces, new String[] {})); } @Override public String getLabelSelector() { - return valueOrDefault(annotation, Controller::labelSelector, ""); + return valueOrDefault(annotation, ControllerConfiguration::labelSelector, ""); } @Override @@ -69,8 +69,8 @@ public void setConfigurationService(ConfigurationService service) { } @Override - public String getAssociatedControllerClassName() { - return controller.getClass().getCanonicalName(); + public String getAssociatedReconcilerClassName() { + return reconciler.getClass().getCanonicalName(); } @SuppressWarnings("unchecked") @@ -79,7 +79,8 @@ public CustomResourceEventFilter getEventFilter() { CustomResourceEventFilter answer = null; Class>[] filterTypes = - (Class>[]) valueOrDefault(annotation, Controller::eventFilters, + (Class>[]) valueOrDefault(annotation, + ControllerConfiguration::eventFilters, new Object[] {}); if (filterTypes.length > 0) { for (var filterType : filterTypes) { @@ -101,12 +102,13 @@ public CustomResourceEventFilter getEventFilter() { : CustomResourceEventFilters.passthrough(); } - public static T valueOrDefault(Controller controller, Function mapper, + public static T valueOrDefault(ControllerConfiguration controllerConfiguration, + Function mapper, T defaultValue) { - if (controller == null) { + if (controllerConfiguration == null) { return defaultValue; } else { - return mapper.apply(controller); + return mapper.apply(controllerConfiguration); } } } diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessor.java similarity index 89% rename from operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java rename to operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessor.java index aaa55a01e8..df509f942e 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessor.java @@ -16,17 +16,17 @@ import javax.lang.model.type.TypeMirror; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import com.google.auto.service.AutoService; import com.squareup.javapoet.TypeName; -import static io.javaoperatorsdk.operator.config.runtime.RuntimeControllerMetadata.CONTROLLERS_RESOURCE_PATH; +import static io.javaoperatorsdk.operator.config.runtime.RuntimeControllerMetadata.RECONCILERS_RESOURCE_PATH; -@SupportedAnnotationTypes("io.javaoperatorsdk.operator.api.Controller") +@SupportedAnnotationTypes("io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration") @SupportedSourceVersion(SourceVersion.RELEASE_11) @AutoService(Processor.class) -public class ControllerAnnotationProcessor extends AbstractProcessor { +public class ControllerConfigurationAnnotationProcessor extends AbstractProcessor { private AccumulativeMappingWriter controllersResourceWriter; private TypeParameterResolver typeParameterResolver; @@ -35,7 +35,7 @@ public class ControllerAnnotationProcessor extends AbstractProcessor { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); controllersResourceWriter = - new AccumulativeMappingWriter(CONTROLLERS_RESOURCE_PATH, processingEnv) + new AccumulativeMappingWriter(RECONCILERS_RESOURCE_PATH, processingEnv) .loadExistingMappings(); typeParameterResolver = initializeResolver(processingEnv); @@ -66,7 +66,7 @@ private TypeParameterResolver initializeResolver(ProcessingEnvironment processin .getDeclaredType( processingEnv .getElementUtils() - .getTypeElement(ResourceController.class.getCanonicalName()), + .getTypeElement(Reconciler.class.getCanonicalName()), processingEnv.getTypeUtils().getWildcardType(null, null)); return new TypeParameterResolver(resourceControllerType, 0); } diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java index 60e65a06f4..bcd2ed2f59 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java @@ -1,10 +1,10 @@ package io.javaoperatorsdk.operator.config.runtime; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.BaseConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.Utils; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; public class DefaultConfigurationService extends BaseConfigurationService { @@ -20,27 +20,27 @@ public static DefaultConfigurationService instance() { @Override public > ControllerConfiguration getConfigurationFor( - ResourceController controller) { - return getConfigurationFor(controller, true); + Reconciler reconciler) { + return getConfigurationFor(reconciler, true); } > ControllerConfiguration getConfigurationFor( - ResourceController controller, boolean createIfNeeded) { - var config = super.getConfigurationFor(controller); + Reconciler reconciler, boolean createIfNeeded) { + var config = super.getConfigurationFor(reconciler); if (config == null) { if (createIfNeeded) { // create the configuration on demand and register it - config = new AnnotationConfiguration<>(controller); + config = new AnnotationConfiguration<>(reconciler); register(config); getLogger().info( "Created configuration for controller {} with name {}", - controller.getClass().getName(), + reconciler.getClass().getName(), config.getName()); } } else { // check that we don't have a controller name collision - final var newControllerClassName = controller.getClass().getCanonicalName(); - if (!config.getAssociatedControllerClassName().equals(newControllerClassName)) { + final var newControllerClassName = reconciler.getClass().getCanonicalName(); + if (!config.getAssociatedReconcilerClassName().equals(newControllerClassName)) { throwExceptionOnNameCollision(newControllerClassName, config); } } diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java index 1536d681f3..68ba58f1c1 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/RuntimeControllerMetadata.java @@ -3,29 +3,29 @@ import java.util.Map; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @SuppressWarnings("rawtypes") public class RuntimeControllerMetadata { - public static final String CONTROLLERS_RESOURCE_PATH = "javaoperatorsdk/controllers"; - private static final Map, Class> controllerToCustomResourceMappings; + public static final String RECONCILERS_RESOURCE_PATH = "javaoperatorsdk/reconcilers"; + private static final Map, Class> controllerToCustomResourceMappings; static { controllerToCustomResourceMappings = ClassMappingProvider.provide( - CONTROLLERS_RESOURCE_PATH, ResourceController.class, CustomResource.class); + RECONCILERS_RESOURCE_PATH, Reconciler.class, CustomResource.class); } static > Class getCustomResourceClass( - ResourceController controller) { + Reconciler reconciler) { final Class customResourceClass = - controllerToCustomResourceMappings.get(controller.getClass()); + controllerToCustomResourceMappings.get(reconciler.getClass()); if (customResourceClass == null) { throw new IllegalArgumentException( String.format( "No custom resource has been found for controller %s", - controller.getClass().getCanonicalName())); + reconciler.getClass().getCanonicalName())); } return (Class) customResourceClass; } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java index 4332faf413..458e2d12eb 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java @@ -13,7 +13,7 @@ import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; -import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController; +import io.javaoperatorsdk.operator.sample.simple.TestReconciler; import io.javaoperatorsdk.operator.support.TestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +30,7 @@ public class ConcurrencyIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(new TestCustomResourceController(true)) + .withReconciler(new TestReconciler(true)) .build(); @Test @@ -48,7 +48,7 @@ public void manyResourcesGetCreatedUpdatedAndDeleted() throws InterruptedExcepti List items = operator.resources(ConfigMap.class) .withLabel( - "managedBy", TestCustomResourceController.class.getSimpleName()) + "managedBy", TestReconciler.class.getSimpleName()) .list() .getItems(); assertThat(items).hasSize(NUMBER_OF_RESOURCES_CREATED); @@ -81,7 +81,7 @@ public void manyResourcesGetCreatedUpdatedAndDeleted() throws InterruptedExcepti List items = operator.resources(ConfigMap.class) .withLabel( - "managedBy", TestCustomResourceController.class.getSimpleName()) + "managedBy", TestReconciler.class.getSimpleName()) .list() .getItems(); // reducing configmaps to names only - better for debugging diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java index cb3cdbb704..b1f783b958 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java @@ -9,7 +9,7 @@ import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; -import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController; +import io.javaoperatorsdk.operator.sample.simple.TestReconciler; import io.javaoperatorsdk.operator.support.TestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -20,12 +20,12 @@ public class ControllerExecutionIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(new TestCustomResourceController(true)) + .withReconciler(new TestReconciler(true)) .build(); @Test public void configMapGetsCreatedForTestCustomResource() { - operator.getControllerOfType(TestCustomResourceController.class).setUpdateStatus(true); + operator.getControllerOfType(TestReconciler.class).setUpdateStatus(true); TestCustomResource resource = TestUtils.testCustomResource(); operator.create(TestCustomResource.class, resource); @@ -37,7 +37,7 @@ public void configMapGetsCreatedForTestCustomResource() { @Test public void eventIsSkippedChangedOnMetadataOnlyUpdate() { - operator.getControllerOfType(TestCustomResourceController.class).setUpdateStatus(false); + operator.getControllerOfType(TestReconciler.class).setUpdateStatus(false); TestCustomResource resource = TestUtils.testCustomResource(); operator.create(TestCustomResource.class, resource); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java index eb556535a1..509cb74d42 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java @@ -8,8 +8,8 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; +import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomReconciler; import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResource; -import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResourceController; import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResourceSpec; import io.javaoperatorsdk.operator.support.TestUtils; @@ -21,7 +21,7 @@ public class EventSourceIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(EventSourceTestCustomResourceController.class) + .withReconciler(EventSourceTestCustomReconciler.class) .build(); @Test @@ -33,7 +33,7 @@ public void receivingPeriodicEvents() { await() .atMost(5, TimeUnit.SECONDS) .pollInterval( - EventSourceTestCustomResourceController.TIMER_PERIOD / 2, TimeUnit.MILLISECONDS) + EventSourceTestCustomReconciler.TIMER_PERIOD / 2, TimeUnit.MILLISECONDS) .untilAsserted( () -> assertThat(TestUtils.getNumberOfExecutions(operator)) .isGreaterThanOrEqualTo(4)); @@ -45,7 +45,7 @@ public EventSourceTestCustomResource createTestCustomResource(String id) { new ObjectMetaBuilder() .withName("eventsource-" + id) .withNamespace(operator.getNamespace()) - .withFinalizers(EventSourceTestCustomResourceController.FINALIZER_NAME) + .withFinalizers(EventSourceTestCustomReconciler.FINALIZER_NAME) .build()); resource.setKind("Eventsourcesample"); resource.setSpec(new EventSourceTestCustomResourceSpec()); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/InformerEventSourceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/InformerEventSourceIT.java index 1cb3fa7096..d290d06ecd 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/InformerEventSourceIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/InformerEventSourceIT.java @@ -10,11 +10,11 @@ import io.fabric8.kubernetes.api.model.ObjectMeta; import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; +import io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomReconciler; import io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomResource; -import io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomResourceController; -import static io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomResourceController.RELATED_RESOURCE_UID; -import static io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomResourceController.TARGET_CONFIG_MAP_KEY; +import static io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomReconciler.RELATED_RESOURCE_UID; +import static io.javaoperatorsdk.operator.sample.informereventsource.InformerEventSourceTestCustomReconciler.TARGET_CONFIG_MAP_KEY; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -28,7 +28,7 @@ public class InformerEventSourceIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(new InformerEventSourceTestCustomResourceController()) + .withReconciler(new InformerEventSourceTestCustomReconciler()) .build(); @Test diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java index e5fcde6934..cb7109f8cf 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java @@ -9,8 +9,8 @@ import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; import io.javaoperatorsdk.operator.processing.retry.GenericRetry; +import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomReconciler; import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResource; -import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceController; import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceSpec; import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceStatus; import io.javaoperatorsdk.operator.support.TestUtils; @@ -25,8 +25,8 @@ public class RetryIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController( - new RetryTestCustomResourceController(), + .withReconciler( + new RetryTestCustomReconciler(), new GenericRetry().setInitialInterval(RETRY_INTERVAL).withLinearRetry() .setMaxAttempts(5)) .build(); @@ -40,7 +40,7 @@ public void retryFailedExecution() { await("cr status updated") .pollDelay( - RETRY_INTERVAL * (RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 2), + RETRY_INTERVAL * (RetryTestCustomReconciler.NUMBER_FAILED_EXECUTIONS + 2), TimeUnit.MILLISECONDS) .pollInterval( RETRY_INTERVAL, @@ -49,7 +49,7 @@ public void retryFailedExecution() { .untilAsserted(() -> { assertThat( TestUtils.getNumberOfExecutions(operator)) - .isEqualTo(RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 1); + .isEqualTo(RetryTestCustomReconciler.NUMBER_FAILED_EXECUTIONS + 1); RetryTestCustomResource finalResource = operator.get(RetryTestCustomResource.class, @@ -64,7 +64,7 @@ public RetryTestCustomResource createTestCustomResource(String id) { resource.setMetadata( new ObjectMetaBuilder() .withName("retrysource-" + id) - .withFinalizers(RetryTestCustomResourceController.FINALIZER_NAME) + .withFinalizers(RetryTestCustomReconciler.FINALIZER_NAME) .build()); resource.setKind("retrysample"); resource.setSpec(new RetryTestCustomResourceSpec()); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java index 1cee81c054..5998502f32 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java @@ -9,8 +9,8 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; +import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomReconciler; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResource; -import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController; import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec; import io.javaoperatorsdk.operator.support.TestUtils; @@ -24,7 +24,7 @@ public class SubResourceUpdateIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(SubResourceTestCustomResourceController.class) + .withReconciler(SubResourceTestCustomReconciler.class) .build(); @Test @@ -113,7 +113,7 @@ public SubResourceTestCustomResource createTestCustomResource(String id) { resource.setMetadata( new ObjectMetaBuilder() .withName("subresource-" + id) - .withFinalizers(SubResourceTestCustomResourceController.FINALIZER_NAME) + .withFinalizers(SubResourceTestCustomReconciler.FINALIZER_NAME) .build()); resource.setKind("SubresourceSample"); resource.setSpec(new SubResourceTestCustomResourceSpec()); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java index 7d08ca6110..2a479d47df 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java @@ -8,8 +8,8 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; import io.javaoperatorsdk.operator.junit.OperatorExtension; +import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomReconciler; import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResource; -import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceController; import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceSpec; import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceStatus; import io.javaoperatorsdk.operator.support.TestUtils; @@ -22,7 +22,7 @@ public class UpdatingResAndSubResIT { OperatorExtension operator = OperatorExtension.builder() .withConfigurationService(DefaultConfigurationService.instance()) - .withController(DoubleUpdateTestCustomResourceController.class) + .withReconciler(DoubleUpdateTestCustomReconciler.class) .build(); @Test @@ -47,7 +47,7 @@ public void updatesSubResourceStatus() { customResource .getMetadata() .getAnnotations() - .get(DoubleUpdateTestCustomResourceController.TEST_ANNOTATION)) + .get(DoubleUpdateTestCustomReconciler.TEST_ANNOTATION)) .isNotNull(); } @@ -73,7 +73,6 @@ void awaitStatusUpdated(String name) { public DoubleUpdateTestCustomResource createTestCustomResource(String id) { DoubleUpdateTestCustomResource resource = new DoubleUpdateTestCustomResource(); resource.setMetadata(new ObjectMetaBuilder().withName("doubleupdateresource-" + id).build()); - resource.setKind("DoubleUpdateSample"); resource.setSpec(new DoubleUpdateTestCustomResourceSpec()); resource.getSpec().setValue(id); return resource; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessorTest.java similarity index 71% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessorTest.java index e2f750b5d1..ce9637af9e 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessorTest.java @@ -7,16 +7,16 @@ import com.google.testing.compile.Compiler; import com.google.testing.compile.JavaFileObjects; -class ControllerAnnotationProcessorTest { +class ControllerConfigurationAnnotationProcessorTest { @Test public void generateCorrectDoneableClassIfInterfaceIsSecond() { Compilation compilation = Compiler.javac() - .withProcessors(new ControllerAnnotationProcessor()) + .withProcessors(new ControllerConfigurationAnnotationProcessor()) .compile( JavaFileObjects.forResource( - "compile-fixtures/ControllerImplemented2Interfaces.java")); + "compile-fixtures/ReconcilerImplemented2Interfaces.java")); CompilationSubject.assertThat(compilation).succeeded(); } @@ -24,11 +24,11 @@ public void generateCorrectDoneableClassIfInterfaceIsSecond() { public void generateCorrectDoneableClassIfThereIsAbstractBaseController() { Compilation compilation = Compiler.javac() - .withProcessors(new ControllerAnnotationProcessor()) + .withProcessors(new ControllerConfigurationAnnotationProcessor()) .compile( - JavaFileObjects.forResource("compile-fixtures/AbstractController.java"), + JavaFileObjects.forResource("compile-fixtures/AbstractReconciler.java"), JavaFileObjects.forResource( - "compile-fixtures/ControllerImplementedIntermediateAbstractClass.java")); + "compile-fixtures/ReconcilerImplementedIntermediateAbstractClass.java")); CompilationSubject.assertThat(compilation).succeeded(); } @@ -36,11 +36,11 @@ public void generateCorrectDoneableClassIfThereIsAbstractBaseController() { public void generateDoneableClasswithMultilevelHierarchy() { Compilation compilation = Compiler.javac() - .withProcessors(new ControllerAnnotationProcessor()) + .withProcessors(new ControllerConfigurationAnnotationProcessor()) .compile( - JavaFileObjects.forResource("compile-fixtures/AdditionalControllerInterface.java"), - JavaFileObjects.forResource("compile-fixtures/MultilevelAbstractController.java"), - JavaFileObjects.forResource("compile-fixtures/MultilevelController.java")); + JavaFileObjects.forResource("compile-fixtures/AdditionalReconcilerInterface.java"), + JavaFileObjects.forResource("compile-fixtures/MultilevelAbstractReconciler.java"), + JavaFileObjects.forResource("compile-fixtures/MultilevelReconciler.java")); CompilationSubject.assertThat(compilation).succeeded(); } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java index 64623470ae..425f822ddc 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java @@ -12,10 +12,10 @@ import io.fabric8.kubernetes.model.annotation.Group; import io.fabric8.kubernetes.model.annotation.Version; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -74,10 +74,11 @@ void attemptingToRetrieveAnUnknownControllerShouldLogWarning() { @Test public void returnsValuesFromControllerAnnotationFinalizer() { - final var controller = new TestCustomResourceController(); + final var reconciler = new TestCustomReconciler(); final var configuration = - DefaultConfigurationService.instance().getConfigurationFor(controller); - assertEquals(CustomResource.getCRDName(TestCustomResource.class), configuration.getCRDName()); + DefaultConfigurationService.instance().getConfigurationFor(reconciler); + assertEquals(CustomResource.getCRDName(TestCustomResource.class), + configuration.getCRDName()); assertEquals( ControllerUtils.getDefaultFinalizerName(configuration.getCRDName()), configuration.getFinalizer()); @@ -87,29 +88,29 @@ public void returnsValuesFromControllerAnnotationFinalizer() { @Test public void returnCustomerFinalizerNameIfSet() { - final var controller = new TestCustomFinalizerController(); + final var reconciler = new TestCustomFinalizerReconciler(); final var configuration = - DefaultConfigurationService.instance().getConfigurationFor(controller); + DefaultConfigurationService.instance().getConfigurationFor(reconciler); assertEquals(CUSTOM_FINALIZER_NAME, configuration.getFinalizer()); } @Test public void supportsInnerClassCustomResources() { - final var controller = new TestCustomFinalizerController(); + final var controller = new TestCustomFinalizerReconciler(); assertDoesNotThrow( () -> { DefaultConfigurationService.instance() .getConfigurationFor(controller) - .getAssociatedControllerClassName(); + .getAssociatedReconcilerClassName(); }); } - @Controller(finalizerName = CUSTOM_FINALIZER_NAME) - static class TestCustomFinalizerController - implements ResourceController { + @ControllerConfiguration(finalizerName = CUSTOM_FINALIZER_NAME) + static class TestCustomFinalizerReconciler + implements Reconciler { @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( InnerCustomResource resource, Context context) { return null; } @@ -120,23 +121,23 @@ public static class InnerCustomResource extends CustomResource { } } - @Controller(name = NotAutomaticallyCreated.NAME) - static class NotAutomaticallyCreated implements ResourceController { + @ControllerConfiguration(name = NotAutomaticallyCreated.NAME) + static class NotAutomaticallyCreated implements Reconciler { public static final String NAME = "should-be-logged"; @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( TestCustomResource resource, Context context) { return null; } } - @Controller(generationAwareEventProcessing = false, name = "test") - static class TestCustomResourceController implements ResourceController { + @ControllerConfiguration(generationAwareEventProcessing = false, name = "test") + static class TestCustomReconciler implements Reconciler { @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( TestCustomResource resource, Context context) { return null; } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java similarity index 71% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java index df9f3dcf10..2f65be15a6 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomReconciler.java @@ -6,24 +6,24 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; -@Controller -public class DoubleUpdateTestCustomResourceController - implements ResourceController, TestExecutionInfoProvider { +@ControllerConfiguration +public class DoubleUpdateTestCustomReconciler + implements Reconciler, TestExecutionInfoProvider { private static final Logger log = - LoggerFactory.getLogger(DoubleUpdateTestCustomResourceController.class); + LoggerFactory.getLogger(DoubleUpdateTestCustomReconciler.class); public static final String TEST_ANNOTATION = "TestAnnotation"; public static final String TEST_ANNOTATION_VALUE = "TestAnnotationValue"; private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( DoubleUpdateTestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java similarity index 58% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java index bc26fc3e47..c8a5c673c0 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomReconciler.java @@ -4,18 +4,13 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.EventSourceInitializer; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; -import io.javaoperatorsdk.operator.processing.event.EventSourceManager; -import io.javaoperatorsdk.operator.processing.event.internal.TimerEventSource; +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; -@Controller -public class EventSourceTestCustomResourceController - implements ResourceController, EventSourceInitializer, +@ControllerConfiguration +public class EventSourceTestCustomReconciler + implements Reconciler, TestExecutionInfoProvider { public static final String FINALIZER_NAME = @@ -23,16 +18,9 @@ public class EventSourceTestCustomResourceController CustomResource.getCRDName(EventSourceTestCustomResource.class)); public static final int TIMER_PERIOD = 500; private final AtomicInteger numberOfExecutions = new AtomicInteger(0); - private final TimerEventSource timerEventSource = - new TimerEventSource<>(); @Override - public void prepareEventSources(EventSourceManager eventSourceManager) { - eventSourceManager.registerEventSource(timerEventSource); - } - - @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( EventSourceTestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java similarity index 66% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java index ad2a2dc863..a0b7805ccf 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java @@ -5,29 +5,29 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.EventSourceInitializer; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; -import io.javaoperatorsdk.operator.processing.event.EventSourceManager; +import io.javaoperatorsdk.operator.processing.event.EventSourceRegistry; import io.javaoperatorsdk.operator.processing.event.internal.InformerEventSource; import io.javaoperatorsdk.operator.processing.event.internal.Mappers; -import static io.javaoperatorsdk.operator.api.Controller.NO_FINALIZER; +import static io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.NO_FINALIZER; /** * Copies the config map value from spec into status. The main purpose is to test and demonstrate * sample usage of InformerEventSource */ -@Controller(finalizerName = NO_FINALIZER) -public class InformerEventSourceTestCustomResourceController implements - ResourceController, KubernetesClientAware, +@ControllerConfiguration(finalizerName = NO_FINALIZER) +public class InformerEventSourceTestCustomReconciler implements + Reconciler, KubernetesClientAware, EventSourceInitializer { private static final Logger LOGGER = - LoggerFactory.getLogger(InformerEventSourceTestCustomResourceController.class); + LoggerFactory.getLogger(InformerEventSourceTestCustomReconciler.class); public static final String RELATED_RESOURCE_UID = "relatedResourceName"; public static final String TARGET_CONFIG_MAP_KEY = "targetStatus"; @@ -36,14 +36,14 @@ public class InformerEventSourceTestCustomResourceController implements private InformerEventSource eventSource; @Override - public void prepareEventSources(EventSourceManager eventSourceManager) { + public void prepareEventSources(EventSourceRegistry eventSourceRegistry) { eventSource = new InformerEventSource<>(kubernetesClient, ConfigMap.class, Mappers.fromAnnotation(RELATED_RESOURCE_UID)); - eventSourceManager.registerEventSource(eventSource); + eventSourceRegistry.registerEventSource(eventSource); } @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( InformerEventSourceTestCustomResource resource, Context context) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java similarity index 77% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java index cf24ee9484..5ae059342e 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomReconciler.java @@ -7,15 +7,15 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; -@Controller -public class RetryTestCustomResourceController - implements ResourceController, TestExecutionInfoProvider { +@ControllerConfiguration +public class RetryTestCustomReconciler + implements Reconciler, TestExecutionInfoProvider { public static final int NUMBER_FAILED_EXECUTIONS = 2; @@ -23,11 +23,11 @@ public class RetryTestCustomResourceController ControllerUtils.getDefaultFinalizerName( CustomResource.getCRDName(RetryTestCustomResource.class)); private static final Logger log = - LoggerFactory.getLogger(RetryTestCustomResourceController.class); + LoggerFactory.getLogger(RetryTestCustomReconciler.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( RetryTestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java similarity index 84% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java index 6aefaa3922..30f57fd8c6 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestReconciler.java @@ -13,20 +13,17 @@ import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; -@Controller(generationAwareEventProcessing = false) -public class TestCustomResourceController - implements ResourceController, TestExecutionInfoProvider, +@ControllerConfiguration(generationAwareEventProcessing = false) +public class TestReconciler + implements Reconciler, TestExecutionInfoProvider, KubernetesClientAware { - private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); + private static final Logger log = LoggerFactory.getLogger(TestReconciler.class); public static final String FINALIZER_NAME = ControllerUtils.getDefaultFinalizerName(CustomResource.getCRDName(TestCustomResource.class)); @@ -35,11 +32,11 @@ public class TestCustomResourceController private KubernetesClient kubernetesClient; private boolean updateStatus; - public TestCustomResourceController() { + public TestReconciler() { this(true); } - public TestCustomResourceController(boolean updateStatus) { + public TestReconciler(boolean updateStatus) { this.updateStatus = updateStatus; } @@ -62,7 +59,7 @@ public void setKubernetesClient(KubernetesClient kubernetesClient) { } @Override - public DeleteControl deleteResource( + public DeleteControl cleanup( TestCustomResource resource, Context context) { Boolean delete = kubernetesClient @@ -85,7 +82,7 @@ public DeleteControl deleteResource( } @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( TestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); if (!resource.getMetadata().getFinalizers().contains(FINALIZER_NAME)) { @@ -109,7 +106,7 @@ public UpdateControl createOrUpdateResource( .createOrReplace(existingConfigMap); } else { Map labels = new HashMap<>(); - labels.put("managedBy", TestCustomResourceController.class.getSimpleName()); + labels.put("managedBy", TestReconciler.class.getSimpleName()); ConfigMap newConfigMap = new ConfigMapBuilder() .withMetadata( diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java similarity index 71% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java index f04958cbcd..9eefc7568d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomReconciler.java @@ -7,25 +7,25 @@ import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.ControllerUtils; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; -@Controller(generationAwareEventProcessing = false) -public class SubResourceTestCustomResourceController - implements ResourceController, TestExecutionInfoProvider { +@ControllerConfiguration(generationAwareEventProcessing = false) +public class SubResourceTestCustomReconciler + implements Reconciler, TestExecutionInfoProvider { public static final String FINALIZER_NAME = ControllerUtils.getDefaultFinalizerName( CustomResource.getCRDName(SubResourceTestCustomResource.class)); private static final Logger log = - LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); + LoggerFactory.getLogger(SubResourceTestCustomReconciler.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( SubResourceTestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); if (!resource.getMetadata().getFinalizers().contains(FINALIZER_NAME)) { diff --git a/operator-framework/src/test/resources/compile-fixtures/AbstractController.java b/operator-framework/src/test/resources/compile-fixtures/AbstractReconciler.java similarity index 58% rename from operator-framework/src/test/resources/compile-fixtures/AbstractController.java rename to operator-framework/src/test/resources/compile-fixtures/AbstractReconciler.java index d35a18c070..6f351b845a 100644 --- a/operator-framework/src/test/resources/compile-fixtures/AbstractController.java +++ b/operator-framework/src/test/resources/compile-fixtures/AbstractReconciler.java @@ -1,12 +1,12 @@ package io; import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import java.io.Serializable; -public abstract class AbstractController> implements Serializable, - ResourceController { +public abstract class AbstractReconciler> implements Serializable, + Reconciler { public static class MyCustomResource extends CustomResource { diff --git a/operator-framework/src/test/resources/compile-fixtures/AdditionalControllerInterface.java b/operator-framework/src/test/resources/compile-fixtures/AdditionalControllerInterface.java deleted file mode 100644 index 01077510f5..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/AdditionalControllerInterface.java +++ /dev/null @@ -1,11 +0,0 @@ -package io; - -import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.ResourceController; -import java.io.Serializable; - - -public interface AdditionalControllerInterface> extends - Serializable, - ResourceController { -} diff --git a/operator-framework/src/test/resources/compile-fixtures/AdditionalReconcilerInterface.java b/operator-framework/src/test/resources/compile-fixtures/AdditionalReconcilerInterface.java new file mode 100644 index 0000000000..2579e31c56 --- /dev/null +++ b/operator-framework/src/test/resources/compile-fixtures/AdditionalReconcilerInterface.java @@ -0,0 +1,11 @@ +package io; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import java.io.Serializable; + + +public interface AdditionalReconcilerInterface> extends + Serializable, + Reconciler { +} diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java deleted file mode 100644 index 2b0fa58a8f..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java +++ /dev/null @@ -1,26 +0,0 @@ -package io; - -import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; -import java.io.Serializable; - -@Controller -public class ControllerImplemented2Interfaces implements Serializable, ResourceController { - - public static class MyCustomResource extends CustomResource { - } - - @Override - public UpdateControl createOrUpdateResource(MyCustomResource customResource, Context context) { - return UpdateControl.updateCustomResource(null); - } - - @Override - public DeleteControl deleteResource(MyCustomResource customResource, Context context) { - return DeleteControl.defaultDelete(); - } -} diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java deleted file mode 100644 index 5674a3ed81..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java +++ /dev/null @@ -1,23 +0,0 @@ -package io; - -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.UpdateControl; -import java.io.Serializable; - -@Controller -public class ControllerImplementedIntermediateAbstractClass extends - AbstractController implements Serializable { - - public UpdateControl createOrUpdateResource( - AbstractController.MyCustomResource customResource, - Context context) { - return UpdateControl.updateCustomResource(null); - } - - public DeleteControl deleteResource(AbstractController.MyCustomResource customResource, - Context context) { - return DeleteControl.defaultDelete(); - } -} diff --git a/operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractController.java b/operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractReconciler.java similarity index 58% rename from operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractController.java rename to operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractReconciler.java index 4fe30adfe3..0dafba4c69 100644 --- a/operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractController.java +++ b/operator-framework/src/test/resources/compile-fixtures/MultilevelAbstractReconciler.java @@ -4,8 +4,8 @@ import java.io.Serializable; -public abstract class MultilevelAbstractController> implements +public abstract class MultilevelAbstractReconciler> implements Serializable, - AdditionalControllerInterface { + AdditionalReconcilerInterface { } diff --git a/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java b/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java deleted file mode 100644 index 0c07065337..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java +++ /dev/null @@ -1,28 +0,0 @@ -package io; - -import io.fabric8.kubernetes.client.CustomResource; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.UpdateControl; - -@Controller -public class MultilevelController extends - MultilevelAbstractController { - - public static class MyCustomResource extends CustomResource { - - } - - public UpdateControl createOrUpdateResource( - MultilevelController.MyCustomResource customResource, - Context context) { - return UpdateControl.updateCustomResource(null); - } - - public DeleteControl deleteResource(MultilevelController.MyCustomResource customResource, - Context context) { - return DeleteControl.defaultDelete(); - } - -} diff --git a/operator-framework/src/test/resources/compile-fixtures/MultilevelReconciler.java b/operator-framework/src/test/resources/compile-fixtures/MultilevelReconciler.java new file mode 100644 index 0000000000..fe15e54a6c --- /dev/null +++ b/operator-framework/src/test/resources/compile-fixtures/MultilevelReconciler.java @@ -0,0 +1,28 @@ +package io; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; + +@ControllerConfiguration +public class MultilevelReconciler extends + MultilevelAbstractReconciler { + + public static class MyCustomResource extends CustomResource { + + } + + public UpdateControl reconcile( + MultilevelReconciler.MyCustomResource customResource, + Context context) { + return UpdateControl.updateCustomResource(null); + } + + public DeleteControl cleanup(MultilevelReconciler.MyCustomResource customResource, + Context context) { + return DeleteControl.defaultDelete(); + } + +} diff --git a/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplemented2Interfaces.java b/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplemented2Interfaces.java new file mode 100644 index 0000000000..6331c54d2c --- /dev/null +++ b/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplemented2Interfaces.java @@ -0,0 +1,26 @@ +package io; + +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import java.io.Serializable; + +@ControllerConfiguration +public class ReconcilerImplemented2Interfaces implements Serializable, Reconciler { + + public static class MyCustomResource extends CustomResource { + } + + @Override + public UpdateControl reconcile(MyCustomResource customResource, Context context) { + return UpdateControl.updateCustomResource(null); + } + + @Override + public DeleteControl cleanup(MyCustomResource customResource, Context context) { + return DeleteControl.defaultDelete(); + } +} diff --git a/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplementedIntermediateAbstractClass.java b/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplementedIntermediateAbstractClass.java new file mode 100644 index 0000000000..17280051a2 --- /dev/null +++ b/operator-framework/src/test/resources/compile-fixtures/ReconcilerImplementedIntermediateAbstractClass.java @@ -0,0 +1,23 @@ +package io; + +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import java.io.Serializable; + +@ControllerConfiguration +public class ReconcilerImplementedIntermediateAbstractClass extends + AbstractReconciler implements Serializable { + + public UpdateControl reconcile( + AbstractReconciler.MyCustomResource customResource, + Context context) { + return UpdateControl.updateCustomResource(null); + } + + public DeleteControl cleanup(AbstractReconciler.MyCustomResource customResource, + Context context) { + return DeleteControl.defaultDelete(); + } +} diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceReconciler.java similarity index 73% rename from samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java rename to samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceReconciler.java index 932fd1bc1b..5400a8bef3 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceReconciler.java @@ -10,37 +10,34 @@ import io.fabric8.kubernetes.api.model.ServiceSpec; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; -import io.javaoperatorsdk.operator.api.DeleteControl; -import io.javaoperatorsdk.operator.api.ResourceController; -import io.javaoperatorsdk.operator.api.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; /** A very simple sample controller that creates a service with a label. */ -@Controller -public class CustomServiceController implements ResourceController { +@ControllerConfiguration +public class CustomServiceReconciler implements Reconciler { public static final String KIND = "CustomService"; - private static final Logger log = LoggerFactory.getLogger(CustomServiceController.class); + private static final Logger log = LoggerFactory.getLogger(CustomServiceReconciler.class); private final KubernetesClient kubernetesClient; - public CustomServiceController() { + public CustomServiceReconciler() { this(new DefaultKubernetesClient()); } - public CustomServiceController(KubernetesClient kubernetesClient) { + public CustomServiceReconciler(KubernetesClient kubernetesClient) { this.kubernetesClient = kubernetesClient; } @Override - public DeleteControl deleteResource(CustomService resource, Context context) { + public DeleteControl cleanup(CustomService resource, Context context) { log.info("Execution deleteResource for: {}", resource.getMetadata().getName()); return DeleteControl.defaultDelete(); } @Override - public UpdateControl createOrUpdateResource( + public UpdateControl reconcile( CustomService resource, Context context) { log.info("Execution createOrUpdateResource for: {}", resource.getMetadata().getName()); diff --git a/samples/pure-java/src/main/java/io/javaoperatorsdk/operator/sample/PureJavaApplicationRunner.java b/samples/pure-java/src/main/java/io/javaoperatorsdk/operator/sample/PureJavaApplicationRunner.java index 6aaa737c7c..2cc212340b 100644 --- a/samples/pure-java/src/main/java/io/javaoperatorsdk/operator/sample/PureJavaApplicationRunner.java +++ b/samples/pure-java/src/main/java/io/javaoperatorsdk/operator/sample/PureJavaApplicationRunner.java @@ -11,7 +11,7 @@ public static void main(String[] args) { new Operator(ConfigurationServiceOverrider.override(DefaultConfigurationService.instance()) .withConcurrentReconciliationThreads(2) .build()); - operator.register(new CustomServiceController()); + operator.register(new CustomServiceReconciler()); operator.start(); } } diff --git a/samples/spring-boot-plain/src/main/java/io/javaoperatorsdk/operator/sample/Config.java b/samples/spring-boot-plain/src/main/java/io/javaoperatorsdk/operator/sample/Config.java index 40c5ecefb9..07dd4b50c0 100644 --- a/samples/spring-boot-plain/src/main/java/io/javaoperatorsdk/operator/sample/Config.java +++ b/samples/spring-boot-plain/src/main/java/io/javaoperatorsdk/operator/sample/Config.java @@ -6,20 +6,20 @@ import org.springframework.context.annotation.Configuration; import io.javaoperatorsdk.operator.Operator; -import io.javaoperatorsdk.operator.api.ResourceController; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService; @Configuration public class Config { @Bean - public CustomServiceController customServiceController() { - return new CustomServiceController(); + public CustomServiceReconciler customServiceController() { + return new CustomServiceReconciler(); } // Register all controller beans @Bean(initMethod = "start", destroyMethod = "stop") - public Operator operator(List controllers) { + public Operator operator(List controllers) { Operator operator = new Operator(DefaultConfigurationService.instance()); controllers.forEach(operator::register); return operator;