From 9bc7a89e6079515e9d85bd735b2cfb46f869baa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 14 Aug 2023 14:17:29 +0200 Subject: [PATCH] discriminator improvements (#2013) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: csviri Signed-off-by: Attila Mészáros --- .../api/reconciler/IndexDiscriminator.java | 50 +++++++++++++++++++ .../ResourceIDMatcherDiscriminator.java | 26 ++++++++-- .../IndexDiscriminator.java | 41 --------------- .../IndexDiscriminatorTestReconciler.java | 4 +- .../TestIndexDiscriminator.java | 14 ++++++ 5 files changed, 89 insertions(+), 46 deletions(-) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexDiscriminator.java delete 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/TestIndexDiscriminator.java diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexDiscriminator.java new file mode 100644 index 0000000000..7a27397b26 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexDiscriminator.java @@ -0,0 +1,50 @@ +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.source.informer.InformerEventSource; + +/** + * Uses a custom index of {@link InformerEventSource} to access the target resource. The index needs + * to be explicitly created when the event source is defined. This approach improves the performance + * to access the resource. + */ +public class IndexDiscriminator + implements ResourceDiscriminator { + + private final String indexName; + private final String eventSourceName; + private final Function keyMapper; + + public IndexDiscriminator(String indexName, Function keyMapper) { + this(indexName, null, keyMapper); + } + + public IndexDiscriminator(String indexName, String eventSourceName, + Function keyMapper) { + this.indexName = indexName; + this.eventSourceName = eventSourceName; + this.keyMapper = keyMapper; + } + + @Override + public Optional distinguish(Class resource, + P primary, + Context

context) { + + InformerEventSource eventSource = + (InformerEventSource) context + .eventSourceRetriever() + .getResourceEventSourceFor(resource, eventSourceName); + var resources = eventSource.byIndex(indexName, keyMapper.apply(primary)); + if (resources.isEmpty()) { + return Optional.empty(); + } else if (resources.size() > 1) { + throw new IllegalStateException("More than one resource found"); + } else { + return Optional.of(resources.get(0)); + } + } +} 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 d23459e271..da773fc210 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 @@ -5,21 +5,41 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.processing.event.ResourceID; +import io.javaoperatorsdk.operator.processing.event.source.Cache; public class ResourceIDMatcherDiscriminator implements ResourceDiscriminator { + + private final String eventSourceName; private final Function mapper; public ResourceIDMatcherDiscriminator(Function mapper) { + this(null, mapper); + } + + public ResourceIDMatcherDiscriminator(String eventSourceName, Function mapper) { + this.eventSourceName = eventSourceName; this.mapper = mapper; } + @SuppressWarnings("unchecked") @Override public Optional distinguish(Class resource, P primary, Context

context) { var resourceID = mapper.apply(primary); - return context.getSecondaryResourcesAsStream(resource) - .filter(resourceID::isSameResource) - .findFirst(); + if (eventSourceName != null) { + return ((Cache) context.eventSourceRetriever().getResourceEventSourceFor(resource, + eventSourceName)) + .get(resourceID); + } else { + var eventSources = context.eventSourceRetriever().getResourceEventSourcesFor(resource); + if (eventSources.size() == 1) { + return ((Cache) eventSources.get(0)).get(resourceID); + } else { + return context.getSecondaryResourcesAsStream(resource) + .filter(resourceID::isSameResource) + .findFirst(); + } + } } } 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 deleted file mode 100644 index eb6e193479..0000000000 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminator.java +++ /dev/null @@ -1,41 +0,0 @@ -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.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) { - - InformerEventSource eventSource = - (InformerEventSource) context - .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/IndexDiscriminatorTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/IndexDiscriminatorTestReconciler.java index 0b0af2a1cc..b988c93491 100644 --- 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 @@ -81,10 +81,10 @@ public Map prepareEventSources( firstDependentResourceConfigMap .setResourceDiscriminator( - new IndexDiscriminator(CONFIG_MAP_INDEX_1, FIRST_CONFIG_MAP_SUFFIX_1)); + new TestIndexDiscriminator(CONFIG_MAP_INDEX_1, FIRST_CONFIG_MAP_SUFFIX_1)); secondDependentResourceConfigMap .setResourceDiscriminator( - new IndexDiscriminator(CONFIG_MAP_INDEX_2, FIRST_CONFIG_MAP_SUFFIX_2)); + new TestIndexDiscriminator(CONFIG_MAP_INDEX_2, FIRST_CONFIG_MAP_SUFFIX_2)); return EventSourceInitializer.nameEventSources(eventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/TestIndexDiscriminator.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/TestIndexDiscriminator.java new file mode 100644 index 0000000000..a56e44ced8 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/indexdiscriminator/TestIndexDiscriminator.java @@ -0,0 +1,14 @@ +package io.javaoperatorsdk.operator.sample.indexdiscriminator; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.javaoperatorsdk.operator.api.reconciler.IndexDiscriminator; + +import static io.javaoperatorsdk.operator.sample.indexdiscriminator.IndexDiscriminatorTestReconciler.configMapKeyFromPrimary; + +public class TestIndexDiscriminator + extends IndexDiscriminator { + + public TestIndexDiscriminator(String indexName, String nameSuffix) { + super(indexName, p -> configMapKeyFromPrimary(p, nameSuffix)); + } +}