From d33df68abcb69a2809af0e1f2fa3b12f579441c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Wed, 28 Sep 2022 09:19:08 +0200 Subject: [PATCH 01/26] fix: PerResourcePollingEventSourceIT integration test race condition issue (#1499) --- .../PerResourcePollingEventSourceTestReconciler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java index dec730d536..ecc33afcb3 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java @@ -57,7 +57,8 @@ public void setKubernetesClient(KubernetesClient kubernetesClient) { } public int getNumberOfExecutions(String name) { - return numberOfExecutions.get(name); + var num = numberOfExecutions.get(name); + return num == null ? 0 : num; } public int getNumberOfFetchExecution(String name) { From 3bb2d456787460e5454e95f1f51845e5e72fd912 Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 27 Jul 2022 13:26:40 +0200 Subject: [PATCH 02/26] feat: improvements on caching and dependent resources --- .../operator/api/reconciler/Context.java | 1 + .../api/reconciler/dependent/DependentResource.java | 9 ++++++++- .../dependent/AbstractDependentResource.java | 9 ++++++++- .../external/AbstractCachingDependentResource.java | 6 ------ .../external/AbstractSimpleDependentResource.java | 2 +- .../kubernetes/KubernetesDependentResource.java | 8 ++------ .../config/ControllerConfigurationOverriderTest.java | 5 ----- .../dependent/AbstractDependentResourceTest.java | 4 ++-- .../dependent/EmptyTestDependentResource.java | 7 ------- .../external/AbstractSimpleDependentResourceTest.java | 4 ++-- .../workflow/AbstractWorkflowExecutorTest.java | 11 ----------- .../StandaloneDependentTestReconciler.java | 2 +- .../sample/WebPageDependentsWorkflowReconciler.java | 2 +- .../sample/WebPageStandaloneDependentsReconciler.java | 2 +- 14 files changed, 27 insertions(+), 45 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index 845810c8a1..fbe83181af 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -17,6 +17,7 @@ default Optional getSecondaryResource(Class expectedType) { Set getSecondaryResources(Class expectedType); + @Deprecated(forRemoval = true) Optional getSecondaryResource(Class expectedType, String eventSourceName); ControllerConfiguration

getControllerConfiguration(); 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 index 0923d19473..1c73cac176 100644 --- 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 @@ -10,7 +10,7 @@ * @param the dependent resource type * @param

the associated primary resource type */ -public interface DependentResource extends ResourceOwner { +public interface DependentResource { /** * Reconciles the dependent resource given the desired primary state @@ -21,6 +21,13 @@ public interface DependentResource extends ResourceOwn */ ReconcileResult reconcile(P primary, Context

context); + /** + * Retrieves the resource type associated with this ResourceOwner + * + * @return the resource type associated with this ResourceOwner + */ + Class resourceType(); + /** * Computes a default name for the specified DependentResource class * 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 5dbdba9358..730add6f01 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 @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.processing.dependent; +import java.util.Optional; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,9 +29,10 @@ public AbstractDependentResource() { updater = updatable ? (Updater) this : null; } + @SuppressWarnings("unchecked") @Override public ReconcileResult reconcile(P primary, Context

context) { - var maybeActual = getSecondaryResource(primary); + Optional maybeActual = getSecondaryResource(primary, context); if (creatable || updatable) { if (maybeActual.isEmpty()) { if (creatable) { @@ -62,6 +65,10 @@ public ReconcileResult reconcile(P primary, Context

context) { return ReconcileResult.noOperation(maybeActual.orElse(null)); } + protected Optional getSecondaryResource(P primary, Context

context) { + return context.getSecondaryResource(resourceType()); + } + private void throwIfNull(R desired, P primary, String descriptor) { if (desired == null) { throw new DependentResourceException( 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 242625bc5d..e7d07a5513 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 @@ -1,7 +1,5 @@ package io.javaoperatorsdk.operator.processing.dependent.external; -import java.util.Optional; - import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; @@ -22,8 +20,4 @@ public Class resourceType() { return resourceType; } - @Override - public Optional getSecondaryResource(P primaryResource) { - return eventSource().getSecondaryResource(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 0675db5f1a..748452c30c 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 @@ -33,7 +33,7 @@ public AbstractSimpleDependentResource(UpdatableCache cache) { } @Override - public Optional getSecondaryResource(HasMetadata primaryResource) { + public Optional getSecondaryResource(P primaryResource, Context

context) { return cache.get(ResourceID.fromResource(primaryResource)); } 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 930e5fd5b4..3de659ca92 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 @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; import java.util.HashMap; -import java.util.Optional; import java.util.Set; import org.slf4j.Logger; @@ -138,7 +137,7 @@ public Result match(R actualResource, P primary, Context

context) { } public void delete(P primary, Context

context) { - var resource = getSecondaryResource(primary); + var resource = context.getSecondaryResource(primary.getClass()); resource.ifPresent(r -> client.resource(r).delete()); } @@ -208,10 +207,7 @@ public Class resourceType() { return resourceType; } - @Override - public Optional getSecondaryResource(P primaryResource) { - return eventSource().getSecondaryResource(primaryResource); - } + @Override public void setKubernetesClient(KubernetesClient kubernetesClient) { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java index 127cd535b1..6e486b5347 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java @@ -1,6 +1,5 @@ package io.javaoperatorsdk.operator.api.config; -import java.util.Optional; import java.util.Set; import org.junit.jupiter.api.Test; @@ -85,10 +84,6 @@ public Class resourceType() { return Object.class; } - @Override - public Optional getSecondaryResource(ConfigMap primary) { - return Optional.empty(); - } } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java index 4edd3dfb4c..004cb5d159 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java @@ -16,7 +16,6 @@ class AbstractDependentResourceTest { - @Test void throwsExceptionIfDesiredIsNullOnCreate() { TestDependentResource testDependentResource = new TestDependentResource(); @@ -80,7 +79,8 @@ public Class resourceType() { } @Override - public Optional getSecondaryResource(TestCustomResource primary) { + protected Optional getSecondaryResource(TestCustomResource primary, + Context context) { return Optional.ofNullable(secondary); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/EmptyTestDependentResource.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/EmptyTestDependentResource.java index aa75849051..dab1bc0132 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/EmptyTestDependentResource.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/EmptyTestDependentResource.java @@ -1,7 +1,5 @@ package io.javaoperatorsdk.operator.processing.dependent; -import java.util.Optional; - import io.fabric8.kubernetes.api.model.apps.Deployment; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @@ -17,11 +15,6 @@ public ReconcileResult reconcile(TestCustomResource primary, return null; } - @Override - public Optional getSecondaryResource(TestCustomResource primaryResource) { - return Optional.empty(); - } - @Override public Class resourceType() { return Deployment.class; diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResourceTest.java index e020fd27a3..520f44365f 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractSimpleDependentResourceTest.java @@ -45,14 +45,14 @@ void getsTheResourceFromSupplyIfReconciling() { simpleDependentResource.reconcile(TestUtils.testCustomResource1(), null); verify(supplierMock, times(1)).get(); - assertThat(simpleDependentResource.getSecondaryResource(TestUtils.testCustomResource1())) + assertThat(simpleDependentResource.getSecondaryResource(TestUtils.testCustomResource1(), null)) .isPresent() .isEqualTo(Optional.of(SampleExternalResource.testResource1())); } @Test void getResourceReadsTheResourceFromCache() { - simpleDependentResource.getSecondaryResource(TestUtils.testCustomResource1()); + simpleDependentResource.getSecondaryResource(TestUtils.testCustomResource1(), null); verify(supplierMock, times(0)).get(); verify(updatableCacheMock, times(1)).get(any()); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java index 8dfab3fa20..9c10c06cc0 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Optional; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; @@ -49,11 +48,6 @@ public Class resourceType() { return String.class; } - @Override - public Optional getSecondaryResource(TestCustomResource primary) { - return Optional.of(VALUE); - } - @Override public String toString() { return name; @@ -113,11 +107,6 @@ public Class resourceType() { return String.class; } - @Override - public Optional getSecondaryResource(TestCustomResource primary) { - return Optional.of(VALUE); - } - @Override public String toString() { return name; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/standalonedependent/StandaloneDependentTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/standalonedependent/StandaloneDependentTestReconciler.java index af6b2d7e25..2dace670ba 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/standalonedependent/StandaloneDependentTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/standalonedependent/StandaloneDependentTestReconciler.java @@ -47,7 +47,7 @@ public UpdateControl reconcile( StandaloneDependentTestCustomResource primary, Context context) { deploymentDependent.reconcile(primary, context); - Optional deployment = deploymentDependent.getSecondaryResource(primary); + Optional deployment = context.getSecondaryResource(Deployment.class); if (deployment.isEmpty()) { throw new IllegalStateException("Resource should not be empty after reconcile."); } diff --git a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java index 6986180b89..06080be67b 100644 --- a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java +++ b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java @@ -69,7 +69,7 @@ public UpdateControl reconcile(WebPage webPage, Context contex webPage.setStatus( createStatus( - configMapDR.getSecondaryResource(webPage).orElseThrow().getMetadata().getName())); + context.getSecondaryResource(ConfigMap.class).orElseThrow().getMetadata().getName())); return UpdateControl.patchStatus(webPage); } 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 0bb692a4d0..b99e130135 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 @@ -65,7 +65,7 @@ public UpdateControl reconcile(WebPage webPage, Context contex webPage.setStatus( createStatus( - configMapDR.getSecondaryResource(webPage).orElseThrow().getMetadata().getName())); + context.getSecondaryResource(ConfigMap.class).orElseThrow().getMetadata().getName())); return UpdateControl.patchStatus(webPage); } From 741ac0f02fbe22f0dd86e0765e46927ef1759797 Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 27 Jul 2022 14:26:13 +0200 Subject: [PATCH 03/26] wip --- .../operator/api/reconciler/Context.java | 11 +++++--- .../api/reconciler/DefaultContext.java | 7 +++++ .../api/reconciler/ResourceDiscriminator.java | 14 ++++++++++ .../reconciler/ResourceListDiscriminator.java | 19 ++++++++++++++ .../dependent/DependentResource.java | 1 - .../operator/processing/ResourceOwner.java | 26 ------------------- .../processing/event/EventSourceManager.java | 20 +++++++++----- .../event/EventSourceRetriever.java | 18 +++++++++++++ .../processing/event/EventSources.java | 5 ++-- .../event/source/ResourceEventSource.java | 11 +++++--- .../WebPageDependentsWorkflowReconciler.java | 2 -- 11 files changed, 89 insertions(+), 45 deletions(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java delete mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index fbe83181af..a26e7c46fb 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -11,14 +11,17 @@ public interface Context

{ Optional getRetryInfo(); - default Optional getSecondaryResource(Class expectedType) { - return getSecondaryResource(expectedType, null); + default Optional getSecondaryResource(Class expectedType) { + return getSecondaryResource(expectedType, (String) null); } - Set getSecondaryResources(Class expectedType); + Set getSecondaryResources(Class expectedType); @Deprecated(forRemoval = true) - Optional getSecondaryResource(Class expectedType, String eventSourceName); + Optional getSecondaryResource(Class expectedType, String eventSourceName); + + Optional getSecondaryResource(Class expectedType, + ResourceDiscriminator discriminator); ControllerConfiguration

getControllerConfiguration(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index afb37a8c53..3ad03516ae 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -47,6 +47,13 @@ public Optional getSecondaryResource(Class expectedType, String eventS .getSecondaryResource(primaryResource); } + // todo implement + @Override + public Optional getSecondaryResource(Class expectedType, + ResourceDiscriminator discriminator) { + return Optional.empty(); + } + @Override public ControllerConfiguration

getControllerConfiguration() { return controllerConfiguration; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java new file mode 100644 index 0000000000..3ff1dc58a2 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.api.reconciler; + +import java.util.Optional; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; + +// todo is discriminator a good name? it not just discriminates but also reads from cache +public interface ResourceDiscriminator { + + Optional distinguish(Class resource, Context

context, + EventSourceRetriever

eventSourceManager); + +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java new file mode 100644 index 0000000000..da6f173268 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java @@ -0,0 +1,19 @@ +package io.javaoperatorsdk.operator.api.reconciler; + +import java.util.Optional; +import java.util.Set; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; + +public abstract class ResourceListDiscriminator + implements ResourceDiscriminator { + @Override + public Optional distinguish(Class resource, Context

context, + EventSourceRetriever

eventSourceManager) { + var resources = context.getSecondaryResources(resource); + return distinguish(resources); + } + + abstract Optional distinguish(Set resourceList); +} 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 index 1c73cac176..3bd9bf8061 100644 --- 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 @@ -2,7 +2,6 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.processing.ResourceOwner; /** * An interface to implement and provide dependent resource support. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java deleted file mode 100644 index f9c02a8a33..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.javaoperatorsdk.operator.processing; - -import java.util.Optional; - -import io.fabric8.kubernetes.api.model.HasMetadata; - -public interface ResourceOwner { - - /** - * Retrieves the resource type associated with this ResourceOwner - * - * @return the resource type associated with this ResourceOwner - */ - Class resourceType(); - - /** - * Retrieves the resource associated with the specified primary one, returning the actual state of - * the resource. Typically, this state might come from a local cache, updated after - * reconciliation. - * - * @param primary the primary resource for which we want to retrieve the secondary resource - * @return an {@link Optional} containing the secondary resource or {@link Optional#empty()} if it - * doesn't exist - */ - Optional getSecondaryResource(P primary); -} 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 3f1e5e848d..6e4305b82a 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 @@ -23,7 +23,8 @@ import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceAction; import io.javaoperatorsdk.operator.processing.event.source.timer.TimerEventSource; -public class EventSourceManager

implements LifecycleAware { +public class EventSourceManager

+ implements LifecycleAware, EventSourceRetriever

{ private static final Logger log = LoggerFactory.getLogger(EventSourceManager.class); @@ -171,17 +172,24 @@ public ControllerResourceEventSource

getControllerResourceEventSource() { return eventSources.controllerResourceEventSource(); } - ResourceEventSource getResourceEventSourceFor( - Class dependentType) { + @Override + public ResourceEventSource getResourceEventSourceFor( + Class dependentType) { return getResourceEventSourceFor(dependentType, null); } - public List> getEventSourcesFor(Class dependentType) { + public List> getResourceEventSourcesFor(Class dependentType) { return eventSources.getEventSources(dependentType); } - public ResourceEventSource getResourceEventSourceFor( - Class dependentType, String qualifier) { + @Deprecated + public List> getEventSourcesFor(Class dependentType) { + return eventSources.getEventSources(dependentType); + } + + @Override + public ResourceEventSource getResourceEventSourceFor( + Class dependentType, String qualifier) { Objects.requireNonNull(dependentType, "dependentType is Mandatory"); return eventSources.get(dependentType, qualifier); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java new file mode 100644 index 0000000000..a31d8902b0 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java @@ -0,0 +1,18 @@ +package io.javaoperatorsdk.operator.processing.event; + +import java.util.List; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.event.source.ResourceEventSource; + +public interface EventSourceRetriever

{ + + ResourceEventSource getResourceEventSourceFor( + Class dependentType); + + ResourceEventSource getResourceEventSourceFor( + Class dependentType, String qualifier); + + List> getResourceEventSourcesFor(Class dependentType); + +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java index 17de7ff947..e4fabe7ff8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSources.java @@ -8,7 +8,6 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.processing.Controller; -import io.javaoperatorsdk.operator.processing.ResourceOwner; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.ResourceEventSource; import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerResourceEventSource; @@ -86,8 +85,8 @@ public void add(String name, EventSource eventSource) { @SuppressWarnings("rawtypes") private Class getResourceType(EventSource source) { - return source instanceof ResourceOwner - ? ((ResourceOwner) source).resourceType() + return source instanceof ResourceEventSource + ? ((ResourceEventSource) source).resourceType() : source.getClass(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java index bf6b9c0fd3..d58ea11e48 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java @@ -4,14 +4,19 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.ResourceOwner; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter; -public interface ResourceEventSource extends EventSource, - ResourceOwner { +public interface ResourceEventSource extends EventSource { + + /** + * Retrieves the resource type associated with this ResourceOwner + * + * @return the resource type associated with this ResourceOwner + */ + Class resourceType(); default Optional getSecondaryResource(P primary) { var resources = getSecondaryResources(primary); diff --git a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java index 06080be67b..6b81a9d6e3 100644 --- a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java +++ b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java @@ -93,6 +93,4 @@ private void initDependentResources(KubernetesClient client) { }); } - - } From a5b2bb6067e357a24bbfc7c9226717d140b389b1 Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 27 Jul 2022 16:05:27 +0200 Subject: [PATCH 04/26] fix --- .../dependent/kubernetes/KubernetesDependentResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3de659ca92..9b37d3b880 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 @@ -137,7 +137,7 @@ public Result match(R actualResource, P primary, Context

context) { } public void delete(P primary, Context

context) { - var resource = context.getSecondaryResource(primary.getClass()); + var resource = context.getSecondaryResource(resourceType()); resource.ifPresent(r -> client.resource(r).delete()); } From 7cbc2976af42e48cf9a18c06edbd36beaffa3a9f Mon Sep 17 00:00:00 2001 From: csviri Date: Thu, 28 Jul 2022 13:11:18 +0200 Subject: [PATCH 05/26] kubernetes dependent resource configuration --- .../AnnotationControllerConfiguration.java | 11 +++++++---- .../reconciler/VoidResourceDiscriminator.java | 16 ++++++++++++++++ .../dependent/AbstractDependentResource.java | 19 ++++++++++++++++++- .../kubernetes/KubernetesDependent.java | 5 +++++ .../KubernetesDependentResource.java | 1 + .../KubernetesDependentResourceConfig.java | 19 +++++++++++++------ 6 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index b5e3fffcf0..59dc80869a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -17,15 +17,13 @@ import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.ReconcilerUtils; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; -import io.javaoperatorsdk.operator.api.reconciler.Constants; +import io.javaoperatorsdk.operator.api.reconciler.*; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig; -import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition; import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters; @@ -287,6 +285,7 @@ private Object createKubernetesResourceConfig(Class OnUpdateFilter onUpdateFilter = null; OnDeleteFilter onDeleteFilter = null; GenericFilter genericFilter = null; + ResourceDiscriminator resourceDiscriminator = null; if (kubeDependent != null) { if (!Arrays.equals(KubernetesDependent.DEFAULT_NAMESPACES, kubeDependent.namespaces())) { @@ -311,10 +310,14 @@ private Object createKubernetesResourceConfig(Class genericFilter = createFilter(kubeDependent.genericFilter(), GenericFilter.class, context) .orElse(null); + + resourceDiscriminator = instantiateIfNotVoid(kubeDependent.resourceDiscriminator(), + VoidResourceDiscriminator.class); } config = - new KubernetesDependentResourceConfig(namespaces, labelSelector, configuredNS, onAddFilter, + new KubernetesDependentResourceConfig(namespaces, labelSelector, configuredNS, + resourceDiscriminator, onAddFilter, onUpdateFilter, onDeleteFilter, genericFilter); return config; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java new file mode 100644 index 0000000000..0caec9361d --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java @@ -0,0 +1,16 @@ +package io.javaoperatorsdk.operator.api.reconciler; + +import java.util.Optional; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; + +public class VoidResourceDiscriminator + implements ResourceDiscriminator { + + @Override + public Optional distinguish(Class resource, Context

context, + EventSourceRetriever

eventSourceManager) { + throw new UnsupportedOperationException(); + } +} 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 730add6f01..9e12f25db0 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 @@ -8,6 +8,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.Ignore; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.event.ResourceID; @@ -23,6 +24,8 @@ public abstract class AbstractDependentResource protected Creator creator; protected Updater updater; + private ResourceDiscriminator resourceDiscriminator; + @SuppressWarnings("unchecked") public AbstractDependentResource() { creator = creatable ? (Creator) this : null; @@ -66,7 +69,11 @@ public ReconcileResult reconcile(P primary, Context

context) { } protected Optional getSecondaryResource(P primary, Context

context) { - return context.getSecondaryResource(resourceType()); + if (resourceDiscriminator == null) { + return context.getSecondaryResource(resourceType()); + } else { + return context.getSecondaryResource(resourceType(), resourceDiscriminator); + } } private void throwIfNull(R desired, P primary, String descriptor) { @@ -125,4 +132,14 @@ protected R desired(P primary, Context

context) { throw new IllegalStateException( "desired method must be implemented if this DependentResource can be created and/or updated"); } + + protected ResourceDiscriminator getResourceDiscriminator() { + return resourceDiscriminator; + } + + protected AbstractDependentResource setResourceDiscriminator( + ResourceDiscriminator resourceDiscriminator) { + this.resourceDiscriminator = resourceDiscriminator; + return this; + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java index f66ff95373..6453a1b061 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java @@ -6,6 +6,9 @@ import java.lang.annotation.Target; import io.javaoperatorsdk.operator.api.reconciler.Constants; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; +import io.javaoperatorsdk.operator.api.reconciler.VoidResourceDiscriminator; +import io.javaoperatorsdk.operator.processing.event.source.filter.*; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter; @@ -68,4 +71,6 @@ * itself if no value is set */ Class genericFilter() default GenericFilter.class; + + Class resourceDiscriminator() default VoidResourceDiscriminator.class; } 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 9b37d3b880..e6d358ce12 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 @@ -166,6 +166,7 @@ protected InformerEventSource createEventSource(EventSourceContext

cont onUpdateFilter = kubernetesDependentResourceConfig.onUpdateFilter(); onDeleteFilter = kubernetesDependentResourceConfig.onDeleteFilter(); genericFilter = kubernetesDependentResourceConfig.genericFilter(); + setResourceDiscriminator(kubernetesDependentResourceConfig.getResourceDiscriminator()); configureWith(kubernetesDependentResourceConfig.labelSelector(), kubernetesDependentResourceConfig.namespaces(), diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java index e4a75b165a..fbd4eebd9a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java @@ -3,6 +3,7 @@ import java.util.Set; import io.javaoperatorsdk.operator.api.reconciler.Constants; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter; @@ -15,7 +16,7 @@ public class KubernetesDependentResourceConfig { private Set namespaces = Constants.SAME_AS_CONTROLLER_NAMESPACES_SET; private String labelSelector = NO_VALUE_SET; private boolean namespacesWereConfigured = false; - + private ResourceDiscriminator resourceDiscriminator; private OnAddFilter onAddFilter; @@ -29,7 +30,8 @@ public KubernetesDependentResourceConfig() {} @SuppressWarnings("rawtypes") public KubernetesDependentResourceConfig(Set namespaces, String labelSelector, - boolean configuredNS, OnAddFilter onAddFilter, + boolean configuredNS, ResourceDiscriminator resourceDiscriminator, + OnAddFilter onAddFilter, OnUpdateFilter onUpdateFilter, OnDeleteFilter onDeleteFilter, GenericFilter genericFilter) { this.namespaces = namespaces; @@ -42,7 +44,7 @@ public KubernetesDependentResourceConfig(Set namespaces, String labelSel } public KubernetesDependentResourceConfig(Set namespaces, String labelSelector) { - this(namespaces, labelSelector, true, null, null, null, null); + this(namespaces, labelSelector, true, null, null, null, null, null); } public KubernetesDependentResourceConfig setNamespaces(Set namespaces) { @@ -73,17 +75,22 @@ public OnAddFilter onAddFilter() { return onAddFilter; } - @SuppressWarnings("rawtypes") - public OnUpdateFilter onUpdateFilter() { + + public OnUpdateFilter onUpdateFilter() { return onUpdateFilter; } @SuppressWarnings("rawtypes") - public OnDeleteFilter onDeleteFilter() { + public OnDeleteFilter onDeleteFilter() { return onDeleteFilter; } public GenericFilter genericFilter() { return genericFilter; } + + @SuppressWarnings("rawtypes") + public ResourceDiscriminator getResourceDiscriminator() { + return resourceDiscriminator; + } } From fbac50f796229653e0a7646069d752031a9e402c Mon Sep 17 00:00:00 2001 From: csviri Date: Thu, 28 Jul 2022 14:58:09 +0200 Subject: [PATCH 06/26] IT fix --- .../operator/api/reconciler/DefaultContext.java | 4 ++-- .../api/reconciler/ResourceDiscriminator.java | 2 +- .../reconciler/ResourceListDiscriminator.java | 7 ++++--- .../reconciler/VoidResourceDiscriminator.java | 2 +- .../dependent/AbstractDependentResource.java | 1 + .../KubernetesDependentResourceConfig.java | 1 + .../ConfigMapDependentResource1.java | 16 +++++++++++++++- .../ConfigMapDependentResource2.java | 16 +++++++++++++++- 8 files changed, 40 insertions(+), 9 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index 3ad03516ae..0d5bc22018 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -47,11 +47,11 @@ public Optional getSecondaryResource(Class expectedType, String eventS .getSecondaryResource(primaryResource); } - // todo implement @Override public Optional getSecondaryResource(Class expectedType, ResourceDiscriminator discriminator) { - return Optional.empty(); + return discriminator.distinguish(expectedType, primaryResource, this, + controller.getEventSourceManager()); } @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java index 3ff1dc58a2..2fe69c3804 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -8,7 +8,7 @@ // todo is discriminator a good name? it not just discriminates but also reads from cache public interface ResourceDiscriminator { - Optional distinguish(Class resource, Context

context, + Optional distinguish(Class resource, P primary, Context

context, EventSourceRetriever

eventSourceManager); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java index da6f173268..fbb86dbd04 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java @@ -6,14 +6,15 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; +// todo this requires rather a matcher (name+namespace) as input public abstract class ResourceListDiscriminator implements ResourceDiscriminator { @Override - public Optional distinguish(Class resource, Context

context, + public Optional distinguish(Class resource, P primary, Context

context, EventSourceRetriever

eventSourceManager) { var resources = context.getSecondaryResources(resource); - return distinguish(resources); + return distinguish(primary, resources); } - abstract Optional distinguish(Set resourceList); + protected abstract Optional distinguish(P primary, Set resourceList); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java index 0caec9361d..3a627df109 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java @@ -9,7 +9,7 @@ public class VoidResourceDiscriminator implements ResourceDiscriminator { @Override - public Optional distinguish(Class resource, Context

context, + public Optional distinguish(Class resource, P primary, Context

context, EventSourceRetriever

eventSourceManager) { throw new UnsupportedOperationException(); } 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 9e12f25db0..130b6237e3 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 @@ -24,6 +24,7 @@ public abstract class AbstractDependentResource protected Creator creator; protected Updater updater; + // todo discuss, rather implement this as interface? private ResourceDiscriminator resourceDiscriminator; @SuppressWarnings("unchecked") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java index fbd4eebd9a..93b399631b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java @@ -41,6 +41,7 @@ public KubernetesDependentResourceConfig(Set namespaces, String labelSel this.onUpdateFilter = onUpdateFilter; this.onDeleteFilter = onDeleteFilter; this.genericFilter = genericFilter; + this.resourceDiscriminator = resourceDiscriminator; } public KubernetesDependentResourceConfig(Set namespaces, String labelSelector) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java index 14530cf17e..d9364f0d83 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java @@ -2,15 +2,19 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; +import java.util.Set; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ResourceListDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; -@KubernetesDependent(labelSelector = "dependent = cm1") +@KubernetesDependent(labelSelector = "dependent = cm1", + resourceDiscriminator = ConfigMapDependentResource1.CM1ResourceDiscriminator.class) public class ConfigMapDependentResource1 extends CRUDKubernetesDependentResource { @@ -42,4 +46,14 @@ protected ConfigMap desired(OrderedManagedDependentCustomResource primary, return configMap; } + public static class CM1ResourceDiscriminator + extends ResourceListDiscriminator { + @Override + protected Optional distinguish(OrderedManagedDependentCustomResource primary, + Set resourceList) { + return resourceList.stream().filter(cm -> cm.getMetadata().getName() + .equals(primary.getMetadata().getName() + "1")).findFirst(); + } + } + } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java index 35ae69586e..6ad23d0ae9 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java @@ -2,15 +2,19 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; +import java.util.Set; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ResourceListDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; -@KubernetesDependent(labelSelector = "dependent = cm2") +@KubernetesDependent(labelSelector = "dependent = cm2", + resourceDiscriminator = ConfigMapDependentResource2.CM2ResourceDiscriminator.class) public class ConfigMapDependentResource2 extends CRUDKubernetesDependentResource { @@ -42,4 +46,14 @@ protected ConfigMap desired(OrderedManagedDependentCustomResource primary, return configMap; } + public static class CM2ResourceDiscriminator + extends ResourceListDiscriminator { + @Override + protected Optional distinguish(OrderedManagedDependentCustomResource primary, + Set resourceList) { + return resourceList.stream().filter(cm -> cm.getMetadata().getName() + .equals(primary.getMetadata().getName() + "2")).findFirst(); + } + } + } From 5fe2013ed37a0e7e7d18186c4badfc8e6fce563a Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 29 Jul 2022 09:31:48 +0200 Subject: [PATCH 07/26] fixed ITs --- .../ResourceIDMatcherDiscriminator.java | 30 +++++++++++++++++++ .../reconciler/ResourceListDiscriminator.java | 20 ------------- .../KubernetesDependentResourceConfig.java | 6 ++++ .../MultipleDependentResourceReconciler.java | 23 +++++++++----- .../ConfigMapDependentResource1.java | 14 ++++----- .../ConfigMapDependentResource2.java | 14 ++++----- 6 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java delete mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java new file mode 100644 index 0000000000..0d06222e45 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java @@ -0,0 +1,30 @@ +package io.javaoperatorsdk.operator.api.reconciler; + +import java.util.Optional; +import java.util.function.Function; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; +import io.javaoperatorsdk.operator.processing.event.ResourceID; + +public class ResourceIDMatcherDiscriminator + implements ResourceDiscriminator { + + private final Function mapper; + + public ResourceIDMatcherDiscriminator(Function mapper) { + this.mapper = mapper; + } + + @Override + public Optional distinguish(Class resource, P primary, Context

context, + EventSourceRetriever

eventSourceManager) { + var resourceID = mapper.apply(primary); + return context.getSecondaryResources(resource).stream() + .filter(r -> r.getMetadata().getName() + .equals(resourceID.getName()) && + resourceID.getNamespace().map(ns -> ns.equals(r.getMetadata().getNamespace())) + .orElse(true)) + .findFirst(); + } +} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java deleted file mode 100644 index fbb86dbd04..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceListDiscriminator.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler; - -import java.util.Optional; -import java.util.Set; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; - -// todo this requires rather a matcher (name+namespace) as input -public abstract class ResourceListDiscriminator - implements ResourceDiscriminator { - @Override - public Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceManager) { - var resources = context.getSecondaryResources(resource); - return distinguish(primary, resources); - } - - protected abstract Optional distinguish(P primary, Set resourceList); -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java index 93b399631b..a185071221 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java @@ -94,4 +94,10 @@ public GenericFilter genericFilter() { public ResourceDiscriminator getResourceDiscriminator() { return resourceDiscriminator; } + + public

KubernetesDependentResourceConfig setResourceDiscriminator( + ResourceDiscriminator resourceDiscriminator) { + this.resourceDiscriminator = resourceDiscriminator; + return this; + } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java index 8cdbb81eba..69c1ba0b04 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java @@ -3,15 +3,12 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; -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.api.reconciler.*; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig; +import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; @@ -32,14 +29,24 @@ public class MultipleDependentResourceReconciler public MultipleDependentResourceReconciler() { firstDependentResourceConfigMap = new MultipleDependentResourceConfigMap(FIRST_CONFIG_MAP_ID); + secondDependentResourceConfigMap = new MultipleDependentResourceConfigMap(SECOND_CONFIG_MAP_ID); firstDependentResourceConfigMap.configureWith( new KubernetesDependentResourceConfig() - .setLabelSelector(getLabelSelector(FIRST_CONFIG_MAP_ID))); + .setLabelSelector(getLabelSelector(FIRST_CONFIG_MAP_ID)) + .setResourceDiscriminator( + new ResourceIDMatcherDiscriminator( + p -> new ResourceID(p.getConfigMapName(FIRST_CONFIG_MAP_ID), + p.getMetadata().getNamespace())))); + secondDependentResourceConfigMap.configureWith( new KubernetesDependentResourceConfig() - .setLabelSelector(getLabelSelector(SECOND_CONFIG_MAP_ID))); + .setLabelSelector(getLabelSelector(SECOND_CONFIG_MAP_ID)) + .setResourceDiscriminator( + new ResourceIDMatcherDiscriminator( + p -> new ResourceID(p.getConfigMapName(SECOND_CONFIG_MAP_ID), + p.getMetadata().getNamespace())))); } private String getLabelSelector(int resourceId) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java index d9364f0d83..bf8d60d9c4 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource1.java @@ -2,16 +2,15 @@ import java.util.HashMap; import java.util.Map; -import java.util.Optional; -import java.util.Set; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.ResourceListDiscriminator; +import io.javaoperatorsdk.operator.api.reconciler.ResourceIDMatcherDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; +import io.javaoperatorsdk.operator.processing.event.ResourceID; @KubernetesDependent(labelSelector = "dependent = cm1", resourceDiscriminator = ConfigMapDependentResource1.CM1ResourceDiscriminator.class) @@ -47,12 +46,9 @@ protected ConfigMap desired(OrderedManagedDependentCustomResource primary, } public static class CM1ResourceDiscriminator - extends ResourceListDiscriminator { - @Override - protected Optional distinguish(OrderedManagedDependentCustomResource primary, - Set resourceList) { - return resourceList.stream().filter(cm -> cm.getMetadata().getName() - .equals(primary.getMetadata().getName() + "1")).findFirst(); + extends ResourceIDMatcherDiscriminator { + public CM1ResourceDiscriminator() { + super(p -> new ResourceID(p.getMetadata().getName() + "1", p.getMetadata().getNamespace())); } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java index 6ad23d0ae9..2b17d615b9 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/orderedmanageddependent/ConfigMapDependentResource2.java @@ -2,16 +2,15 @@ import java.util.HashMap; import java.util.Map; -import java.util.Optional; -import java.util.Set; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.ResourceListDiscriminator; +import io.javaoperatorsdk.operator.api.reconciler.ResourceIDMatcherDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; +import io.javaoperatorsdk.operator.processing.event.ResourceID; @KubernetesDependent(labelSelector = "dependent = cm2", resourceDiscriminator = ConfigMapDependentResource2.CM2ResourceDiscriminator.class) @@ -47,12 +46,9 @@ protected ConfigMap desired(OrderedManagedDependentCustomResource primary, } public static class CM2ResourceDiscriminator - extends ResourceListDiscriminator { - @Override - protected Optional distinguish(OrderedManagedDependentCustomResource primary, - Set resourceList) { - return resourceList.stream().filter(cm -> cm.getMetadata().getName() - .equals(primary.getMetadata().getName() + "2")).findFirst(); + extends ResourceIDMatcherDiscriminator { + public CM2ResourceDiscriminator() { + super(p -> new ResourceID(p.getMetadata().getName() + "2", p.getMetadata().getNamespace())); } } From 28287060c80283e59c7a71122c3b98bd75a99f80 Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 29 Jul 2022 13:48:16 +0200 Subject: [PATCH 08/26] index based discriminator --- .../api/reconciler/ResourceDiscriminator.java | 2 +- .../ResourceIDMatcherDiscriminator.java | 2 +- .../reconciler/VoidResourceDiscriminator.java | 2 +- .../dependent/AbstractDependentResource.java | 5 +- .../KubernetesDependentResource.java | 18 +-- .../operator/IndexDiscriminatorIT.java | 77 +++++++++++ .../IndexDiscriminator.java | 42 ++++++ .../IndexDiscriminatorTestCustomResource.java | 16 +++ .../IndexDiscriminatorTestDRConfigMap.java | 38 ++++++ .../IndexDiscriminatorTestReconciler.java | 120 ++++++++++++++++++ .../IndexDiscriminatorTestSpec.java | 15 +++ .../IndexDiscriminatorTestStatus.java | 5 + .../MultipleDependentResourceConfigMap.java | 1 - .../MultipleDependentResourceReconciler.java | 7 - 14 files changed, 329 insertions(+), 21 deletions(-) create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/IndexDiscriminatorIT.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestCustomResource.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestDRConfigMap.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestReconciler.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestSpec.java create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestStatus.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java index 2fe69c3804..0505fd0b57 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -9,6 +9,6 @@ public interface ResourceDiscriminator { Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceManager); + EventSourceRetriever

eventSourceRetriever); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java index 0d06222e45..3df1956bf9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java @@ -18,7 +18,7 @@ public ResourceIDMatcherDiscriminator(Function mapper) { @Override public Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceManager) { + EventSourceRetriever

eventSourceRetriever) { var resourceID = mapper.apply(primary); return context.getSecondaryResources(resource).stream() .filter(r -> r.getMetadata().getName() diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java index 3a627df109..a02c0c6a95 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java @@ -10,7 +10,7 @@ public class VoidResourceDiscriminator @Override public Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceManager) { + EventSourceRetriever

eventSourceRetriever) { throw new UnsupportedOperationException(); } } 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 130b6237e3..5ecd52cc35 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 @@ -134,11 +134,12 @@ protected R desired(P primary, Context

context) { "desired method must be implemented if this DependentResource can be created and/or updated"); } - protected ResourceDiscriminator getResourceDiscriminator() { + // todo review & refactor configuration to cover all cases + public ResourceDiscriminator getResourceDiscriminator() { return resourceDiscriminator; } - protected AbstractDependentResource setResourceDiscriminator( + public AbstractDependentResource setResourceDiscriminator( ResourceDiscriminator resourceDiscriminator) { this.resourceDiscriminator = resourceDiscriminator; return this; 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 e6d358ce12..5c8e7f35f5 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 @@ -67,13 +67,15 @@ private void configureWith(String labelSelector, Set namespaces, namespaces = context.getControllerConfiguration().getNamespaces(); } - var ic = InformerConfiguration.from(resourceType()) - .withLabelSelector(labelSelector) - .withSecondaryToPrimaryMapper(getSecondaryToPrimaryMapper()) - .withNamespaces(namespaces, inheritNamespacesOnChange) - .build(); - - configureWith(new InformerEventSource<>(ic, context)); + if (eventSource() == null) { + var ic = InformerConfiguration.from(resourceType()) + .withLabelSelector(labelSelector) + .withSecondaryToPrimaryMapper(getSecondaryToPrimaryMapper()) + .withNamespaces(namespaces, inheritNamespacesOnChange) + .build(); + + configureWith(new InformerEventSource<>(ic, context)); + } } @SuppressWarnings("unchecked") @@ -137,7 +139,7 @@ public Result match(R actualResource, P primary, Context

context) { } public void delete(P primary, Context

context) { - var resource = context.getSecondaryResource(resourceType()); + var resource = getSecondaryResource(primary, context); resource.ifPresent(r -> client.resource(r).delete()); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IndexDiscriminatorIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IndexDiscriminatorIT.java new file mode 100644 index 0000000000..fe5b63de8a --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IndexDiscriminatorIT.java @@ -0,0 +1,77 @@ +package io.javaoperatorsdk.operator; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension; +import io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestCustomResource; +import io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler; +import io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestSpec; + +import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestDRConfigMap.DATA_KEY; +import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler.FIRST_CONFIG_MAP_SUFFIX_1; +import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler.FIRST_CONFIG_MAP_SUFFIX_2; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +class IndexDiscriminatorIT { + + public static final String TEST_RESOURCE_1 = "test1"; + public static final String CHANGED_SPEC_VALUE = "otherValue"; + @RegisterExtension + LocallyRunOperatorExtension operator = + LocallyRunOperatorExtension.builder().withReconciler(IndexDiscriminatorTestReconciler.class) + .build(); + + @Test + void resourcesFoundAndReconciled() { + var res = operator.create(createTestCustomResource()); + var reconciler = operator.getReconcilerOfType(IndexDiscriminatorTestReconciler.class); + + await().untilAsserted(() -> { + assertThat(reconciler.getNumberOfExecutions()).isEqualTo(1); + assertThat(operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_1)) + .isNotNull(); + assertThat(operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_2)) + .isNotNull(); + }); + + res.getSpec().setValue(CHANGED_SPEC_VALUE); + res = operator.replace(res); + + await().untilAsserted(() -> { + assertThat(reconciler.getNumberOfExecutions()).isEqualTo(2); + var cm1 = operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_1); + var cm2 = operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_2); + assertThat(cm1).isNotNull(); + assertThat(cm2).isNotNull(); + assertThat(cm1.getData().get(DATA_KEY)).isEqualTo(CHANGED_SPEC_VALUE); + assertThat(cm2.getData().get(DATA_KEY)).isEqualTo(CHANGED_SPEC_VALUE); + }); + + operator.delete(res); + + await().untilAsserted(() -> { + var cm1 = operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_1); + var cm2 = operator.get(ConfigMap.class, TEST_RESOURCE_1 + FIRST_CONFIG_MAP_SUFFIX_2); + assertThat(cm1).isNull(); + assertThat(cm2).isNull(); + }); + } + + public IndexDiscriminatorTestCustomResource createTestCustomResource() { + IndexDiscriminatorTestCustomResource resource = + new IndexDiscriminatorTestCustomResource(); + resource.setMetadata( + new ObjectMetaBuilder() + .withName(TEST_RESOURCE_1) + .withNamespace(operator.getNamespace()) + .build()); + resource.setSpec(new IndexDiscriminatorTestSpec()); + resource.getSpec().setValue("default"); + return resource; + } + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java new file mode 100644 index 0000000000..6cf72519a1 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java @@ -0,0 +1,42 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +import java.util.Optional; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; +import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; + +import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler.configMapKeyFromPrimary; + +public class IndexDiscriminator + implements ResourceDiscriminator { + + private final String indexName; + private final String nameSuffix; + + public IndexDiscriminator(String indexName, String nameSuffix) { + this.indexName = indexName; + this.nameSuffix = nameSuffix; + } + + @Override + public Optional distinguish(Class resource, + IndexDiscriminatorTestCustomResource primary, + Context context, + EventSourceRetriever eventSourceRetriever) { + + InformerEventSource eventSource = + (InformerEventSource) eventSourceRetriever + .getResourceEventSourceFor(ConfigMap.class); + var resources = eventSource.byIndex(indexName, configMapKeyFromPrimary(primary, nameSuffix)); + if (resources.isEmpty()) { + return Optional.empty(); + } else if (resources.size() > 1) { + throw new IllegalStateException("more than one resource"); + } else { + return Optional.of(resources.get(0)); + } + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestCustomResource.java new file mode 100644 index 0000000000..729b1d80eb --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestCustomResource.java @@ -0,0 +1,16 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +import io.fabric8.kubernetes.api.model.Namespaced; +import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.ShortNames; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@ShortNames("idt") +public class IndexDiscriminatorTestCustomResource + extends CustomResource + implements Namespaced { + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestDRConfigMap.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestDRConfigMap.java new file mode 100644 index 0000000000..88dc40f55c --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestDRConfigMap.java @@ -0,0 +1,38 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +import java.util.HashMap; +import java.util.Map; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDNoGCKubernetesDependentResource; +import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; + +@KubernetesDependent +public class IndexDiscriminatorTestDRConfigMap + extends CRUDNoGCKubernetesDependentResource { + + public static final String DATA_KEY = "key"; + private final String suffix; + + public IndexDiscriminatorTestDRConfigMap(String value) { + super(ConfigMap.class); + this.suffix = value; + } + + @Override + protected ConfigMap desired(IndexDiscriminatorTestCustomResource primary, + Context context) { + Map data = new HashMap<>(); + data.put(DATA_KEY, primary.getSpec().getValue()); + + return new ConfigMapBuilder() + .withNewMetadata() + .withName(primary.getMetadata().getName() + suffix) + .withNamespace(primary.getMetadata().getNamespace()) + .endMetadata() + .withData(data) + .build(); + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestReconciler.java new file mode 100644 index 0000000000..0b0af2a1cc --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestReconciler.java @@ -0,0 +1,120 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.*; +import io.javaoperatorsdk.operator.junit.KubernetesClientAware; +import io.javaoperatorsdk.operator.processing.event.source.EventSource; +import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; +import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; + +@ControllerConfiguration +public class IndexDiscriminatorTestReconciler + implements Reconciler, + Cleaner, + TestExecutionInfoProvider, EventSourceInitializer, + KubernetesClientAware { + + public static final String FIRST_CONFIG_MAP_SUFFIX_1 = "-1"; + public static final String FIRST_CONFIG_MAP_SUFFIX_2 = "-2"; + public static final String CONFIG_MAP_INDEX_1 = "CONFIG_MAP_INDEX1"; + public static final String CONFIG_MAP_INDEX_2 = "CONFIG_MAP_INDEX2"; + + private final AtomicInteger numberOfExecutions = new AtomicInteger(0); + + private final IndexDiscriminatorTestDRConfigMap firstDependentResourceConfigMap; + private final IndexDiscriminatorTestDRConfigMap secondDependentResourceConfigMap; + private KubernetesClient client; + + public IndexDiscriminatorTestReconciler() { + firstDependentResourceConfigMap = + new IndexDiscriminatorTestDRConfigMap(FIRST_CONFIG_MAP_SUFFIX_1); + secondDependentResourceConfigMap = + new IndexDiscriminatorTestDRConfigMap(FIRST_CONFIG_MAP_SUFFIX_2); + } + + @Override + public UpdateControl reconcile( + IndexDiscriminatorTestCustomResource resource, + Context context) { + numberOfExecutions.getAndIncrement(); + firstDependentResourceConfigMap.reconcile(resource, context); + secondDependentResourceConfigMap.reconcile(resource, context); + return UpdateControl.noUpdate(); + } + + public int getNumberOfExecutions() { + return numberOfExecutions.get(); + } + + @Override + public Map prepareEventSources( + EventSourceContext context) { + + InformerEventSource eventSource = + new InformerEventSource<>(InformerConfiguration.from(ConfigMap.class, context) + .build(), context); + + eventSource.addIndexer(CONFIG_MAP_INDEX_1, cm -> { + if (cm.getMetadata().getName().endsWith(FIRST_CONFIG_MAP_SUFFIX_1)) { + return List.of(configMapKey(cm)); + } else { + return Collections.emptyList(); + } + }); + eventSource.addIndexer(CONFIG_MAP_INDEX_2, cm -> { + if (cm.getMetadata().getName().endsWith(FIRST_CONFIG_MAP_SUFFIX_2)) { + return List.of(configMapKey(cm)); + } else { + return Collections.emptyList(); + } + }); + + firstDependentResourceConfigMap.configureWith(eventSource); + secondDependentResourceConfigMap.configureWith(eventSource); + + firstDependentResourceConfigMap + .setResourceDiscriminator( + new IndexDiscriminator(CONFIG_MAP_INDEX_1, FIRST_CONFIG_MAP_SUFFIX_1)); + secondDependentResourceConfigMap + .setResourceDiscriminator( + new IndexDiscriminator(CONFIG_MAP_INDEX_2, FIRST_CONFIG_MAP_SUFFIX_2)); + return EventSourceInitializer.nameEventSources(eventSource); + } + + @Override + public KubernetesClient getKubernetesClient() { + return client; + } + + @Override + public void setKubernetesClient(KubernetesClient kubernetesClient) { + this.client = kubernetesClient; + firstDependentResourceConfigMap.setKubernetesClient(kubernetesClient); + secondDependentResourceConfigMap.setKubernetesClient(kubernetesClient); + } + + public static String configMapKey(ConfigMap configMap) { + return configMap.getMetadata().getName() + "#" + configMap.getMetadata().getNamespace(); + } + + public static String configMapKeyFromPrimary(IndexDiscriminatorTestCustomResource primary, + String nameSuffix) { + return primary.getMetadata().getName() + nameSuffix + "#" + + primary.getMetadata().getNamespace(); + } + + @Override + public DeleteControl cleanup(IndexDiscriminatorTestCustomResource resource, + Context context) { + firstDependentResourceConfigMap.delete(resource, context); + secondDependentResourceConfigMap.delete(resource, context); + return DeleteControl.defaultDelete(); + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestSpec.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestSpec.java new file mode 100644 index 0000000000..fcedd48abe --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestSpec.java @@ -0,0 +1,15 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +public class IndexDiscriminatorTestSpec { + + private String value; + + public String getValue() { + return value; + } + + public IndexDiscriminatorTestSpec setValue(String value) { + this.value = value; + return this; + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestStatus.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestStatus.java new file mode 100644 index 0000000000..d31c86e8de --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestStatus.java @@ -0,0 +1,5 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +public class IndexDiscriminatorTestStatus { + +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceConfigMap.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceConfigMap.java index 4cdc2e457d..1adbfb9f95 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceConfigMap.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceConfigMap.java @@ -31,7 +31,6 @@ protected ConfigMap desired(MultipleDependentResourceCustomResource primary, .withNewMetadata() .withName(primary.getConfigMapName(value)) .withNamespace(primary.getMetadata().getNamespace()) - .withLabels(Map.of(MultipleDependentResourceReconciler.LABEL, String.valueOf(value))) .endMetadata() .withData(data) .build(); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java index 69c1ba0b04..2891129a93 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java @@ -20,7 +20,6 @@ public class MultipleDependentResourceReconciler public static final int FIRST_CONFIG_MAP_ID = 1; public static final int SECOND_CONFIG_MAP_ID = 2; - public static final String LABEL = "multipledependentresource"; private final AtomicInteger numberOfExecutions = new AtomicInteger(0); private final MultipleDependentResourceConfigMap firstDependentResourceConfigMap; @@ -34,7 +33,6 @@ public MultipleDependentResourceReconciler() { firstDependentResourceConfigMap.configureWith( new KubernetesDependentResourceConfig() - .setLabelSelector(getLabelSelector(FIRST_CONFIG_MAP_ID)) .setResourceDiscriminator( new ResourceIDMatcherDiscriminator( p -> new ResourceID(p.getConfigMapName(FIRST_CONFIG_MAP_ID), @@ -42,17 +40,12 @@ public MultipleDependentResourceReconciler() { secondDependentResourceConfigMap.configureWith( new KubernetesDependentResourceConfig() - .setLabelSelector(getLabelSelector(SECOND_CONFIG_MAP_ID)) .setResourceDiscriminator( new ResourceIDMatcherDiscriminator( p -> new ResourceID(p.getConfigMapName(SECOND_CONFIG_MAP_ID), p.getMetadata().getNamespace())))); } - private String getLabelSelector(int resourceId) { - return LABEL + "=" + resourceId; - } - @Override public UpdateControl reconcile( MultipleDependentResourceCustomResource resource, From fed11e80ffe29e9010af54001f5f5b90bba02a59 Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 29 Jul 2022 14:13:03 +0200 Subject: [PATCH 09/26] IT fix --- .../KubernetesDependentResource.java | 17 +++++---- .../MultipleDependentResourceReconciler.java | 36 ++++++++++--------- 2 files changed, 27 insertions(+), 26 deletions(-) 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 5c8e7f35f5..d9eae04da8 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 @@ -67,15 +67,14 @@ private void configureWith(String labelSelector, Set namespaces, namespaces = context.getControllerConfiguration().getNamespaces(); } - if (eventSource() == null) { - var ic = InformerConfiguration.from(resourceType()) - .withLabelSelector(labelSelector) - .withSecondaryToPrimaryMapper(getSecondaryToPrimaryMapper()) - .withNamespaces(namespaces, inheritNamespacesOnChange) - .build(); - - configureWith(new InformerEventSource<>(ic, context)); - } + var ic = InformerConfiguration.from(resourceType()) + .withLabelSelector(labelSelector) + .withSecondaryToPrimaryMapper(getSecondaryToPrimaryMapper()) + .withNamespaces(namespaces, inheritNamespacesOnChange) + .build(); + + configureWith(new InformerEventSource<>(ic, context)); + } @SuppressWarnings("unchecked") diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java index 2891129a93..49f5ee64c1 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/multipledependentresource/MultipleDependentResourceReconciler.java @@ -5,11 +5,12 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.*; import io.javaoperatorsdk.operator.junit.KubernetesClientAware; -import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; +import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider; @ControllerConfiguration @@ -31,19 +32,16 @@ public MultipleDependentResourceReconciler() { secondDependentResourceConfigMap = new MultipleDependentResourceConfigMap(SECOND_CONFIG_MAP_ID); - firstDependentResourceConfigMap.configureWith( - new KubernetesDependentResourceConfig() - .setResourceDiscriminator( - new ResourceIDMatcherDiscriminator( - p -> new ResourceID(p.getConfigMapName(FIRST_CONFIG_MAP_ID), - p.getMetadata().getNamespace())))); - - secondDependentResourceConfigMap.configureWith( - new KubernetesDependentResourceConfig() - .setResourceDiscriminator( - new ResourceIDMatcherDiscriminator( - p -> new ResourceID(p.getConfigMapName(SECOND_CONFIG_MAP_ID), - p.getMetadata().getNamespace())))); + firstDependentResourceConfigMap + .setResourceDiscriminator( + new ResourceIDMatcherDiscriminator<>( + p -> new ResourceID(p.getConfigMapName(FIRST_CONFIG_MAP_ID), + p.getMetadata().getNamespace()))); + secondDependentResourceConfigMap + .setResourceDiscriminator( + new ResourceIDMatcherDiscriminator<>( + p -> new ResourceID(p.getConfigMapName(SECOND_CONFIG_MAP_ID), + p.getMetadata().getNamespace()))); } @Override @@ -64,9 +62,13 @@ public int getNumberOfExecutions() { @Override public Map prepareEventSources( EventSourceContext context) { - return EventSourceInitializer.nameEventSources( - firstDependentResourceConfigMap.initEventSource(context), - secondDependentResourceConfigMap.initEventSource(context)); + InformerEventSource eventSource = + new InformerEventSource<>(InformerConfiguration.from(ConfigMap.class, context) + .build(), context); + firstDependentResourceConfigMap.configureWith(eventSource); + secondDependentResourceConfigMap.configureWith(eventSource); + + return EventSourceInitializer.nameEventSources(eventSource); } @Override From 6b392e81965d6e6dce26396b504b0ec73f85dc30 Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 29 Jul 2022 16:03:01 +0200 Subject: [PATCH 10/26] wip --- .../operator/api/reconciler/ResourceDiscriminator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java index 0505fd0b57..97130a27d5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -6,6 +6,7 @@ import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; // todo is discriminator a good name? it not just discriminates but also reads from cache +// todo discuss a List version of this (for reconciler but also for batch processing?) public interface ResourceDiscriminator { Optional distinguish(Class resource, P primary, Context

context, From 364e73dd7a370b6717b56bb79da7354de3193ecd Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 26 Aug 2022 10:15:34 +0200 Subject: [PATCH 11/26] fixes from rebase from next --- .../config/AnnotationControllerConfiguration.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index 59dc80869a..2f1e6149df 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -24,6 +24,7 @@ import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig; +import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition; import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters; @@ -311,8 +312,8 @@ private Object createKubernetesResourceConfig(Class createFilter(kubeDependent.genericFilter(), GenericFilter.class, context) .orElse(null); - resourceDiscriminator = instantiateIfNotVoid(kubeDependent.resourceDiscriminator(), - VoidResourceDiscriminator.class); + resourceDiscriminator = + instantiateDiscriminatorIfNotVoid(kubeDependent.resourceDiscriminator()); } config = @@ -323,6 +324,15 @@ private Object createKubernetesResourceConfig(Class return config; } + @SuppressWarnings({"unchecked"}) + private ResourceDiscriminator instantiateDiscriminatorIfNotVoid( + Class discriminator) { + if (discriminator != VoidResourceDiscriminator.class) { + return instantiateAndConfigureIfNeeded(discriminator, ResourceDiscriminator.class); + } + return null; + } + public static T valueOrDefault( ControllerConfiguration controllerConfiguration, Function mapper, From 342ab862112bb8d8f18dc6ca972528866c0921f6 Mon Sep 17 00:00:00 2001 From: csviri Date: Mon, 5 Sep 2022 15:04:49 +0200 Subject: [PATCH 12/26] fix after rebase --- .../AnnotationControllerConfiguration.java | 8 ++-- .../workflow/WorkflowCleanupExecutor.java | 5 +- .../workflow/WorkflowReconcileExecutor.java | 12 +++-- .../workflow/WorkflowCleanupExecutorTest.java | 11 +++-- .../WorkflowReconcileExecutorTest.java | 46 ++++++++++--------- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index 2f1e6149df..1475cf58bc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -45,13 +45,14 @@ public class AnnotationControllerConfiguration

private static final String KUBE_DEPENDENT_NAME = KubernetesDependent.class.getSimpleName(); protected final Reconciler

reconciler; - private final ControllerConfiguration annotation; + private final io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation; private List specs; private Class

resourceClass; public AnnotationControllerConfiguration(Reconciler

reconciler) { this.reconciler = reconciler; - this.annotation = reconciler.getClass().getAnnotation(ControllerConfiguration.class); + this.annotation = reconciler.getClass() + .getAnnotation(io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class); if (annotation == null) { throw new OperatorException( "Missing mandatory @" + ControllerConfiguration.class.getSimpleName() + @@ -328,7 +329,8 @@ private Object createKubernetesResourceConfig(Class private ResourceDiscriminator instantiateDiscriminatorIfNotVoid( Class discriminator) { if (discriminator != VoidResourceDiscriminator.class) { - return instantiateAndConfigureIfNeeded(discriminator, ResourceDiscriminator.class); + return instantiateAndConfigureIfNeeded(discriminator, ResourceDiscriminator.class, + CONTROLLER_CONFIG_ANNOTATION); } return null; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java index 98c6789869..a3c6319511 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java @@ -106,7 +106,10 @@ public void run() { } boolean deletePostConditionMet = deletePostCondition.map(c -> c.isMet(primary, - dependentResourceNode.getDependentResource().getSecondaryResource(primary) + // todo pass also discriminator + context + .getSecondaryResource( + dependentResourceNode.getDependentResource().resourceType()) .orElse(null), context)).orElse(true); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java index 14028cb980..6b2f7fb82b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java @@ -86,7 +86,9 @@ private synchronized void handleReconcile(DependentResourceNode depend boolean reconcileConditionMet = dependentResourceNode.getReconcilePrecondition() .map(rc -> rc.isMet(primary, - dependentResourceNode.getDependentResource().getSecondaryResource(primary).orElse(null), + context + .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) + .orElse(null), context)) .orElse(true); @@ -169,7 +171,9 @@ public void run() { reconciled.add(dependentResourceNode); boolean ready = dependentResourceNode.getReadyPostcondition() .map(rc -> rc.isMet(primary, - dependentResourceNode.getDependentResource().getSecondaryResource(primary) + context + .getSecondaryResource( + dependentResourceNode.getDependentResource().resourceType()) .orElse(null), context)) .orElse(true); @@ -210,8 +214,8 @@ public void run() { } boolean deletePostConditionMet = deletePostCondition.map(c -> c.isMet(primary, - dependentResourceNode.getDependentResource().getSecondaryResource(primary) - .orElse(null), + context.getSecondaryResource( + dependentResourceNode.getDependentResource().resourceType()).orElse(null), context)).orElse(true); if (deletePostConditionMet) { alreadyVisited.add(dependentResourceNode); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java index 7c1c5d6ff6..56bd876687 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java @@ -4,17 +4,20 @@ import org.junit.jupiter.api.Test; import io.javaoperatorsdk.operator.AggregatedOperatorException; +import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.processing.dependent.workflow.builder.WorkflowBuilder; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; import static io.javaoperatorsdk.operator.processing.dependent.workflow.ExecutionAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; class WorkflowCleanupExecutorTest extends AbstractWorkflowExecutorTest { protected TestDeleterDependent dd1 = new TestDeleterDependent("DR_DELETER_1"); protected TestDeleterDependent dd2 = new TestDeleterDependent("DR_DELETER_2"); protected TestDeleterDependent dd3 = new TestDeleterDependent("DR_DELETER_3"); + Context mockContext = mock(Context.class); @Test void cleanUpDiamondWorkflow() { @@ -45,7 +48,7 @@ void dontDeleteIfDependentErrored() { .withThrowExceptionFurther(false) .build(); - var res = workflow.cleanup(new TestCustomResource(), null); + var res = workflow.cleanup(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -64,7 +67,7 @@ void cleanupConditionTrivialCase() { .addDependentResource(dd2).dependsOn(dd1).withDeletePostcondition(noMetDeletePostCondition) .build(); - var res = workflow.cleanup(new TestCustomResource(), null); + var res = workflow.cleanup(new TestCustomResource(), mockContext); assertThat(executionHistory).deleted(dd2).notReconciled(dd1); Assertions.assertThat(res.getDeleteCalledOnDependents()).containsExactlyInAnyOrder(dd2); @@ -79,7 +82,7 @@ void cleanupConditionMet() { .addDependentResource(dd2).dependsOn(dd1).withDeletePostcondition(metDeletePostCondition) .build(); - var res = workflow.cleanup(new TestCustomResource(), null); + var res = workflow.cleanup(new TestCustomResource(), mockContext); assertThat(executionHistory).deleted(dd2, dd1); @@ -99,7 +102,7 @@ void cleanupConditionDiamondWorkflow() { .addDependentResource(dd4).dependsOn(dd2, dd3) .build(); - var res = workflow.cleanup(new TestCustomResource(), null); + var res = workflow.cleanup(new TestCustomResource(), mockContext); assertThat(executionHistory) .reconciledInOrder(dd4, dd2) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java index fa9d757b67..873cf66cb6 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java @@ -4,11 +4,13 @@ import org.junit.jupiter.api.Test; import io.javaoperatorsdk.operator.AggregatedOperatorException; +import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.processing.dependent.workflow.builder.WorkflowBuilder; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; import static io.javaoperatorsdk.operator.processing.dependent.workflow.ExecutionAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; @SuppressWarnings("rawtypes") class WorkflowReconcileExecutorTest extends AbstractWorkflowExecutorTest { @@ -21,6 +23,8 @@ class WorkflowReconcileExecutorTest extends AbstractWorkflowExecutorTest { private final Condition notMetReadyCondition = (primary, secondary, context) -> false; + Context mockContext = mock(Context.class); + @Test void reconcileTopLevelResources() { var workflow = new WorkflowBuilder() @@ -28,7 +32,7 @@ void reconcileTopLevelResources() { .addDependentResource(dr2) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).reconciled(dr1, dr2); Assertions.assertThat(res.getErroredDependents()).isEmpty(); @@ -42,7 +46,7 @@ void reconciliationWithSimpleDependsOn() { .addDependentResource(dr2).dependsOn(dr1) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); assertThat(executionHistory).reconciledInOrder(dr1, dr2); @@ -61,7 +65,7 @@ void reconciliationWithTwoTheDependsOns() { .addDependentResource(dr3).dependsOn(dr1) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); assertThat(executionHistory) @@ -83,7 +87,7 @@ void diamondShareWorkflowReconcile() { .addDependentResource(dr4).dependsOn(dr3).dependsOn(dr2) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); assertThat(executionHistory) @@ -103,7 +107,7 @@ void exceptionHandlingSimpleCases() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -123,7 +127,7 @@ void dependentsOnErroredResourceNotReconciled() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -145,7 +149,7 @@ void oneBranchErrorsOtherCompletes() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -164,7 +168,7 @@ void onlyOneDependsOnErroredResourceNotReconciled() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -182,7 +186,7 @@ void simpleReconcileCondition() { .addDependentResource(drDeleter).withReconcilePrecondition(not_met_reconcile_condition) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).notReconciled(dr1).reconciled(dr2).deleted(drDeleter); Assertions.assertThat(res.getErroredDependents()).isEmpty(); @@ -200,7 +204,7 @@ void triangleOnceConditionNotMet() { .dependsOn(dr1) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).reconciledInOrder(dr1, dr2).deleted(drDeleter); Assertions.assertThat(res.getErroredDependents()).isEmpty(); @@ -222,7 +226,7 @@ void reconcileConditionTransitiveDelete() { .withReconcilePrecondition(met_reconcile_condition) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); assertThat(executionHistory).notReconciled(dr2); @@ -246,7 +250,7 @@ void reconcileConditionAlsoErrorDependsOn() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThrows(AggregatedOperatorException.class, res::throwAggregateExceptionIfErrorsPresent); @@ -267,7 +271,7 @@ void oneDependsOnConditionNotMet() { .addDependentResource(drDeleter).dependsOn(dr1, dr2) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); @@ -287,7 +291,7 @@ void deletedIfReconcileConditionNotMet() { .addDependentResource(drDeleter2).dependsOn(dr1, drDeleter) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory) .reconciledInOrder(dr1, drDeleter2, drDeleter) @@ -313,7 +317,7 @@ void deleteDoneInReverseOrder() { .addDependentResource(drDeleter4).dependsOn(drDeleter3) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory) .reconciledInOrder(dr1, drDeleter4, drDeleter3, drDeleter) @@ -339,7 +343,7 @@ void diamondDeleteWithPostConditionInMiddle() { .addDependentResource(drDeleter4).dependsOn(drDeleter3, drDeleter2) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).notReconciled(drDeleter) .reconciledInOrder(drDeleter4, drDeleter2) @@ -363,7 +367,7 @@ void diamondDeleteErrorInMiddle() { .withThrowExceptionFurther(false) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory) .notReconciled(drDeleter, drError) @@ -381,7 +385,7 @@ void readyConditionTrivialCase() { .addDependentResource(dr2).dependsOn(dr1) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).reconciledInOrder(dr1, dr2); @@ -397,7 +401,7 @@ void readyConditionNotMetTrivialCase() { .addDependentResource(dr2).dependsOn(dr1) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).reconciled(dr1).notReconciled(dr2); @@ -417,7 +421,7 @@ void readyConditionNotMetInOneParent() { .addDependentResource(dr3).dependsOn(dr1, dr2) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); assertThat(executionHistory).reconciled(dr1, dr2).notReconciled(dr3); Assertions.assertThat(res.getErroredDependents()).isEmpty(); @@ -437,7 +441,7 @@ void diamondShareWithReadyCondition() { .addDependentResource(dr4).dependsOn(dr2, dr3) .build(); - var res = workflow.reconcile(new TestCustomResource(), null); + var res = workflow.reconcile(new TestCustomResource(), mockContext); Assertions.assertThat(res.getErroredDependents()).isEmpty(); assertThat(executionHistory).reconciledInOrder(dr1, dr2) From 9a16aa16fbb8a1129b8584839d346e72b9c58669 Mon Sep 17 00:00:00 2001 From: csviri Date: Tue, 6 Sep 2022 16:46:08 +0200 Subject: [PATCH 13/26] event source provider to context --- .../javaoperatorsdk/operator/api/reconciler/Context.java | 3 +++ .../operator/api/reconciler/DefaultContext.java | 9 +++++++-- .../operator/api/reconciler/ResourceDiscriminator.java | 4 +--- .../api/reconciler/ResourceIDMatcherDiscriminator.java | 4 +--- .../api/reconciler/VoidResourceDiscriminator.java | 4 +--- .../sample/indexdiscriminator/IndexDiscriminator.java | 7 +++---- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index a26e7c46fb..2e4fb98e6f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; public interface Context

{ @@ -26,4 +27,6 @@ Optional getSecondaryResource(Class expectedType, ControllerConfiguration

getControllerConfiguration(); ManagedDependentResourceContext managedDependentResourceContext(); + + EventSourceRetriever

eventSourceRetriever(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index 0d5bc22018..cb7f4ae63b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -9,6 +9,7 @@ import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext; import io.javaoperatorsdk.operator.processing.Controller; +import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; public class DefaultContext

implements Context

{ @@ -50,8 +51,7 @@ public Optional getSecondaryResource(Class expectedType, String eventS @Override public Optional getSecondaryResource(Class expectedType, ResourceDiscriminator discriminator) { - return discriminator.distinguish(expectedType, primaryResource, this, - controller.getEventSourceManager()); + return discriminator.distinguish(expectedType, primaryResource, this); } @Override @@ -64,6 +64,11 @@ public ManagedDependentResourceContext managedDependentResourceContext() { return defaultManagedDependentResourceContext; } + @Override + public EventSourceRetriever

eventSourceRetriever() { + return controller.getEventSourceManager(); + } + public DefaultContext

setRetryInfo(RetryInfo retryInfo) { this.retryInfo = retryInfo; return this; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java index 97130a27d5..5af8239901 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -3,13 +3,11 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; // todo is discriminator a good name? it not just discriminates but also reads from cache // todo discuss a List version of this (for reconciler but also for batch processing?) public interface ResourceDiscriminator { - Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceRetriever); + Optional distinguish(Class resource, P primary, Context

context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java index 3df1956bf9..ef0852c900 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java @@ -4,7 +4,6 @@ import java.util.function.Function; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.ResourceID; public class ResourceIDMatcherDiscriminator @@ -17,8 +16,7 @@ public ResourceIDMatcherDiscriminator(Function mapper) { } @Override - public Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceRetriever) { + public Optional distinguish(Class resource, P primary, Context

context) { var resourceID = mapper.apply(primary); return context.getSecondaryResources(resource).stream() .filter(r -> r.getMetadata().getName() diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java index a02c0c6a95..0a5fd1f965 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java @@ -3,14 +3,12 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; public class VoidResourceDiscriminator implements ResourceDiscriminator { @Override - public Optional distinguish(Class resource, P primary, Context

context, - EventSourceRetriever

eventSourceRetriever) { + public Optional distinguish(Class resource, P primary, Context

context) { throw new UnsupportedOperationException(); } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java index 6cf72519a1..eb6e193479 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java @@ -5,7 +5,6 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; -import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler.configMapKeyFromPrimary; @@ -24,11 +23,11 @@ public IndexDiscriminator(String indexName, String nameSuffix) { @Override public Optional distinguish(Class resource, IndexDiscriminatorTestCustomResource primary, - Context context, - EventSourceRetriever eventSourceRetriever) { + Context context) { InformerEventSource eventSource = - (InformerEventSource) eventSourceRetriever + (InformerEventSource) context + .eventSourceRetriever() .getResourceEventSourceFor(ConfigMap.class); var resources = eventSource.byIndex(indexName, configMapKeyFromPrimary(primary, nameSuffix)); if (resources.isEmpty()) { From c7b2d2e235466bac9b21baddad82350c44ab5d08 Mon Sep 17 00:00:00 2001 From: csviri Date: Fri, 16 Sep 2022 09:48:32 +0200 Subject: [PATCH 14/26] todo fixes --- .../api/reconciler/ResourceDiscriminator.java | 2 -- .../dependent/AbstractDependentResource.java | 13 +++----- .../workflow/WorkflowCleanupExecutor.java | 33 ++++++++++++++----- .../workflow/WorkflowReconcileExecutor.java | 26 ++++++++++++--- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java index 5af8239901..072e7d8078 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceDiscriminator.java @@ -4,8 +4,6 @@ import io.fabric8.kubernetes.api.model.HasMetadata; -// todo is discriminator a good name? it not just discriminates but also reads from cache -// todo discuss a List version of this (for reconciler but also for batch processing?) public interface ResourceDiscriminator { Optional distinguish(Class resource, P primary, Context

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 5ecd52cc35..ec553864e6 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 @@ -24,7 +24,6 @@ public abstract class AbstractDependentResource protected Creator creator; protected Updater updater; - // todo discuss, rather implement this as interface? private ResourceDiscriminator resourceDiscriminator; @SuppressWarnings("unchecked") @@ -134,14 +133,12 @@ protected R desired(P primary, Context

context) { "desired method must be implemented if this DependentResource can be created and/or updated"); } - // todo review & refactor configuration to cover all cases - public ResourceDiscriminator getResourceDiscriminator() { - return resourceDiscriminator; - } - - public AbstractDependentResource setResourceDiscriminator( + public void setResourceDiscriminator( ResourceDiscriminator resourceDiscriminator) { this.resourceDiscriminator = resourceDiscriminator; - return this; + } + + public ResourceDiscriminator getResourceDiscriminator() { + return resourceDiscriminator; } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java index a3c6319511..5d4f46b9f6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java @@ -13,8 +13,10 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected; +import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; @SuppressWarnings("rawtypes") public class WorkflowCleanupExecutor

{ @@ -105,14 +107,10 @@ public void run() { deleteCalled.add(dependentResourceNode); } boolean deletePostConditionMet = - deletePostCondition.map(c -> c.isMet(primary, - // todo pass also discriminator - context - .getSecondaryResource( - dependentResourceNode.getDependentResource().resourceType()) - .orElse(null), - context)).orElse(true); - + deletePostCondition + .map(c -> c.isMet(primary, getSecondaryResource(dependentResourceNode), + context)) + .orElse(true); if (deletePostConditionMet) { alreadyVisited.add(dependentResourceNode); handleDependentCleaned(dependentResourceNode); @@ -130,6 +128,25 @@ public void run() { } } + @SuppressWarnings("unchecked") + private R getSecondaryResource(DependentResourceNode dependentResourceNode) { + if (dependentResourceNode.getDependentResource() instanceof AbstractDependentResource && + ((AbstractDependentResource) dependentResourceNode.getDependentResource()) + .getResourceDiscriminator() != null) { + ResourceDiscriminator discriminator = + ((AbstractDependentResource) dependentResourceNode.getDependentResource()) + .getResourceDiscriminator(); + return context + .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType(), + discriminator) + .orElse(null); + } else { + return context + .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) + .orElse(null); + } + } + private synchronized void handleDependentCleaned( DependentResourceNode dependentResourceNode) { var dependOns = dependentResourceNode.getDependsOn(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java index 6b2f7fb82b..735604d4a9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java @@ -13,10 +13,12 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; +import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; import io.javaoperatorsdk.operator.processing.event.ResourceID; @SuppressWarnings({"rawtypes", "unchecked"}) @@ -85,10 +87,7 @@ private synchronized void handleReconcile(DependentResourceNode depend } boolean reconcileConditionMet = dependentResourceNode.getReconcilePrecondition() - .map(rc -> rc.isMet(primary, - context - .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) - .orElse(null), + .map(rc -> rc.isMet(primary, getSecondaryResource(dependentResourceNode), context)) .orElse(true); @@ -102,6 +101,25 @@ private synchronized void handleReconcile(DependentResourceNode depend } } + @SuppressWarnings("unchecked") + private R getSecondaryResource(DependentResourceNode dependentResourceNode) { + if (dependentResourceNode.getDependentResource() instanceof AbstractDependentResource && + ((AbstractDependentResource) dependentResourceNode.getDependentResource()) + .getResourceDiscriminator() != null) { + ResourceDiscriminator discriminator = + ((AbstractDependentResource) dependentResourceNode.getDependentResource()) + .getResourceDiscriminator(); + return context + .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType(), + discriminator) + .orElse(null); + } else { + return context + .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) + .orElse(null); + } + } + private synchronized void handleDelete(DependentResourceNode dependentResourceNode) { log.debug("Submitting for delete: {}", dependentResourceNode); From fc01f943e4b07dc1915a9cc8d06f54f162070fad Mon Sep 17 00:00:00 2001 From: csviri Date: Tue, 27 Sep 2022 09:22:15 +0200 Subject: [PATCH 15/26] remove void discriminator --- .../config/AnnotationControllerConfiguration.java | 2 +- .../api/reconciler/VoidResourceDiscriminator.java | 14 -------------- .../dependent/kubernetes/KubernetesDependent.java | 3 +-- 3 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index 1475cf58bc..db3e8de3f0 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -328,7 +328,7 @@ private Object createKubernetesResourceConfig(Class @SuppressWarnings({"unchecked"}) private ResourceDiscriminator instantiateDiscriminatorIfNotVoid( Class discriminator) { - if (discriminator != VoidResourceDiscriminator.class) { + if (discriminator != ResourceDiscriminator.class) { return instantiateAndConfigureIfNeeded(discriminator, ResourceDiscriminator.class, CONTROLLER_CONFIG_ANNOTATION); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java deleted file mode 100644 index 0a5fd1f965..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/VoidResourceDiscriminator.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.javaoperatorsdk.operator.api.reconciler; - -import java.util.Optional; - -import io.fabric8.kubernetes.api.model.HasMetadata; - -public class VoidResourceDiscriminator - implements ResourceDiscriminator { - - @Override - public Optional distinguish(Class resource, P primary, Context

context) { - throw new UnsupportedOperationException(); - } -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java index 6453a1b061..603f4ae62e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java @@ -7,7 +7,6 @@ import io.javaoperatorsdk.operator.api.reconciler.Constants; import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; -import io.javaoperatorsdk.operator.api.reconciler.VoidResourceDiscriminator; import io.javaoperatorsdk.operator.processing.event.source.filter.*; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; @@ -72,5 +71,5 @@ */ Class genericFilter() default GenericFilter.class; - Class resourceDiscriminator() default VoidResourceDiscriminator.class; + Class resourceDiscriminator() default ResourceDiscriminator.class; } From 9aa1890340f7b370fcea559a530719f9a7e47642 Mon Sep 17 00:00:00 2001 From: csviri Date: Tue, 27 Sep 2022 09:46:31 +0200 Subject: [PATCH 16/26] rebase on next --- .../processing/dependent/workflow/WorkflowReconcileExecutor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java index 735604d4a9..46c47c01ab 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java @@ -187,6 +187,7 @@ public void run() { ReconcileResult reconcileResult = dependentResource.reconcile(primary, context); reconcileResults.put(dependentResource, reconcileResult); reconciled.add(dependentResourceNode); + boolean ready = dependentResourceNode.getReadyPostcondition() .map(rc -> rc.isMet(primary, context From e355a1e803a68e312c47552991e95b37226f6f6b Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 16:36:18 +0200 Subject: [PATCH 17/26] refactor: clean-up --- .../api/config/AnnotationControllerConfiguration.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index db3e8de3f0..7f7ab000a8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -45,18 +45,16 @@ public class AnnotationControllerConfiguration

private static final String KUBE_DEPENDENT_NAME = KubernetesDependent.class.getSimpleName(); protected final Reconciler

reconciler; - private final io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation; + private final ControllerConfiguration annotation; private List specs; private Class

resourceClass; public AnnotationControllerConfiguration(Reconciler

reconciler) { this.reconciler = reconciler; - this.annotation = reconciler.getClass() - .getAnnotation(io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class); + this.annotation = reconciler.getClass().getAnnotation(ControllerConfiguration.class); if (annotation == null) { - throw new OperatorException( - "Missing mandatory @" + ControllerConfiguration.class.getSimpleName() + - " annotation for reconciler: " + reconciler); + throw new OperatorException("Missing mandatory @" + CONTROLLER_CONFIG_ANNOTATION + + " annotation for reconciler: " + reconciler); } } @@ -298,7 +296,6 @@ private Object createKubernetesResourceConfig(Class final var fromAnnotation = kubeDependent.labelSelector(); labelSelector = Constants.NO_VALUE_SET.equals(fromAnnotation) ? null : fromAnnotation; - final var context = KUBE_DEPENDENT_NAME + " annotation on " + dependentType.getName() + " DependentResource"; onAddFilter = createFilter(kubeDependent.onAddFilter(), OnAddFilter.class, context) From 98f0378304bde4087eca74ad1b1df1db8a960884 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 16:36:32 +0200 Subject: [PATCH 18/26] fix: wrong reference --- .../operator/api/reconciler/dependent/DependentResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 3bd9bf8061..15e78a4855 100644 --- 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 @@ -21,9 +21,9 @@ public interface DependentResource { ReconcileResult reconcile(P primary, Context

context); /** - * Retrieves the resource type associated with this ResourceOwner + * Retrieves the resource type associated with this DependentResource * - * @return the resource type associated with this ResourceOwner + * @return the resource type associated with this DependentResource */ Class resourceType(); From 18e7ce5501065de46907e161f0cd155a62723175 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 17:04:45 +0200 Subject: [PATCH 19/26] refactor: extract more generic instantiateIfNotDefault method --- .../AnnotationControllerConfiguration.java | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index 7f7ab000a8..755ffe58f6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -245,9 +245,9 @@ public List getDependentResources() { final var context = "DependentResource of type '" + dependentType.getName() + "'"; spec = new DependentResourceSpec(dependentType, config, name, Set.of(dependent.dependsOn()), - instantiateConditionIfNotDefault(dependent.readyPostcondition(), context), - instantiateConditionIfNotDefault(dependent.reconcilePrecondition(), context), - instantiateConditionIfNotDefault(dependent.deletePostcondition(), context)); + instantiateIfNotDefault(dependent.readyPostcondition(), Condition.class, context), + instantiateIfNotDefault(dependent.reconcilePrecondition(), Condition.class, context), + instantiateIfNotDefault(dependent.deletePostcondition(), Condition.class, context)); specsMap.put(name, spec); } @@ -256,10 +256,10 @@ public List getDependentResources() { return specs; } - protected Condition instantiateConditionIfNotDefault(Class condition, + protected T instantiateIfNotDefault(Class toInstantiate, Class defaultClass, String context) { - if (condition != Condition.class) { - return instantiateAndConfigureIfNeeded(condition, Condition.class, context); + if (!defaultClass.equals(toInstantiate)) { + return instantiateAndConfigureIfNeeded(toInstantiate, defaultClass, context); } return null; } @@ -311,7 +311,7 @@ private Object createKubernetesResourceConfig(Class .orElse(null); resourceDiscriminator = - instantiateDiscriminatorIfNotVoid(kubeDependent.resourceDiscriminator()); + instantiateIfNotDefault(kubeDependent.resourceDiscriminator(), ResourceDiscriminator.class, context); } config = @@ -321,17 +321,7 @@ private Object createKubernetesResourceConfig(Class return config; } - - @SuppressWarnings({"unchecked"}) - private ResourceDiscriminator instantiateDiscriminatorIfNotVoid( - Class discriminator) { - if (discriminator != ResourceDiscriminator.class) { - return instantiateAndConfigureIfNeeded(discriminator, ResourceDiscriminator.class, - CONTROLLER_CONFIG_ANNOTATION); - } - return null; - } - + public static T valueOrDefault( ControllerConfiguration controllerConfiguration, Function mapper, From 4f9de03b24b44ca2ff5cfe73e4780f2bdbdaf9d0 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Mon, 29 Aug 2022 18:27:15 +0200 Subject: [PATCH 20/26] feat: add isSameResource method --- .../operator/processing/event/ResourceID.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java index 7baeab6a4b..b6c2d976e3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java @@ -54,6 +54,12 @@ public boolean equals(Object o) { that.namespace); } + public boolean isSameResource(HasMetadata hasMetadata) { + final var metadata = hasMetadata.getMetadata(); + return getName().equals(metadata.getName()) && + getNamespace().map(ns -> ns.equals(metadata.getNamespace())).orElse(true); + } + @Override public int hashCode() { return Objects.hash(name, namespace); From f5079bf92e3207caf2320d05ed5f0b6443d300d5 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 20:59:50 +0200 Subject: [PATCH 21/26] refactor: use isSameResource method --- .../api/config/AnnotationControllerConfiguration.java | 5 +++-- .../api/reconciler/ResourceIDMatcherDiscriminator.java | 5 +---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index 755ffe58f6..dbd09a32cc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -311,7 +311,8 @@ private Object createKubernetesResourceConfig(Class .orElse(null); resourceDiscriminator = - instantiateIfNotDefault(kubeDependent.resourceDiscriminator(), ResourceDiscriminator.class, context); + instantiateIfNotDefault(kubeDependent.resourceDiscriminator(), + ResourceDiscriminator.class, context); } config = @@ -321,7 +322,7 @@ private Object createKubernetesResourceConfig(Class return config; } - + public static T valueOrDefault( ControllerConfiguration controllerConfiguration, Function mapper, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java index ef0852c900..f28633252a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java @@ -19,10 +19,7 @@ public ResourceIDMatcherDiscriminator(Function mapper) { public Optional distinguish(Class resource, P primary, Context

context) { var resourceID = mapper.apply(primary); return context.getSecondaryResources(resource).stream() - .filter(r -> r.getMetadata().getName() - .equals(resourceID.getName()) && - resourceID.getNamespace().map(ns -> ns.equals(r.getMetadata().getNamespace())) - .orElse(true)) + .filter(resourceID::isSameResource) .findFirst(); } } From af9d162ef2bc134279934b7fba3db29f6087da16 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 21:16:56 +0200 Subject: [PATCH 22/26] refactor: clean-up --- .../kubernetes/KubernetesDependentResourceConfig.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java index a185071221..e2a2c0f684 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java @@ -28,7 +28,6 @@ public class KubernetesDependentResourceConfig { public KubernetesDependentResourceConfig() {} - @SuppressWarnings("rawtypes") public KubernetesDependentResourceConfig(Set namespaces, String labelSelector, boolean configuredNS, ResourceDiscriminator resourceDiscriminator, OnAddFilter onAddFilter, @@ -81,7 +80,6 @@ public OnUpdateFilter onUpdateFilter() { return onUpdateFilter; } - @SuppressWarnings("rawtypes") public OnDeleteFilter onDeleteFilter() { return onDeleteFilter; } @@ -94,10 +92,4 @@ public GenericFilter genericFilter() { public ResourceDiscriminator getResourceDiscriminator() { return resourceDiscriminator; } - - public

KubernetesDependentResourceConfig setResourceDiscriminator( - ResourceDiscriminator resourceDiscriminator) { - this.resourceDiscriminator = resourceDiscriminator; - return this; - } } From 569bed49bf8ef4a4866a050963859b0eaa91ea79 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 22:21:55 +0200 Subject: [PATCH 23/26] feat: re-introduce getSecondaryResource and simplify --- .../dependent/DependentResource.java | 6 ++++ .../dependent/AbstractDependentResource.java | 10 ++----- .../workflow/DependentResourceNode.java | 5 ++++ .../workflow/WorkflowCleanupExecutor.java | 29 +++---------------- .../workflow/WorkflowReconcileExecutor.java | 23 +-------------- .../processing/event/EventSourceManager.java | 3 +- .../AbstractDependentResourceTest.java | 2 +- 7 files changed, 21 insertions(+), 57 deletions(-) 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 index 15e78a4855..8d31778488 100644 --- 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 @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent; +import java.util.Optional; + import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; @@ -27,6 +29,10 @@ public interface DependentResource { */ Class resourceType(); + default Optional getSecondaryResource(P primary, Context

context) { + return Optional.empty(); + } + /** * Computes a default name for the specified DependentResource class * 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 ec553864e6..1abfb3df4b 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 @@ -32,7 +32,6 @@ public AbstractDependentResource() { updater = updatable ? (Updater) this : null; } - @SuppressWarnings("unchecked") @Override public ReconcileResult reconcile(P primary, Context

context) { Optional maybeActual = getSecondaryResource(primary, context); @@ -68,12 +67,9 @@ public ReconcileResult reconcile(P primary, Context

context) { return ReconcileResult.noOperation(maybeActual.orElse(null)); } - protected Optional getSecondaryResource(P primary, Context

context) { - if (resourceDiscriminator == null) { - return context.getSecondaryResource(resourceType()); - } else { - return context.getSecondaryResource(resourceType(), resourceDiscriminator); - } + public Optional getSecondaryResource(P primary, Context

context) { + return resourceDiscriminator == null ? context.getSecondaryResource(resourceType()) + : resourceDiscriminator.distinguish(resourceType(), primary, context); } private void throwIfNull(R desired, P primary, String descriptor) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DependentResourceNode.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DependentResourceNode.java index e317145916..32cef6c68e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DependentResourceNode.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DependentResourceNode.java @@ -5,6 +5,7 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @SuppressWarnings("rawtypes") @@ -85,4 +86,8 @@ public DependentResourceNode setReadyPostcondition(Condition readyPo public List getParents() { return parents; } + + protected R getSecondaryResource(P primary, Context

context) { + return getDependentResource().getSecondaryResource(primary, context).orElse(null); + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java index 5d4f46b9f6..45541b91d6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutor.java @@ -13,10 +13,8 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected; -import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; @SuppressWarnings("rawtypes") public class WorkflowCleanupExecutor

{ @@ -106,11 +104,10 @@ public void run() { ((Deleter

) dependentResourceNode.getDependentResource()).delete(primary, context); deleteCalled.add(dependentResourceNode); } - boolean deletePostConditionMet = - deletePostCondition - .map(c -> c.isMet(primary, getSecondaryResource(dependentResourceNode), - context)) - .orElse(true); + boolean deletePostConditionMet = deletePostCondition + .map(c -> c.isMet(primary, dependentResourceNode.getSecondaryResource(primary, context), + context)) + .orElse(true); if (deletePostConditionMet) { alreadyVisited.add(dependentResourceNode); handleDependentCleaned(dependentResourceNode); @@ -128,24 +125,6 @@ public void run() { } } - @SuppressWarnings("unchecked") - private R getSecondaryResource(DependentResourceNode dependentResourceNode) { - if (dependentResourceNode.getDependentResource() instanceof AbstractDependentResource && - ((AbstractDependentResource) dependentResourceNode.getDependentResource()) - .getResourceDiscriminator() != null) { - ResourceDiscriminator discriminator = - ((AbstractDependentResource) dependentResourceNode.getDependentResource()) - .getResourceDiscriminator(); - return context - .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType(), - discriminator) - .orElse(null); - } else { - return context - .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) - .orElse(null); - } - } private synchronized void handleDependentCleaned( DependentResourceNode dependentResourceNode) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java index 46c47c01ab..33ecd12f77 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java @@ -13,12 +13,10 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected; import io.javaoperatorsdk.operator.api.reconciler.dependent.ReconcileResult; -import io.javaoperatorsdk.operator.processing.dependent.AbstractDependentResource; import io.javaoperatorsdk.operator.processing.event.ResourceID; @SuppressWarnings({"rawtypes", "unchecked"}) @@ -87,7 +85,7 @@ private synchronized void handleReconcile(DependentResourceNode depend } boolean reconcileConditionMet = dependentResourceNode.getReconcilePrecondition() - .map(rc -> rc.isMet(primary, getSecondaryResource(dependentResourceNode), + .map(rc -> rc.isMet(primary, dependentResourceNode.getSecondaryResource(primary, context), context)) .orElse(true); @@ -101,25 +99,6 @@ private synchronized void handleReconcile(DependentResourceNode depend } } - @SuppressWarnings("unchecked") - private R getSecondaryResource(DependentResourceNode dependentResourceNode) { - if (dependentResourceNode.getDependentResource() instanceof AbstractDependentResource && - ((AbstractDependentResource) dependentResourceNode.getDependentResource()) - .getResourceDiscriminator() != null) { - ResourceDiscriminator discriminator = - ((AbstractDependentResource) dependentResourceNode.getDependentResource()) - .getResourceDiscriminator(); - return context - .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType(), - discriminator) - .orElse(null); - } else { - return context - .getSecondaryResource(dependentResourceNode.getDependentResource().resourceType()) - .orElse(null); - } - } - private synchronized void handleDelete(DependentResourceNode dependentResourceNode) { log.debug("Submitting for delete: {}", dependentResourceNode); 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 6e4305b82a..fc68e6e413 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 @@ -173,8 +173,7 @@ public ControllerResourceEventSource

getControllerResourceEventSource() { } @Override - public ResourceEventSource getResourceEventSourceFor( - Class dependentType) { + public ResourceEventSource getResourceEventSourceFor(Class dependentType) { return getResourceEventSourceFor(dependentType, null); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java index 004cb5d159..b93abd45c0 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResourceTest.java @@ -79,7 +79,7 @@ public Class resourceType() { } @Override - protected Optional getSecondaryResource(TestCustomResource primary, + public Optional getSecondaryResource(TestCustomResource primary, Context context) { return Optional.ofNullable(secondary); } From fa0bfb7f4655ca78b02cc497a606b3f928a3ab19 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 27 Sep 2022 22:50:20 +0200 Subject: [PATCH 24/26] fix: typos and wrong logged information --- .../operator/processing/event/EventProcessor.java | 11 ++++++----- .../processing/event/source/ResourceEventSource.java | 4 ++-- .../source/informer/ManagedInformerEventSource.java | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java index 58bf5ee00a..e0280796b2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java @@ -135,7 +135,8 @@ private void handleMarkedEventForResource(ResourceState state) { private void submitReconciliationExecution(ResourceState state) { try { boolean controllerUnderExecution = isControllerUnderExecution(state); - Optional maybeLatest = cache.get(state.getId()); + final var resourceID = state.getId(); + Optional maybeLatest = cache.get(resourceID); maybeLatest.ifPresent(MDCUtils::addResourceInfo); if (!controllerUnderExecution && maybeLatest.isPresent()) { var rateLimit = state.getRateLimit(); @@ -145,24 +146,24 @@ private void submitReconciliationExecution(ResourceState state) { } var rateLimiterPermission = rateLimiter.isLimited(rateLimit); if (rateLimiterPermission.isPresent()) { - handleRateLimitedSubmission(state.getId(), rateLimiterPermission.get()); + handleRateLimitedSubmission(resourceID, rateLimiterPermission.get()); return; } state.setUnderProcessing(true); final var latest = maybeLatest.get(); ExecutionScope executionScope = new ExecutionScope<>(latest, state.getRetry()); state.unMarkEventReceived(); - metrics.reconcileCustomResource(state.getId(), state.getRetry(), metricsMetadata); + metrics.reconcileCustomResource(resourceID, state.getRetry(), metricsMetadata); log.debug("Executing events for custom resource. Scope: {}", executionScope); executor.execute(new ReconcilerExecutor(executionScope)); } else { log.debug( "Skipping executing controller for resource id: {}. Controller in execution: {}. Latest Resource present: {}", - state, + resourceID, controllerUnderExecution, maybeLatest.isPresent()); if (maybeLatest.isEmpty()) { - log.debug("no custom resource found in cache for ResourceID: {}", state); + log.debug("no custom resource found in cache for resource id: {}", resourceID); } } } finally { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java index d58ea11e48..38b5d7007f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventSource.java @@ -12,9 +12,9 @@ public interface ResourceEventSource extends EventSource { /** - * Retrieves the resource type associated with this ResourceOwner + * Retrieves the resource type associated with this ResourceEventSource * - * @return the resource type associated with this ResourceOwner + * @return the resource type associated with this ResourceEventSource */ Class resourceType(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java index 6ebd63a7eb..cc9af59094 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java @@ -93,10 +93,10 @@ public void handleRecentResourceCreate(ResourceID resourceID, R resource) { public Optional get(ResourceID resourceID) { Optional resource = temporaryResourceCache.getResourceFromCache(resourceID); if (resource.isPresent()) { - log.debug("Resource found in temporal cache for Resource ID: {}", resourceID); + log.debug("Resource found in temporary cache for Resource ID: {}", resourceID); return resource; } else { - log.debug("Resource not found in temporal cache reading it from informer cache," + + log.debug("Resource not found in temporary cache reading it from informer cache," + " for Resource ID: {}", resourceID); return cache.get(resourceID); } From e5a98ff7df1e2120bc3f73103fe0b9be6b836e4f Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Mon, 29 Aug 2022 21:56:25 +0200 Subject: [PATCH 25/26] refactor: remove useless AbstractCachingDependentResource class --- ...actEventSourceHolderDependentResource.java | 9 ++++++++ .../AbstractCachingDependentResource.java | 23 ------------------- .../AbstractPollingDependentResource.java | 6 ++++- .../KubernetesDependentResource.java | 16 +++---------- 4 files changed, 17 insertions(+), 37 deletions(-) delete mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java 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 index 0ceba16826..be0db98393 100644 --- 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 @@ -19,12 +19,16 @@ public abstract class AbstractEventSourceHolderDependentResource { private T eventSource; + private final Class resourceType; private boolean isCacheFillerEventSource; protected OnAddFilter onAddFilter; protected OnUpdateFilter onUpdateFilter; protected OnDeleteFilter onDeleteFilter; protected GenericFilter genericFilter; + protected AbstractEventSourceHolderDependentResource(Class resourceType) { + this.resourceType = resourceType; + } public EventSource initEventSource(EventSourceContext

context) { // some sub-classes (e.g. KubernetesDependentResource) can have their event source created @@ -42,6 +46,11 @@ public EventSource initEventSource(EventSourceContext

context) { return eventSource; } + @Override + public Class resourceType() { + return resourceType; + } + protected abstract T createEventSource(EventSourceContext

context); protected void setEventSource(T 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 deleted file mode 100644 index e7d07a5513..0000000000 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.javaoperatorsdk.operator.processing.dependent.external; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.api.reconciler.Ignore; -import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; -import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; - -@Ignore -public abstract class AbstractCachingDependentResource - extends - AbstractEventSourceHolderDependentResource> { - private final Class resourceType; - - protected AbstractCachingDependentResource(Class resourceType) { - this.resourceType = resourceType; - } - - @Override - public Class resourceType() { - return resourceType; - } - -} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractPollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractPollingDependentResource.java index 6bab6f48cf..2ccba025a7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractPollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractPollingDependentResource.java @@ -2,11 +2,15 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Ignore; +import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource; import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @Ignore public abstract class AbstractPollingDependentResource - extends AbstractCachingDependentResource implements CacheKeyMapper { + extends + AbstractEventSourceHolderDependentResource> + implements CacheKeyMapper { public static final int DEFAULT_POLLING_PERIOD = 5000; private long pollingPeriod; 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 d9eae04da8..c02ea6610a 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 @@ -40,13 +40,12 @@ public abstract class KubernetesDependentResource matcher; private final ResourceUpdatePreProcessor processor; - private final Class resourceType; private final boolean garbageCollected = this instanceof GarbageCollected; private KubernetesDependentResourceConfig kubernetesDependentResourceConfig; @SuppressWarnings("unchecked") public KubernetesDependentResource(Class resourceType) { - this.resourceType = resourceType; + super(resourceType); matcher = this instanceof Matcher ? (Matcher) this : GenericKubernetesResourceMatcher.matcherFor(resourceType, this); @@ -94,7 +93,7 @@ private SecondaryToPrimaryMapper getSecondaryToPrimaryMapper() { /** * Use to share informers between event more resources. * - * @param informerEventSource informer to use* + * @param informerEventSource informer to use */ public void configureWith(InformerEventSource informerEventSource) { setEventSource(informerEventSource); @@ -138,8 +137,7 @@ public Result match(R actualResource, P primary, Context

context) { } public void delete(P primary, Context

context) { - var resource = getSecondaryResource(primary, context); - resource.ifPresent(r -> client.resource(r).delete()); + getSecondaryResource(primary, context).ifPresent(r -> client.resource(r).delete()); } @SuppressWarnings("unchecked") @@ -204,13 +202,6 @@ protected boolean addOwnerReference() { return garbageCollected; } - @Override - public Class resourceType() { - return resourceType; - } - - - @Override public void setKubernetesClient(KubernetesClient kubernetesClient) { this.client = kubernetesClient; @@ -233,5 +224,4 @@ private void prepareEventFiltering(R desired, ResourceID resourceID) { private void cleanupAfterEventFiltering(ResourceID resourceID) { eventSource().cleanupOnCreateOrUpdateEventFiltering(resourceID); } - } From c689843872e5a29556ca173a05c829473c9474ab Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 28 Sep 2022 10:12:26 +0200 Subject: [PATCH 26/26] refactor: use new fabric8 resource access pattern --- .../kubernetes/KubernetesDependentResource.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 c02ea6610a..328a061e6b 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 @@ -7,9 +7,7 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; @@ -124,12 +122,12 @@ protected R handleUpdate(R actual, R desired, P primary, Context

context) { @SuppressWarnings("unused") public R create(R target, P primary, Context

context) { - return prepare(target, primary, "Creating").create(target); + return prepare(target, primary, "Creating").create(); } public R update(R actual, R target, P primary, Context

context) { var updatedActual = processor.replaceSpecOnActual(actual, target, context); - return prepare(target, primary, "Updating").replace(updatedActual); + return prepare(updatedActual, primary, "Updating").replace(); } public Result match(R actualResource, P primary, Context

context) { @@ -141,8 +139,7 @@ public void delete(P primary, Context

context) { } @SuppressWarnings("unchecked") - protected NonNamespaceOperation, Resource> prepare(R desired, - P primary, String actionName) { + protected Resource prepare(R desired, P primary, String actionName) { log.debug("{} target resource with type: {}, with id: {}", actionName, desired.getClass(), @@ -153,7 +150,8 @@ protected NonNamespaceOperation, Resource> prepa addDefaultSecondaryToPrimaryMapperAnnotations(desired, primary); } Class targetClass = (Class) desired.getClass(); - return client.resources(targetClass).inNamespace(desired.getMetadata().getNamespace()); + return client.resources(targetClass).inNamespace(desired.getMetadata().getNamespace()) + .resource(desired); } @Override