diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java index 38f21683d8..e539e10b3a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java @@ -14,11 +14,12 @@ public interface EventSourceInitializer

{ /** - * Prepares a list of {@link EventSource} implementations to be registered by the SDK. + * Prepares a map of {@link EventSource} implementations keyed by the name with which they need to + * be registered by the SDK. * * @param context a {@link EventSourceContext} providing access to information useful to event * sources - * @return list of event sources to register + * @return a map of event sources to register */ Map prepareEventSources(EventSourceContext

context); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java index 1762198286..eb44735a89 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java @@ -2,7 +2,6 @@ import io.fabric8.kubernetes.api.model.HasMetadata; -@SuppressWarnings("rawtypes") public class UpdateControl extends BaseControl> { private final T resource; @@ -32,8 +31,7 @@ public static UpdateControl updateResource(T customRe return new UpdateControl<>(customResource, false, true); } - public static UpdateControl updateStatus( - T customResource) { + public static UpdateControl updateStatus(T customResource) { return new UpdateControl<>(customResource, true, false); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceProvider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceProvider.java index cc1514fac0..98190cb7ef 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceProvider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceProvider.java @@ -10,6 +10,4 @@ public interface EventSourceProvider

{ * @return the initiated event source. */ EventSource initEventSource(EventSourceContext

context); - - EventSource getEventSource(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java index 2a96965000..f0fdd07b16 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java @@ -209,7 +209,6 @@ public UpdateControl

execute() throws Exception { .collect(Collectors.joining("\n")), exceptions); } - return reconciler.reconcile(resource, context); } }); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java index 8b1a634c08..8c4ef11b1b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java @@ -5,12 +5,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; -import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; -import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider; -import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; -import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationEventFilter; -import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; +import io.javaoperatorsdk.operator.api.reconciler.dependent.*; import io.javaoperatorsdk.operator.processing.event.ResourceID; public abstract class AbstractDependentResource @@ -68,89 +63,20 @@ public ReconcileResult reconcile(P primary, Context

context) { protected R handleCreate(R desired, P primary, Context

context) { ResourceID resourceID = ResourceID.fromResource(primary); - R created = null; - try { - prepareEventFiltering(desired, resourceID); - created = creator.create(desired, primary, context); - cacheAfterCreate(resourceID, created); - return created; - } catch (RuntimeException e) { - cleanupAfterEventFiltering(desired, resourceID, created); - throw e; - } - } - - private void cleanupAfterEventFiltering(R desired, ResourceID resourceID, R created) { - if (isFilteringEventSource()) { - eventSourceAsRecentOperationEventFilter() - .cleanupOnCreateOrUpdateEventFiltering(resourceID, created); - } - } - - private void cacheAfterCreate(ResourceID resourceID, R created) { - if (isRecentOperationCacheFiller()) { - eventSourceAsRecentOperationCacheFiller().handleRecentResourceCreate(resourceID, created); - } + R created = creator.create(desired, primary, context); + cacheAfterCreate(resourceID, created); + return created; } - private void cacheAfterUpdate(R actual, ResourceID resourceID, R updated) { - if (isRecentOperationCacheFiller()) { - eventSourceAsRecentOperationCacheFiller().handleRecentResourceUpdate(resourceID, updated, - actual); - } - } + protected abstract void cacheAfterCreate(ResourceID resourceID, R created); - private void prepareEventFiltering(R desired, ResourceID resourceID) { - if (isFilteringEventSource()) { - eventSourceAsRecentOperationEventFilter().prepareForCreateOrUpdateEventFiltering(resourceID, - desired); - } - } + protected abstract void cacheAfterUpdate(R actual, ResourceID resourceID, R updated); protected R handleUpdate(R actual, R desired, P primary, Context

context) { ResourceID resourceID = ResourceID.fromResource(primary); - R updated = null; - try { - prepareEventFiltering(desired, resourceID); - updated = updater.update(actual, desired, primary, context); - cacheAfterUpdate(actual, resourceID, updated); - return updated; - } catch (RuntimeException e) { - cleanupAfterEventFiltering(desired, resourceID, updated); - throw e; - } - } - - @SuppressWarnings("unchecked") - private RecentOperationEventFilter eventSourceAsRecentOperationEventFilter() { - return (RecentOperationEventFilter) ((EventSourceProvider

) this).getEventSource(); - } - - @SuppressWarnings("unchecked") - private RecentOperationCacheFiller eventSourceAsRecentOperationCacheFiller() { - return (RecentOperationCacheFiller) ((EventSourceProvider

) this).getEventSource(); - } - - @SuppressWarnings("unchecked") - // this cannot be done in constructor since event source might be initialized later - protected boolean isFilteringEventSource() { - if (this instanceof EventSourceProvider) { - final var eventSource = ((EventSourceProvider

) this).getEventSource(); - return eventSource instanceof RecentOperationEventFilter; - } else { - return false; - } - } - - @SuppressWarnings("unchecked") - // this cannot be done in constructor since event source might be initialized later - protected boolean isRecentOperationCacheFiller() { - if (this instanceof EventSourceProvider) { - final var eventSource = ((EventSourceProvider

) this).getEventSource(); - return eventSource instanceof RecentOperationCacheFiller; - } else { - return false; - } + R updated = updater.update(actual, desired, primary, context); + cacheAfterUpdate(actual, resourceID, updated); + return updated; } protected R desired(P primary, Context

context) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java new file mode 100644 index 0000000000..d104425140 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java @@ -0,0 +1,120 @@ +package io.javaoperatorsdk.operator.processing.dependent; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider; +import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; +import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationEventFilter; +import io.javaoperatorsdk.operator.processing.event.EventHandler; +import io.javaoperatorsdk.operator.processing.event.ResourceID; +import io.javaoperatorsdk.operator.processing.event.source.EventSource; + +public abstract class AbstractEventSourceHolderDependentResource + extends AbstractDependentResource implements EventSource, EventSourceProvider

