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 717e339514..c077a7876d 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 @@ -7,8 +7,8 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.ReconcilerUtils; +import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Constants; -import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResourceControllerFactory; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters; @@ -54,10 +54,6 @@ default List getDependentResources() { return Collections.emptyList(); } - default DependentResourceControllerFactory dependentFactory() { - return new DependentResourceControllerFactory<>() {}; - } - default Optional reconciliationMaxInterval() { return Optional.of(Duration.ofHours(10L)); } 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 41bacbbbce..188311cfdb 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 @@ -7,6 +7,7 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfiguration; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; public class DefaultControllerConfiguration diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Dependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Dependent.java deleted file mode 100644 index ed013fafb0..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Dependent.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.javaoperatorsdk.operator.api.config; - -public @interface Dependent { - - Class resourceType(); - - Class type(); -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResource.java deleted file mode 100644 index f4d5df89fb..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResource.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.javaoperatorsdk.operator.api.config; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; - -public interface DependentResource { - default EventSource initEventSource(EventSourceContext

context) { - throw new IllegalStateException("Must be implemented if not automatically provided by the SDK"); - }; - - default Class resourceType() { - return (Class) Utils.getFirstTypeArgumentFromInterface(getClass()); - } -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Dependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Dependent.java new file mode 100644 index 0000000000..017f4363a6 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Dependent.java @@ -0,0 +1,10 @@ +package io.javaoperatorsdk.operator.api.config.dependent; + +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; + +public @interface Dependent { + + Class resourceType(); + + Class type(); +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfiguration.java similarity index 63% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResourceConfiguration.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfiguration.java index 15911e0418..c0f428c12d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DependentResourceConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceConfiguration.java @@ -1,6 +1,7 @@ -package io.javaoperatorsdk.operator.api.config; +package io.javaoperatorsdk.operator.api.config.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; public interface DependentResourceConfiguration { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/KubernetesDependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependent.java similarity index 95% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/KubernetesDependent.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependent.java index 5b9fbd38f3..e7d2ad3158 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/KubernetesDependent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependent.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.api.config; +package io.javaoperatorsdk.operator.api.config.dependent; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependentResourceConfiguration.java similarity index 90% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceConfiguration.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependentResourceConfiguration.java index 23d37881b4..6872322e4f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/KubernetesDependentResourceConfiguration.java @@ -1,14 +1,13 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; +package io.javaoperatorsdk.operator.api.config.dependent; import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.config.ConfigurationService; -import io.javaoperatorsdk.operator.api.config.DependentResource; -import io.javaoperatorsdk.operator.api.config.DependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.event.source.AssociatedSecondaryResourceIdentifier; import io.javaoperatorsdk.operator.processing.event.source.PrimaryResourcesRetriever; -import io.javaoperatorsdk.operator.processing.event.source.informer.InformerConfiguration; public interface KubernetesDependentResourceConfiguration extends InformerConfiguration, DependentResourceConfiguration { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java similarity index 97% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerConfiguration.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java index 087e206f8b..c4d747a990 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java @@ -1,4 +1,4 @@ -package io.javaoperatorsdk.operator.processing.event.source.informer; +package io.javaoperatorsdk.operator.api.config.informer; import java.util.Collections; import java.util.Objects; @@ -12,6 +12,7 @@ import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.AssociatedSecondaryResourceIdentifier; import io.javaoperatorsdk.operator.processing.event.source.PrimaryResourcesRetriever; +import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers; public interface InformerConfiguration extends ResourceConfiguration { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java index 4db09c9cc8..85eed38025 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java @@ -6,8 +6,8 @@ import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; -import io.javaoperatorsdk.operator.api.config.Dependent; -import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResourceController; +import io.javaoperatorsdk.operator.api.config.dependent.Dependent; +import io.javaoperatorsdk.operator.processing.dependent.DependentResourceController; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; @Retention(RetentionPolicy.RUNTIME) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Builder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Builder.java deleted file mode 100644 index 4dfaf91e64..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Builder.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.Context; - -@FunctionalInterface -public interface Builder { - R buildFor(P primary, Context context); -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Cleaner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Cleaner.java deleted file mode 100644 index a6a3d691be..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Cleaner.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.Context; - -public interface Cleaner { - - void delete(R fetched, P primary, Context context); -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java new file mode 100644 index 0000000000..df144ade1f --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java @@ -0,0 +1,62 @@ +package io.javaoperatorsdk.operator.api.reconciler.dependent; + +import java.util.Optional; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.config.Utils; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.processing.event.source.EventSource; + +public interface DependentResource { + default EventSource initEventSource(EventSourceContext

context) { + throw new IllegalStateException("Must be implemented if not automatically provided by the SDK"); + } + + @SuppressWarnings("unchecked") + default Class resourceType() { + return (Class) Utils.getFirstTypeArgumentFromInterface(getClass()); + } + + default void delete(R fetched, P primary, Context context) {} + + /** + * Computes the desired state of the dependent based on the state provided by the specified + * primary resource. + * + * The default implementation returns {@code empty} which corresponds to the case where the + * associated dependent should never be created by the associated reconciler or that the global + * state of the cluster doesn't allow for the resource to be created at this point. + * + * @param primary the primary resource associated with the reconciliation process + * @param context the {@link Context} associated with the reconciliation process + * @return an instance of the dependent resource matching the desired state specified by the + * primary resource or {@code empty} if the dependent shouldn't be created at this point + * (or ever) + */ + default Optional desired(P primary, Context context) { + return Optional.empty(); + } + + /** + * Checks whether the actual resource as fetched from the cluster matches the desired state + * expressed by the specified primary resource. + * + * The default implementation always return {@code true}, which corresponds to the behavior where + * the dependent never needs to be updated after it's been created. + * + * Note that failure to properly implement this method will lead to infinite loops. In particular, + * for typical Kubernetes resource implementations, simply calling + * {@code desired(primary, context).equals(actual)} is not enough because metadata will usually be + * different. + * + * @param actual the current state of the resource as fetched from the cluster + * @param primary the primary resource associated with the reconciliation request + * @param context the {@link Context} associated with the reconciliation request + * @return {@code true} if the actual state of the resource matches the desired state expressed by + * the specified primary resource, {@code false} otherwise + */ + default boolean match(R actual, P primary, Context context) { + return true; + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceController.java deleted file mode 100644 index 21cd16a32f..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceController.java +++ /dev/null @@ -1,94 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.config.DependentResource; -import io.javaoperatorsdk.operator.api.config.DependentResourceConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; - -public class DependentResourceController> - implements DependentResource, Builder, Updater, Persister, - Cleaner { - - private final Builder builder; - private final Updater updater; - private final Cleaner cleaner; - private final Persister persister; - private final DependentResource delegate; - private final C configuration; - - @SuppressWarnings("unchecked") - public DependentResourceController(DependentResource delegate, C configuration) { - this.delegate = delegate; - builder = (delegate instanceof Builder) ? (Builder) delegate : null; - updater = (delegate instanceof Updater) ? (Updater) delegate : null; - cleaner = (delegate instanceof Cleaner) ? (Cleaner) delegate : null; - persister = initPersister(delegate); - this.configuration = configuration; - } - - @SuppressWarnings("unchecked") - protected Persister initPersister(DependentResource delegate) { - if (delegate instanceof Persister) { - return (Persister) delegate; - } else { - throw new IllegalArgumentException( - "DependentResource '" + delegate.getClass().getName() + "' must implement Persister"); - } - } - - public String descriptionFor(R resource) { - return resource.toString(); - } - - @Override - public R buildFor(P primary, Context context) { - return builder.buildFor(primary, context); - } - - @Override - public R update(R fetched, P primary, Context context) { - return updater.update(fetched, primary, context); - } - - @Override - public void delete(R fetched, P primary, Context context) { - cleaner.delete(fetched, primary, context); - } - - public Class getResourceType() { - return delegate.resourceType(); - } - - @Override - public EventSource initEventSource(EventSourceContext

context) { - return delegate.initEventSource(context); - } - - public boolean creatable() { - return builder != null; - } - - public boolean updatable() { - return updater != null; - } - - public boolean deletable() { - return cleaner != null; - } - - @Override - public void createOrReplace(R dependentResource, Context context) { - persister.createOrReplace(dependentResource, context); - } - - @Override - public R getFor(P primary, Context context) { - return persister.getFor(primary, context); - } - - public C getConfiguration() { - return configuration; - } -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceControllerFactory.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceControllerFactory.java deleted file mode 100644 index dd11a7a706..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceControllerFactory.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; - -import java.lang.reflect.InvocationTargetException; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.config.DependentResourceConfiguration; - -public interface DependentResourceControllerFactory

{ - - default , R, C extends DependentResourceConfiguration> T from( - C config) { - try { - final var dependentResource = config.getDependentResourceClass().getConstructor() - .newInstance(); - if (config instanceof KubernetesDependentResourceConfiguration) { - return (T) new KubernetesDependentResourceController(dependentResource, - (KubernetesDependentResourceConfiguration) config); - } else { - return (T) new DependentResourceController(dependentResource, config); - } - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException - | IllegalAccessException e) { - throw new IllegalArgumentException(e); - } - } -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Updater.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Updater.java deleted file mode 100644 index c92f3c5ced..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Updater.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.Context; - -@FunctionalInterface -public interface Updater { - - R update(R fetched, P primary, Context context); -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceController.java new file mode 100644 index 0000000000..d0004111af --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceController.java @@ -0,0 +1,134 @@ +package io.javaoperatorsdk.operator.processing.dependent; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.Ignore; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; +import io.javaoperatorsdk.operator.api.reconciler.dependent.Persister; +import io.javaoperatorsdk.operator.processing.event.source.EventSource; + +@Ignore +public class DependentResourceController> + implements DependentResource, Persister, Reconciler

{ + + private static final Logger log = LoggerFactory.getLogger(DependentResourceController.class); + + private final Persister persister; + private final DependentResource delegate; + private final C configuration; + + public DependentResourceController(DependentResource delegate, C configuration) { + this.delegate = delegate; + persister = initPersister(delegate); + this.configuration = configuration; + } + + @Override + public Class resourceType() { + return delegate.resourceType(); + } + + @Override + public boolean match(R actual, P primary, Context context) { + return delegate.match(actual, primary, context); + } + + @Override + public Optional desired(P primary, Context context) { + return delegate.desired(primary, context); + } + + @Override + public void delete(R fetched, P primary, Context context) { + delegate.delete(fetched, primary, context); + } + + @SuppressWarnings("unchecked") + protected Persister initPersister(DependentResource delegate) { + if (delegate instanceof Persister) { + return (Persister) delegate; + } else { + throw new IllegalArgumentException( + "DependentResource '" + delegate.getClass().getName() + "' must implement Persister"); + } + } + + public String descriptionFor(R resource) { + return resource.toString(); + } + + public Class getResourceType() { + return delegate.resourceType(); + } + + @Override + public EventSource initEventSource(EventSourceContext

context) { + return delegate.initEventSource(context); + } + + @Override + public void createOrReplace(R dependentResource, Context context) { + persister.createOrReplace(dependentResource, context); + } + + @Override + public R getFor(P primary, Context context) { + return persister.getFor(primary, context); + } + + public C getConfiguration() { + return configuration; + } + + @Override + public UpdateControl

reconcile(P resource, Context context) { + var actual = getFor(resource, context); + if (actual == null || !match(actual, resource, context)) { + final var desired = desired(resource, context); + desired.ifPresent(d -> createOrReplaceDependent(resource, d, context)); + } + return UpdateControl.noUpdate(); + } + + @Override + public DeleteControl cleanup(P primary, Context context) { + var dependent = getFor(primary, context); + if (dependent != null) { + delete(dependent, primary, context); + logOperationInfo(primary, dependent, "Deleting"); + } else { + log.info("Ignoring already deleted {} for '{}' {}", + getResourceType().getName(), + primary.getMetadata().getName(), + primary.getKind()); + } + return Reconciler.super.cleanup(primary, context); + } + + protected void createOrReplaceDependent(P primary, R dependent, Context context) { + logOperationInfo(primary, dependent, "Reconciling"); + + // commit the changes + // todo: add metrics timing for dependent resource + createOrReplace(dependent, context); + } + + private void logOperationInfo(P resource, R dependentResource, String operationDescription) { + if (log.isInfoEnabled()) { + log.info("{} {} for '{}' {}", operationDescription, + descriptionFor(dependentResource), + resource.getMetadata().getName(), + resource.getKind()); + } + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceManager.java index 911805b396..8ab04d7d09 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceManager.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceManager.java @@ -1,14 +1,13 @@ package io.javaoperatorsdk.operator.processing.dependent; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.config.DependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.dependent.KubernetesDependentResourceConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ContextInitializer; import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; @@ -18,36 +17,32 @@ import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResourceController; -import io.javaoperatorsdk.operator.api.reconciler.dependent.KubernetesDependentResourceController; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.event.source.EventSource; @SuppressWarnings({"rawtypes", "unchecked"}) @Ignore -public class DependentResourceManager implements EventSourceInitializer, - EventSourceContextInjector, Reconciler { - - private static final Logger log = LoggerFactory.getLogger(DependentResourceManager.class); - - private final Reconciler reconciler; - private final ControllerConfiguration configuration; +public class DependentResourceManager

implements EventSourceInitializer

, + EventSourceContextInjector, Reconciler

{ + private final Reconciler

reconciler; + private final ControllerConfiguration

configuration; private List dependents; - public DependentResourceManager(Controller controller) { + public DependentResourceManager(Controller

controller) { this.reconciler = controller.getReconciler(); this.configuration = controller.getConfiguration(); } @Override - public List prepareEventSources(EventSourceContext context) { + public List prepareEventSources(EventSourceContext

context) { final List configured = configuration.getDependentResources(); dependents = new ArrayList<>(configured.size()); List sources = new ArrayList<>(configured.size() + 5); configured.forEach(dependent -> { - final var dependentResourceController = configuration.dependentFactory().from(dependent); + final var dependentResourceController = from(dependent); dependents.add(dependentResourceController); sources.add(dependentResourceController.initEventSource(context)); }); @@ -64,80 +59,41 @@ public void injectInto(EventSourceContext context) { } @Override - public UpdateControl reconcile(R resource, Context context) { + public UpdateControl

reconcile(P resource, Context context) { initContextIfNeeded(resource, context); - - dependents.stream() - .filter(dependent -> dependent.creatable() || dependent.updatable()) - .forEach(dependent -> { - var dependentResource = dependent.getFor(resource, context); - if (dependent.creatable() && dependentResource == null) { - // we need to create the dependent - dependentResource = dependent.buildFor(resource, context); - createOrReplaceDependent(resource, context, dependent, dependentResource, "Creating"); - } else if (dependent.updatable()) { - dependentResource = dependent.update(dependentResource, resource, context); - createOrReplaceDependent(resource, context, dependent, dependentResource, "Updating"); - } else { - logOperationInfo(resource, dependent, dependentResource, "Ignoring"); - } - }); - + dependents.forEach(dependent -> dependent.reconcile(resource, context)); return UpdateControl.noUpdate(); } @Override - public DeleteControl cleanup(R resource, Context context) { + public DeleteControl cleanup(P resource, Context context) { initContextIfNeeded(resource, context); - - dependents.stream() - .filter(DependentResourceController::deletable) - .forEach(dependent -> { - var dependentResource = dependent.getFor(resource, context); - if (dependentResource != null) { - dependent.delete(dependentResource, resource, context); - logOperationInfo(resource, dependent, dependentResource, "Deleting"); - } else { - log.info("Ignoring already deleted {} for '{}' {}", - dependent.getResourceType().getName(), - resource.getMetadata().getName(), - configuration.getResourceTypeName()); - } - }); - + dependents.forEach(dependent -> dependent.cleanup(resource, context)); return Reconciler.super.cleanup(resource, context); } - private void createOrReplaceDependent(R primaryResource, - Context context, DependentResourceController dependentController, - Object dependentResource, String operationDescription) { - // add owner reference if needed - if (dependentResource instanceof HasMetadata - && ((KubernetesDependentResourceController) dependentController).owned()) { - ((HasMetadata) dependentResource).addOwnerReference(primaryResource); - } - logOperationInfo(primaryResource, dependentController, dependentResource, operationDescription); - - // commit the changes - // todo: add metrics timing for dependent resource - dependentController.createOrReplace(dependentResource, context); - } - - private void logOperationInfo(R resource, DependentResourceController dependent, - Object dependentResource, String operationDescription) { - if (log.isInfoEnabled()) { - log.info("{} {} for '{}' {}", operationDescription, - dependent.descriptionFor(dependentResource), - resource.getMetadata().getName(), - configuration.getResourceTypeName()); + private void initContextIfNeeded(P resource, Context context) { + if (reconciler instanceof ContextInitializer) { + final var initializer = (ContextInitializer

) reconciler; + initializer.initContext(resource, context); } } - private void initContextIfNeeded(R resource, Context context) { - if (reconciler instanceof ContextInitializer) { - final var initializer = (ContextInitializer) reconciler; - initializer.initContext(resource, context); + private DependentResourceController from(DependentResourceConfiguration config) { + try { + final var dependentResource = + (DependentResource) config.getDependentResourceClass().getConstructor() + .newInstance(); + if (config instanceof KubernetesDependentResourceConfiguration) { + return new KubernetesDependentResourceController(dependentResource, + (KubernetesDependentResourceConfiguration) config); + } else { + return new DependentResourceController(dependentResource, config); + } + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException + | IllegalAccessException e) { + throw new IllegalArgumentException(e); } } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesDependentResourceController.java similarity index 80% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceController.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesDependentResourceController.java index 172e9cb0d9..63d533193b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/KubernetesDependentResourceController.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesDependentResourceController.java @@ -1,16 +1,20 @@ -package io.javaoperatorsdk.operator.api.reconciler.dependent; +package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.config.DependentResource; +import io.javaoperatorsdk.operator.api.config.dependent.KubernetesDependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.Ignore; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; +import io.javaoperatorsdk.operator.api.reconciler.dependent.Persister; import io.javaoperatorsdk.operator.processing.event.source.AssociatedSecondaryResourceIdentifier; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.PrimaryResourcesRetriever; -import io.javaoperatorsdk.operator.processing.event.source.informer.InformerConfiguration; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; +@Ignore public class KubernetesDependentResourceController extends DependentResourceController> { @@ -19,6 +23,7 @@ public class KubernetesDependentResourceController informer; + @SuppressWarnings("unchecked") public KubernetesDependentResourceController(DependentResource delegate, KubernetesDependentResourceConfiguration configuration) { super(delegate, configuration); @@ -41,6 +46,7 @@ public KubernetesDependentResourceController(DependentResource delegate, configuration.getDependentResourceClass()); } + @SuppressWarnings("unchecked") @Override protected Persister initPersister(DependentResource delegate) { return (delegate instanceof Persister) ? (Persister) delegate : this; @@ -73,4 +79,12 @@ public R getFor(P primary, Context context) { public boolean owned() { return getConfiguration().isOwned(); } + + @Override + protected void createOrReplaceDependent(P primary, R dependent, Context context) { + if (owned()) { + dependent.addOwnerReference(primary); + } + super.createOrReplaceDependent(primary, dependent, context); + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java index fa9e516585..3def733bd8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.EventHandler; 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 5d10762f35..19e31e932b 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 @@ -11,16 +11,16 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.ReconcilerUtils; import io.javaoperatorsdk.operator.api.config.ConfigurationService; -import io.javaoperatorsdk.operator.api.config.Dependent; -import io.javaoperatorsdk.operator.api.config.DependentResource; -import io.javaoperatorsdk.operator.api.config.DependentResourceConfiguration; -import io.javaoperatorsdk.operator.api.config.KubernetesDependent; +import io.javaoperatorsdk.operator.api.config.dependent.Dependent; +import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.dependent.KubernetesDependent; +import io.javaoperatorsdk.operator.api.config.dependent.KubernetesDependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; -import io.javaoperatorsdk.operator.api.reconciler.dependent.KubernetesDependentResourceConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters; -import io.javaoperatorsdk.operator.processing.event.source.informer.InformerConfiguration; @SuppressWarnings("rawtypes") public class AnnotationConfiguration @@ -159,7 +159,8 @@ public List getDependentResources() { if (HasMetadata.class.isAssignableFrom(resourceType)) { final var kubeDependent = dependentType.getAnnotation(KubernetesDependent.class); final var namespaces = - valueOrDefault(kubeDependent, KubernetesDependent::namespaces, new String[] {}); + valueOrDefault(kubeDependent, KubernetesDependent::namespaces, + this.getNamespaces().toArray(new String[0])); final var labelSelector = valueOrDefault(kubeDependent, KubernetesDependent::labelSelector, null); final var owned = valueOrDefault(kubeDependent, KubernetesDependent::owned, diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java index 2a04b85d19..33128a6b8c 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/informereventsource/InformerEventSourceTestCustomReconciler.java @@ -8,12 +8,12 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.ConfigMap; -import io.javaoperatorsdk.operator.api.config.Dependent; -import io.javaoperatorsdk.operator.api.config.DependentResource; +import io.javaoperatorsdk.operator.api.config.dependent.Dependent; 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.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.PrimaryResourcesRetriever; import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers; diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/MySQLSchemaReconciler.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/MySQLSchemaReconciler.java index ecc2aa9be7..ff4fcad131 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/MySQLSchemaReconciler.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/MySQLSchemaReconciler.java @@ -9,8 +9,7 @@ import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.SecretBuilder; -import io.javaoperatorsdk.operator.api.config.Dependent; -import io.javaoperatorsdk.operator.api.config.DependentResource; +import io.javaoperatorsdk.operator.api.config.dependent.Dependent; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ContextInitializer; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; @@ -20,7 +19,7 @@ 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.api.reconciler.dependent.Builder; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.sample.MySQLSchemaReconciler.SecretDependentResource; import io.javaoperatorsdk.operator.sample.schema.Schema; @@ -51,12 +50,15 @@ public MySQLSchemaReconciler(MySQLDbConfig mysqlDbConfig) { this.mysqlDbConfig = mysqlDbConfig; } - public static class SecretDependentResource - implements DependentResource, Builder { + public static class SecretDependentResource implements DependentResource { + + private static String encode(String value) { + return Base64.getEncoder().encodeToString(value.getBytes()); + } @Override - public Secret buildFor(MySQLSchema schema, Context context) { - return new SecretBuilder() + public Optional desired(MySQLSchema schema, Context context) { + return Optional.of(new SecretBuilder() .withNewMetadata() .withName(context.getMandatory(MYSQL_SECRET_NAME, String.class)) .withNamespace(schema.getMetadata().getNamespace()) @@ -65,14 +67,11 @@ public Secret buildFor(MySQLSchema schema, Context context) { context.getMandatory(MYSQL_SECRET_USERNAME, String.class))) .addToData("MYSQL_PASSWORD", encode( context.getMandatory(MYSQL_SECRET_PASSWORD, String.class))) - .build(); - } - - private static String encode(String value) { - return Base64.getEncoder().encodeToString(value.getBytes()); + .build()); } } + @SuppressWarnings("rawtypes") @Override public void injectInto(EventSourceContext context) { context.put(MYSQL_DB_CONFIG, mysqlDbConfig); diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaDependentResource.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaDependentResource.java index de4b0ece58..8ba9612029 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaDependentResource.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaDependentResource.java @@ -3,12 +3,11 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Optional; -import io.javaoperatorsdk.operator.api.config.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Builder; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Cleaner; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.Persister; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; @@ -18,8 +17,7 @@ import static java.lang.String.format; public class SchemaDependentResource - implements DependentResource, Builder, - Cleaner, Persister { + implements DependentResource, Persister { private static final int POLL_PERIOD = 500; private MySQLDbConfig dbConfig; @@ -33,7 +31,7 @@ public EventSource initEventSource(EventSourceContext context) { } @Override - public Schema buildFor(MySQLSchema primary, Context context) { + public Optional desired(MySQLSchema primary, Context context) { try (Connection connection = getConnection()) { final var schema = SchemaService.createSchemaAndRelatedUser( connection, @@ -44,7 +42,7 @@ public Schema buildFor(MySQLSchema primary, Context context) { // put the newly built schema in the context to let the reconciler know we just built it context.put(MySQLSchemaReconciler.BUILT_SCHEMA, schema); - return schema; + return Optional.of(schema); } catch (SQLException e) { MySQLSchemaReconciler.log.error("Error while creating Schema", e); throw new IllegalStateException(e); diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentDependentResource.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentDependentResource.java index 245011a1cf..58200df988 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentDependentResource.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentDependentResource.java @@ -1,21 +1,20 @@ package io.javaoperatorsdk.operator.sample; +import java.util.Optional; + import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; -import io.javaoperatorsdk.operator.api.config.DependentResource; -import io.javaoperatorsdk.operator.api.config.KubernetesDependent; +import io.javaoperatorsdk.operator.api.config.dependent.KubernetesDependent; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Builder; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Updater; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @KubernetesDependent(labelSelector = "app.kubernetes.io/managed-by=tomcat-operator") public class DeploymentDependentResource - implements DependentResource, Builder, - Updater { + implements DependentResource { @Override - public Deployment buildFor(Tomcat tomcat, Context context) { + public Optional desired(Tomcat tomcat, Context context) { Deployment deployment = TomcatReconciler.loadYaml(Deployment.class, "deployment.yaml"); final ObjectMeta tomcatMetadata = tomcat.getMetadata(); final String tomcatName = tomcatMetadata.getName(); @@ -35,18 +34,21 @@ public Deployment buildFor(Tomcat tomcat, Context context) { // make sure label selector matches label (which has to be matched by service selector too) .editMetadata().addToLabels("app", tomcatName).endMetadata() .editSpec() - .editFirstContainer().withImage("tomcat:" + tomcat.getSpec().getVersion()).endContainer() + .editFirstContainer().withImage(tomcatImage(tomcat)).endContainer() .endSpec() .endTemplate() .endSpec() .build(); - return deployment; + return Optional.of(deployment); + } + + private String tomcatImage(Tomcat tomcat) { + return "tomcat:" + tomcat.getSpec().getVersion(); } @Override - public Deployment update(Deployment fetched, Tomcat tomcat, Context context) { - return new DeploymentBuilder(fetched).editSpec().editTemplate().editSpec().editFirstContainer() - .withImage("tomcat:" + tomcat.getSpec().getVersion()) - .endContainer().endSpec().endTemplate().endSpec().build(); + public boolean match(Deployment fetched, Tomcat tomcat, Context context) { + return fetched.getSpec().getTemplate().getSpec().getContainers().stream() + .findFirst().map(c -> tomcatImage(tomcat).equals(c.getImage())).orElse(false); } } diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/ServiceDependentResource.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/ServiceDependentResource.java index b90bd0e6e2..52d043203b 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/ServiceDependentResource.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/ServiceDependentResource.java @@ -1,28 +1,26 @@ package io.javaoperatorsdk.operator.sample; +import java.util.Optional; + import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; -import io.javaoperatorsdk.operator.api.config.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Builder; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; -public class ServiceDependentResource - implements DependentResource, Builder { +public class ServiceDependentResource implements DependentResource { @Override - public Service buildFor(Tomcat tomcat, Context context) { + public Optional desired(Tomcat tomcat, Context context) { final ObjectMeta tomcatMetadata = tomcat.getMetadata(); - final Service service = - new ServiceBuilder(TomcatReconciler.loadYaml(Service.class, "service.yaml")) - .editMetadata() - .withName(tomcatMetadata.getName()) - .withNamespace(tomcatMetadata.getNamespace()) - .endMetadata() - .editSpec() - .addToSelector("app", tomcatMetadata.getName()) - .endSpec() - .build(); - return service; + return Optional.of(new ServiceBuilder(TomcatReconciler.loadYaml(Service.class, "service.yaml")) + .editMetadata() + .withName(tomcatMetadata.getName()) + .withNamespace(tomcatMetadata.getNamespace()) + .endMetadata() + .editSpec() + .addToSelector("app", tomcatMetadata.getName()) + .endSpec() + .build()); } } diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatDependentResource.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatDependentResource.java index 9dd49466ab..abb4e62358 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatDependentResource.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatDependentResource.java @@ -3,8 +3,8 @@ import java.util.Set; import java.util.stream.Collectors; -import io.javaoperatorsdk.operator.api.config.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.AssociatedSecondaryResourceIdentifier; import io.javaoperatorsdk.operator.processing.event.source.EventSourceContextAware; diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java index 32f7927f44..d2d2a6c96c 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java @@ -11,7 +11,7 @@ import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentStatus; import io.fabric8.kubernetes.client.utils.Serialization; -import io.javaoperatorsdk.operator.api.config.Dependent; +import io.javaoperatorsdk.operator.api.config.dependent.Dependent; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java index 9e1f6f677f..8f7b682d62 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java @@ -17,6 +17,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.ExecListener; import io.fabric8.kubernetes.client.dsl.ExecWatch; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; @@ -28,7 +29,6 @@ import io.javaoperatorsdk.operator.processing.event.source.AssociatedSecondaryResourceIdentifier; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.PrimaryResourcesRetriever; -import io.javaoperatorsdk.operator.processing.event.source.informer.InformerConfiguration; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; @ControllerConfiguration