{ + private T eventSource; + private boolean isFilteringEventSource; + private boolean isCacheFillerEventSource; + + @Override + public void start() throws OperatorException { + eventSource.start(); + } + + @Override + public void stop() throws OperatorException { + eventSource.stop(); + } + + public EventSource initEventSource(EventSourceContext

context) { + // some sub-classes (e.g. KubernetesDependentResource) can have their event source created + // before this method is called in the managed case, so only create the event source if it + // hasn't already been set + if (eventSource == null) { + eventSource = createEventSource(context); + } + + // but we still need to record which interfaces the event source implements even if it has + // already been set before this method is called + isFilteringEventSource = eventSource instanceof RecentOperationEventFilter; + isCacheFillerEventSource = eventSource instanceof RecentOperationCacheFiller; + return this; + } + + protected abstract T createEventSource(EventSourceContext

context); + + protected void setEventSource(T eventSource) { + this.eventSource = eventSource; + } + + @Override + public void setEventHandler(EventHandler handler) { + eventSource.setEventHandler(handler); + } + + protected T eventSource() { + return eventSource; + } + + protected R handleCreate(R desired, P primary, Context

context) { + ResourceID resourceID = ResourceID.fromResource(primary); + R created = null; + try { + prepareEventFiltering(desired, resourceID); + created = super.handleCreate(desired, primary, context); + return created; + } catch (RuntimeException e) { + cleanupAfterEventFiltering(desired, resourceID, created); + throw e; + } + } + + protected R handleUpdate(R actual, R desired, P primary, Context

context) { + ResourceID resourceID = ResourceID.fromResource(primary); + R updated = null; + try { + prepareEventFiltering(desired, resourceID); + updated = super.handleUpdate(actual, desired, primary, context); + return updated; + } catch (RuntimeException e) { + cleanupAfterEventFiltering(desired, resourceID, updated); + throw e; + } + } + + + protected void cacheAfterCreate(ResourceID resourceID, R created) { + if (isCacheFillerEventSource) { + recentOperationCacheFiller().handleRecentResourceCreate(resourceID, created); + } + } + + protected void cacheAfterUpdate(R actual, ResourceID resourceID, R updated) { + if (isCacheFillerEventSource) { + recentOperationCacheFiller().handleRecentResourceUpdate(resourceID, updated, actual); + } + } + + private void prepareEventFiltering(R desired, ResourceID resourceID) { + if (isFilteringEventSource) { + recentOperationEventFilter().prepareForCreateOrUpdateEventFiltering(resourceID, desired); + } + } + + private void cleanupAfterEventFiltering(R desired, ResourceID resourceID, R created) { + if (isFilteringEventSource) { + recentOperationEventFilter().cleanupOnCreateOrUpdateEventFiltering(resourceID, created); + } + } + + @SuppressWarnings("unchecked") + private RecentOperationEventFilter recentOperationEventFilter() { + return (RecentOperationEventFilter) eventSource; + } + + @SuppressWarnings("unchecked") + private RecentOperationCacheFiller recentOperationCacheFiller() { + return (RecentOperationCacheFiller) eventSource; + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java index b131850b1e..cd44012249 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java @@ -3,16 +3,12 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider; -import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; +import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; import io.javaoperatorsdk.operator.processing.event.ExternalResourceCachingEventSource; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; public abstract class AbstractCachingDependentResource - extends AbstractDependentResource - implements EventSourceProvider

{ - - protected ExternalResourceCachingEventSource eventSource; + extends + AbstractEventSourceHolderDependentResource> { private final Class resourceType; protected AbstractCachingDependentResource(Class resourceType) { @@ -20,12 +16,7 @@ protected AbstractCachingDependentResource(Class resourceType) { } public Optional fetchResource(P primaryResource) { - return eventSource.getAssociated(primaryResource); - } - - @Override - public EventSource getEventSource() { - return eventSource; + return eventSource().getAssociated(primaryResource); } @Override @@ -35,6 +26,6 @@ public Class resourceType() { @Override public Optional getResource(P primaryResource) { - return eventSource.getAssociated(primaryResource); + return eventSource().getAssociated(primaryResource); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResource.java index 2b91e6d75f..afd15dcb6d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResource.java @@ -59,17 +59,13 @@ public final void delete(P primary, Context

context) { protected abstract void deleteResource(P primary, Context

context); @Override - protected R handleCreate(R desired, P primary, Context

context) { - var res = this.creator.create(desired, primary, context); - cache.put(ResourceID.fromResource(primary), res); - return res; + protected void cacheAfterCreate(ResourceID resourceID, R created) { + cache.put(resourceID, created); } @Override - protected R handleUpdate(R actual, R desired, P primary, Context

context) { - var res = updater.update(actual, desired, primary, context); - cache.put(ResourceID.fromResource(primary), res); - return res; + protected void cacheAfterUpdate(R actual, ResourceID resourceID, R updated) { + cache.put(resourceID, updated); } public Matcher.Result match(R actualResource, P primary, Context

context) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java index 11b18832a7..b598073a21 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java @@ -2,7 +2,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; +import io.javaoperatorsdk.operator.processing.event.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; public abstract class PerResourcePollingDependentResource @@ -17,9 +17,9 @@ public PerResourcePollingDependentResource(Class resourceType, long pollingPe } @Override - public EventSource initEventSource(EventSourceContext

context) { - eventSource = new PerResourcePollingEventSource<>(this, context.getPrimaryCache(), + protected ExternalResourceCachingEventSource createEventSource( + EventSourceContext

context) { + return new PerResourcePollingEventSource<>(this, context.getPrimaryCache(), getPollingPeriod(), resourceType()); - return eventSource; } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java index 58723a6f11..1cc6e22afe 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java @@ -5,8 +5,8 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.processing.event.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.ResourceID; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PollingEventSource; public abstract class PollingDependentResource @@ -21,8 +21,8 @@ public PollingDependentResource(Class resourceType, long pollingPeriod) { } @Override - public EventSource initEventSource(EventSourceContext

context) { - eventSource = new PollingEventSource<>(this, getPollingPeriod(), resourceType()); - return eventSource; + protected ExternalResourceCachingEventSource createEventSource( + EventSourceContext

context) { + return new PollingEventSource<>(this, getPollingPeriod(), resourceType()); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java index f77ec0b4aa..c96f993126 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java @@ -14,28 +14,25 @@ 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.dependent.EventSourceProvider; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DependentResourceConfigurator; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.KubernetesClientAware; -import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; +import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; import io.javaoperatorsdk.operator.processing.dependent.Matcher; import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result; import io.javaoperatorsdk.operator.processing.event.ResourceID; -import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper; import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers; public abstract class KubernetesDependentResource - extends AbstractDependentResource - implements KubernetesClientAware, EventSourceProvider

, + extends AbstractEventSourceHolderDependentResource> + implements KubernetesClientAware, DependentResourceConfigurator { private static final Logger log = LoggerFactory.getLogger(KubernetesDependentResource.class); protected KubernetesClient client; - private InformerEventSource informerEventSource; private final Matcher matcher; private final ResourceUpdatePreProcessor processor; private final Class resourceType; @@ -80,12 +77,11 @@ private void configureWith(String labelSelector, Set namespaces) { * * @param informerEventSource informer to use* */ - public void configureWith( - InformerEventSource informerEventSource) { - this.informerEventSource = informerEventSource; - + public void configureWith(InformerEventSource informerEventSource) { + setEventSource(informerEventSource); } + @SuppressWarnings("unused") public R create(R target, P primary, Context

context) { return prepare(target, primary, "Creating").create(target); } @@ -121,19 +117,11 @@ protected NonNamespaceOperation, Resource> prepa } @Override - public EventSource initEventSource(EventSourceContext

context) { - if (informerEventSource == null) { - configureWith(null, context.getControllerConfiguration().getNamespaces()); - log.warn("Using default configuration for " + resourceType().getSimpleName() - + " KubernetesDependentResource, call configureWith to provide configuration"); - } - return informerEventSource; - } - - public KubernetesDependentResource setInformerEventSource( - InformerEventSource informerEventSource) { - this.informerEventSource = informerEventSource; - return this; + protected InformerEventSource createEventSource(EventSourceContext

context) { + configureWith(null, context.getControllerConfiguration().getNamespaces()); + log.warn("Using default configuration for " + resourceType().getSimpleName() + + " KubernetesDependentResource, call configureWith to provide configuration"); + return eventSource(); } protected boolean addOwnerReference() { @@ -147,7 +135,7 @@ public Class resourceType() { @Override public Optional getResource(P primaryResource) { - return informerEventSource.getAssociated(primaryResource); + return eventSource().getAssociated(primaryResource); } @Override @@ -164,9 +152,4 @@ public KubernetesClient getKubernetesClient() { protected R desired(P primary, Context

context) { return super.desired(primary, context); } - - @Override - public EventSource getEventSource() { - return informerEventSource; - } } diff --git a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java index 34c7686b45..4ac7dd103d 100644 --- a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java +++ b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java @@ -1,13 +1,13 @@ package io.javaoperatorsdk.operator.sample; import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.Service; -import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; @@ -37,20 +37,25 @@ public class WebPageStandaloneDependentsReconciler private static final Logger log = LoggerFactory.getLogger(WebPageStandaloneDependentsReconciler.class); - private KubernetesDependentResource configMapDR; - private KubernetesDependentResource deploymentDR; - private KubernetesDependentResource serviceDR; + private final Map> dependentResources; public WebPageStandaloneDependentsReconciler(KubernetesClient kubernetesClient) { - createDependentResources(kubernetesClient); + dependentResources = Map.of( + "configmap", new ConfigMapDependentResource(), + "deployment", new DeploymentDependentResource(), + "service", new ServiceDependentResource()); + final var config = new KubernetesDependentResourceConfig() + .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR); + dependentResources.values().forEach(dr -> { + dr.setKubernetesClient(kubernetesClient); + dr.configureWith(config); + }); } @Override public Map prepareEventSources(EventSourceContext context) { - return Map.of( - "configmap", configMapDR.initEventSource(context), - "deployment", deploymentDR.initEventSource(context), - "service", serviceDR.initEventSource(context)); + return dependentResources.entrySet().stream() + .collect(Collectors.toUnmodifiableMap(Entry::getKey, Entry::getValue)); } @Override @@ -58,35 +63,23 @@ public UpdateControl reconcile(WebPage webPage, Context contex throws Exception { simulateErrorIfRequested(webPage); - configMapDR.reconcile(webPage, context); - deploymentDR.reconcile(webPage, context); - serviceDR.reconcile(webPage, context); + dependentResources.values().forEach(dr -> dr.reconcile(webPage, context)); - webPage.setStatus( - createStatus(configMapDR.getResource(webPage).orElseThrow().getMetadata().getName())); + webPage.setStatus(createStatus(getConfigMapName(webPage))); return UpdateControl.updateStatus(webPage); } + private String getConfigMapName(WebPage webPage) { + return dependent("configmap").getResource(webPage).orElseThrow().getMetadata().getName(); + } + @Override public ErrorStatusUpdateControl updateErrorStatus( WebPage resource, Context retryInfo, Exception e) { return handleError(resource, e); } - private void createDependentResources(KubernetesClient client) { - this.configMapDR = new ConfigMapDependentResource(); - this.configMapDR.setKubernetesClient(client); - configMapDR.configureWith(new KubernetesDependentResourceConfig() - .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR)); - - this.deploymentDR = new DeploymentDependentResource(); - deploymentDR.setKubernetesClient(client); - deploymentDR.configureWith(new KubernetesDependentResourceConfig() - .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR)); - - this.serviceDR = new ServiceDependentResource(); - serviceDR.setKubernetesClient(client); - serviceDR.configureWith(new KubernetesDependentResourceConfig() - .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR)); + private KubernetesDependentResource dependent(String name) { + return dependentResources.get(name); } }