From 9b331da07f4f7eba5de277a73c5b1613a231fdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Sat, 18 Oct 2025 16:52:01 +0200 Subject: [PATCH 1/5] improve: ExternalResourceIDProvider extended to be used in CacheKeyMapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../AbstractPollingDependentResource.java | 10 +++---- .../PerResourcePollingDependentResource.java | 8 +++--- .../external/PollingDependentResource.java | 12 ++++---- .../event/source/CacheKeyMapper.java | 20 +++++++++++-- .../ExternalResourceCachingEventSource.java | 19 ++++++------- .../inbound/CachingInboundEventSource.java | 8 +++--- .../PerResourcePollingConfiguration.java | 8 +++--- ...erResourcePollingConfigurationBuilder.java | 16 +++++------ .../PerResourcePollingEventSource.java | 6 ++-- .../source/polling/PollingConfiguration.java | 8 +++--- .../polling/PollingConfigurationBuilder.java | 11 ++++---- .../source/polling/PollingEventSource.java | 6 ++-- ...xternalResourceCachingEventSourceTest.java | 5 ++-- .../event/source/SampleExternalResource.java | 8 +++++- .../CachingInboundEventSourceTest.java | 5 ++-- .../PerResourcePollingEventSourceTest.java | 13 ++++++--- .../polling/PollingEventSourceTest.java | 4 +-- ...ourcePollingEventSourceTestReconciler.java | 28 ++++++++++--------- .../ExternalBulkDependentResource.java | 2 +- .../external/ExternalResource.java | 9 +++++- .../ExternalStateReconciler.java | 9 ++++-- .../ExternalWithStateDependentResource.java | 3 +- ...ulkDependentResourceExternalWithState.java | 2 +- .../AbstractExternalDependentResource.java | 2 +- ...edExternalDependentResourceReconciler.java | 6 ++-- .../dependent/SchemaDependentResource.java | 2 +- 26 files changed, 136 insertions(+), 94 deletions(-) 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 4b255a35d7..22ad401fe7 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 @@ -24,9 +24,9 @@ import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @Ignore -public abstract class AbstractPollingDependentResource - extends AbstractExternalDependentResource> - implements CacheKeyMapper { +public abstract class AbstractPollingDependentResource + extends AbstractExternalDependentResource> + implements CacheKeyMapper { public static final Duration DEFAULT_POLLING_PERIOD = Duration.ofMillis(5000); private Duration pollingPeriod; @@ -52,7 +52,7 @@ public Duration getPollingPeriod() { // for now dependent resources support event sources only with one owned resource. @Override - public String keyFor(R resource) { - return CacheKeyMapper.singleResourceCacheKeyMapper().keyFor(resource); + public ID keyFor(R resource) { + return CacheKeyMapper.externalIdProviderMapper().keyFor(resource); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java index 4df1dcf578..18de989bc1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java @@ -25,8 +25,8 @@ import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; @Ignore -public abstract class PerResourcePollingDependentResource - extends AbstractPollingDependentResource +public abstract class PerResourcePollingDependentResource + extends AbstractPollingDependentResource implements PerResourcePollingEventSource.ResourceFetcher { public PerResourcePollingDependentResource() {} @@ -40,13 +40,13 @@ public PerResourcePollingDependentResource(Class resourceType, Duration polli } @Override - protected ExternalResourceCachingEventSource createEventSource( + protected ExternalResourceCachingEventSource createEventSource( EventSourceContext

context) { return new PerResourcePollingEventSource<>( resourceType(), context, - new PerResourcePollingConfigurationBuilder<>(this, getPollingPeriod()) + new PerResourcePollingConfigurationBuilder(this, getPollingPeriod()) .withCacheKeyMapper(this) .withName(name()) .build()); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java index 6b80edc61a..339f104a4d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java @@ -26,25 +26,25 @@ import io.javaoperatorsdk.operator.processing.event.source.polling.PollingEventSource; @Ignore -public abstract class PollingDependentResource - extends AbstractPollingDependentResource +public abstract class PollingDependentResource + extends AbstractPollingDependentResource implements PollingEventSource.GenericResourceFetcher { - private final CacheKeyMapper cacheKeyMapper; + private final CacheKeyMapper cacheKeyMapper; - public PollingDependentResource(Class resourceType, CacheKeyMapper cacheKeyMapper) { + public PollingDependentResource(Class resourceType, CacheKeyMapper cacheKeyMapper) { super(resourceType); this.cacheKeyMapper = cacheKeyMapper; } public PollingDependentResource( - Class resourceType, Duration pollingPeriod, CacheKeyMapper cacheKeyMapper) { + Class resourceType, Duration pollingPeriod, CacheKeyMapper cacheKeyMapper) { super(resourceType, pollingPeriod); this.cacheKeyMapper = cacheKeyMapper; } @Override - protected ExternalResourceCachingEventSource createEventSource( + protected ExternalResourceCachingEventSource createEventSource( EventSourceContext

context) { return new PollingEventSource<>( resourceType(), diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java index 8038dd1555..6f3b9fd571 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java @@ -15,9 +15,11 @@ */ package io.javaoperatorsdk.operator.processing.event.source; -public interface CacheKeyMapper { +import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; - String keyFor(R resource); +public interface CacheKeyMapper { + + ID keyFor(R resource); /** * Used if a polling event source handles only single secondary resource. See also docs for: @@ -26,7 +28,19 @@ public interface CacheKeyMapper { * @return static id mapper, all resources are mapped for same id. * @param secondary resource type */ - static CacheKeyMapper singleResourceCacheKeyMapper() { + static CacheKeyMapper singleResourceCacheKeyMapper() { return r -> "id"; } + + static CacheKeyMapper externalIdProviderMapper() { + + return r -> { + if (r instanceof ExternalDependentIDProvider externalDependentIDProvider) { + return (ID) externalDependentIDProvider.externalResourceId(); + } else { + throw new IllegalStateException( + "Resource does not implement ExternalDependentIDProvider: " + r.getClass()); + } + }; + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java index 1c4ce45cb9..2a57d9d682 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java @@ -54,23 +54,23 @@ * @param type of polled external secondary resource * @param

primary resource */ -public abstract class ExternalResourceCachingEventSource +public abstract class ExternalResourceCachingEventSource extends AbstractEventSource implements RecentOperationCacheFiller { private static final Logger log = LoggerFactory.getLogger(ExternalResourceCachingEventSource.class); - protected final CacheKeyMapper cacheKeyMapper; + protected final CacheKeyMapper cacheKeyMapper; - protected Map> cache = new ConcurrentHashMap<>(); + protected Map> cache = new ConcurrentHashMap<>(); protected ExternalResourceCachingEventSource( - Class resourceClass, CacheKeyMapper cacheKeyMapper) { + Class resourceClass, CacheKeyMapper cacheKeyMapper) { this(null, resourceClass, cacheKeyMapper); } protected ExternalResourceCachingEventSource( - String name, Class resourceClass, CacheKeyMapper cacheKeyMapper) { + String name, Class resourceClass, CacheKeyMapper cacheKeyMapper) { super(resourceClass, name); this.cacheKeyMapper = cacheKeyMapper; } @@ -91,7 +91,7 @@ protected synchronized void handleDelete(ResourceID primaryID, R resource) { handleDelete(primaryID, Set.of(cacheKeyMapper.keyFor(resource))); } - protected synchronized void handleDelete(ResourceID primaryID, Set resourceIDs) { + protected synchronized void handleDelete(ResourceID primaryID, Set resourceIDs) { if (!isRunning()) { return; } @@ -146,8 +146,7 @@ && acceptedByFiler(cachedResources, newResourcesMap)) { } } - private boolean acceptedByFiler( - Map cachedResourceMap, Map newResourcesMap) { + private boolean acceptedByFiler(Map cachedResourceMap, Map newResourcesMap) { var addedResources = new HashMap<>(newResourcesMap); addedResources.keySet().removeAll(cachedResourceMap.keySet()); @@ -175,7 +174,7 @@ private boolean acceptedByFiler( return true; } - Map possibleUpdatedResources = new HashMap<>(cachedResourceMap); + Map possibleUpdatedResources = new HashMap<>(cachedResourceMap); possibleUpdatedResources.keySet().retainAll(newResourcesMap.keySet()); possibleUpdatedResources = possibleUpdatedResources.entrySet().stream() @@ -248,7 +247,7 @@ public Optional getSecondaryResource(ResourceID primaryID) { } } - public Map> getCache() { + public Map> getCache() { return Collections.unmodifiableMap(cache); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java index 6c9e6ec660..34d8c51d77 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java @@ -26,8 +26,8 @@ import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.source.ResourceEventAware; -public class CachingInboundEventSource - extends ExternalResourceCachingEventSource implements ResourceEventAware

{ +public class CachingInboundEventSource + extends ExternalResourceCachingEventSource implements ResourceEventAware

{ private final ResourceFetcher resourceFetcher; private final Set fetchedForPrimaries = ConcurrentHashMap.newKeySet(); @@ -35,7 +35,7 @@ public class CachingInboundEventSource public CachingInboundEventSource( ResourceFetcher resourceFetcher, Class resourceClass, - CacheKeyMapper cacheKeyMapper) { + CacheKeyMapper cacheKeyMapper) { super(resourceClass, cacheKeyMapper); this.resourceFetcher = resourceFetcher; } @@ -48,7 +48,7 @@ public void handleResourceEvent(ResourceID primaryID, R resource) { super.handleResources(primaryID, resource); } - public void handleResourceDeleteEvent(ResourceID primaryID, String resourceID) { + public void handleResourceDeleteEvent(ResourceID primaryID, ID resourceID) { super.handleDelete(primaryID, Set.of(resourceID)); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java index a66b92cffd..b05ea90055 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java @@ -24,10 +24,10 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; -public record PerResourcePollingConfiguration( +public record PerResourcePollingConfiguration( String name, ScheduledExecutorService executorService, - CacheKeyMapper cacheKeyMapper, + CacheKeyMapper cacheKeyMapper, PerResourcePollingEventSource.ResourceFetcher resourceFetcher, Predicate

registerPredicate, Duration defaultPollingPeriod) { @@ -37,7 +37,7 @@ public record PerResourcePollingConfiguration( public PerResourcePollingConfiguration( String name, ScheduledExecutorService executorService, - CacheKeyMapper cacheKeyMapper, + CacheKeyMapper cacheKeyMapper, PerResourcePollingEventSource.ResourceFetcher resourceFetcher, Predicate

registerPredicate, Duration defaultPollingPeriod) { @@ -47,7 +47,7 @@ public PerResourcePollingConfiguration( ? new ScheduledThreadPoolExecutor(DEFAULT_EXECUTOR_THREAD_NUMBER) : executorService; this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.singleResourceCacheKeyMapper() : cacheKeyMapper; + cacheKeyMapper == null ? CacheKeyMapper.externalIdProviderMapper() : cacheKeyMapper; this.resourceFetcher = Objects.requireNonNull(resourceFetcher); this.registerPredicate = registerPredicate; this.defaultPollingPeriod = defaultPollingPeriod; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java index 13a70bd9f2..7c15904742 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java @@ -22,7 +22,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; -public final class PerResourcePollingConfigurationBuilder { +public final class PerResourcePollingConfigurationBuilder { private final Duration defaultPollingPeriod; private final PerResourcePollingEventSource.ResourceFetcher resourceFetcher; @@ -30,7 +30,7 @@ public final class PerResourcePollingConfigurationBuilder registerPredicate; private ScheduledExecutorService executorService; - private CacheKeyMapper cacheKeyMapper; + private CacheKeyMapper cacheKeyMapper; public PerResourcePollingConfigurationBuilder( PerResourcePollingEventSource.ResourceFetcher resourceFetcher, @@ -40,30 +40,30 @@ public PerResourcePollingConfigurationBuilder( } @SuppressWarnings("unused") - public PerResourcePollingConfigurationBuilder withExecutorService( + public PerResourcePollingConfigurationBuilder withExecutorService( ScheduledExecutorService executorService) { this.executorService = executorService; return this; } - public PerResourcePollingConfigurationBuilder withRegisterPredicate( + public PerResourcePollingConfigurationBuilder withRegisterPredicate( Predicate

registerPredicate) { this.registerPredicate = registerPredicate; return this; } - public PerResourcePollingConfigurationBuilder withCacheKeyMapper( - CacheKeyMapper cacheKeyMapper) { + public PerResourcePollingConfigurationBuilder withCacheKeyMapper( + CacheKeyMapper cacheKeyMapper) { this.cacheKeyMapper = cacheKeyMapper; return this; } - public PerResourcePollingConfigurationBuilder withName(String name) { + public PerResourcePollingConfigurationBuilder withName(String name) { this.name = name; return this; } - public PerResourcePollingConfiguration build() { + public PerResourcePollingConfiguration build() { return new PerResourcePollingConfiguration<>( name, executorService, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index 2827c0bac0..d0e8116cb4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -48,8 +48,8 @@ * @param the resource polled by the event source * @param

related custom resource */ -public class PerResourcePollingEventSource - extends ExternalResourceCachingEventSource implements ResourceEventAware

{ +public class PerResourcePollingEventSource + extends ExternalResourceCachingEventSource implements ResourceEventAware

{ private static final Logger log = LoggerFactory.getLogger(PerResourcePollingEventSource.class); @@ -65,7 +65,7 @@ public class PerResourcePollingEventSource public PerResourcePollingEventSource( Class resourceClass, EventSourceContext

context, - PerResourcePollingConfiguration config) { + PerResourcePollingConfiguration config) { super(config.name(), resourceClass, config.cacheKeyMapper()); this.primaryResourceCache = context.getPrimaryCache(); this.resourceFetcher = config.resourceFetcher(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java index 56b6261a88..c93b5e43d7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java @@ -20,21 +20,21 @@ import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; -public record PollingConfiguration( +public record PollingConfiguration( String name, PollingEventSource.GenericResourceFetcher genericResourceFetcher, Duration period, - CacheKeyMapper cacheKeyMapper) { + CacheKeyMapper cacheKeyMapper) { public PollingConfiguration( String name, PollingEventSource.GenericResourceFetcher genericResourceFetcher, Duration period, - CacheKeyMapper cacheKeyMapper) { + CacheKeyMapper cacheKeyMapper) { this.name = name; this.genericResourceFetcher = Objects.requireNonNull(genericResourceFetcher); this.period = period; this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.singleResourceCacheKeyMapper() : cacheKeyMapper; + cacheKeyMapper == null ? CacheKeyMapper.externalIdProviderMapper() : cacheKeyMapper; } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java index 8d922080eb..783dca99da 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java @@ -19,10 +19,10 @@ import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; -public final class PollingConfigurationBuilder { +public final class PollingConfigurationBuilder { private final Duration period; private final PollingEventSource.GenericResourceFetcher genericResourceFetcher; - private CacheKeyMapper cacheKeyMapper; + private CacheKeyMapper cacheKeyMapper; private String name; public PollingConfigurationBuilder( @@ -31,17 +31,18 @@ public PollingConfigurationBuilder( this.period = period; } - public PollingConfigurationBuilder withCacheKeyMapper(CacheKeyMapper cacheKeyMapper) { + public PollingConfigurationBuilder withCacheKeyMapper( + CacheKeyMapper cacheKeyMapper) { this.cacheKeyMapper = cacheKeyMapper; return this; } - public PollingConfigurationBuilder withName(String name) { + public PollingConfigurationBuilder withName(String name) { this.name = name; return this; } - public PollingConfiguration build() { + public PollingConfiguration build() { return new PollingConfiguration<>(name, genericResourceFetcher, period, cacheKeyMapper); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java index 04548e1a11..be3b397343 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java @@ -57,8 +57,8 @@ * @param type of the polled resource * @param

primary resource type */ -public class PollingEventSource - extends ExternalResourceCachingEventSource { +public class PollingEventSource + extends ExternalResourceCachingEventSource { private static final Logger log = LoggerFactory.getLogger(PollingEventSource.class); @@ -67,7 +67,7 @@ public class PollingEventSource private final Duration period; private final AtomicBoolean healthy = new AtomicBoolean(true); - public PollingEventSource(Class resourceClass, PollingConfiguration config) { + public PollingEventSource(Class resourceClass, PollingConfiguration config) { super(config.name(), resourceClass, config.cacheKeyMapper()); this.genericResourceFetcher = config.genericResourceFetcher(); this.period = config.period(); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java index 0fc5495545..889cc4da75 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java @@ -30,7 +30,8 @@ class ExternalResourceCachingEventSourceTest extends AbstractEventSourceTestBase< - ExternalResourceCachingEventSource, EventHandler> { + ExternalResourceCachingEventSource, + EventHandler> { @BeforeEach public void setup() { @@ -211,7 +212,7 @@ void genericFilteringEvents() { } public static class TestExternalCachingEventSource - extends ExternalResourceCachingEventSource { + extends ExternalResourceCachingEventSource { public TestExternalCachingEventSource() { super(SampleExternalResource.class, SampleExternalResource::getName); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java index a6cebc0916..62b3403f2c 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java @@ -18,9 +18,10 @@ import java.io.Serializable; import java.util.Objects; +import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; import io.javaoperatorsdk.operator.processing.event.ResourceID; -public class SampleExternalResource implements Serializable { +public class SampleExternalResource implements Serializable, ExternalDependentIDProvider { public static final String DEFAULT_VALUE_1 = "value1"; public static final String DEFAULT_VALUE_2 = "value2"; @@ -81,4 +82,9 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(name, value); } + + @Override + public String externalResourceId() { + return name; + } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java index e468e20561..c02f6a288c 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java @@ -39,7 +39,8 @@ class CachingInboundEventSourceTest extends AbstractEventSourceTestBase< - CachingInboundEventSource, EventHandler> { + CachingInboundEventSource, + EventHandler> { @SuppressWarnings("unchecked") private final CachingInboundEventSource.ResourceFetcher< @@ -47,7 +48,7 @@ class CachingInboundEventSourceTest supplier = mock(CachingInboundEventSource.ResourceFetcher.class); private final TestCustomResource testCustomResource = TestUtils.testCustomResource(); - private final CacheKeyMapper cacheKeyMapper = + private final CacheKeyMapper cacheKeyMapper = r -> r.getName() + "#" + r.getValue(); @BeforeEach diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index cc5958cef4..0a2c413d3b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -40,7 +40,8 @@ class PerResourcePollingEventSourceTest extends AbstractEventSourceTestBase< - PerResourcePollingEventSource, EventHandler> { + PerResourcePollingEventSource, + EventHandler> { public static final int PERIOD = 150; @@ -66,7 +67,9 @@ public void setup() { new PerResourcePollingEventSource<>( SampleExternalResource.class, context, - new PerResourcePollingConfigurationBuilder<>(supplier, Duration.ofMillis(PERIOD)) + new PerResourcePollingConfigurationBuilder< + SampleExternalResource, TestCustomResource, String>( + supplier, Duration.ofMillis(PERIOD)) .withCacheKeyMapper(r -> r.getName() + "#" + r.getValue()) .build())); } @@ -91,10 +94,12 @@ void registeringTaskOnAPredicate() { new PerResourcePollingEventSource<>( SampleExternalResource.class, context, - new PerResourcePollingConfigurationBuilder<>(supplier, Duration.ofMillis(PERIOD)) + new PerResourcePollingConfigurationBuilder< + SampleExternalResource, TestCustomResource, String>( + supplier, Duration.ofMillis(PERIOD)) .withRegisterPredicate( testCustomResource -> testCustomResource.getMetadata().getGeneration() > 1) - .withCacheKeyMapper(CacheKeyMapper.singleResourceCacheKeyMapper()) + .withCacheKeyMapper(CacheKeyMapper.externalIdProviderMapper()) .build())); source.onResourceCreated(testCustomResource); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSourceTest.java index 923a4915b9..fbf657ba0b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSourceTest.java @@ -37,7 +37,7 @@ class PollingEventSourceTest extends AbstractEventSourceTestBase< - PollingEventSource, EventHandler> { + PollingEventSource, EventHandler> { public static final int DEFAULT_WAIT_PERIOD = 100; public static final Duration POLL_PERIOD = Duration.ofMillis(30L); @@ -46,7 +46,7 @@ class PollingEventSourceTest private final PollingEventSource.GenericResourceFetcher resourceFetcher = mock(PollingEventSource.GenericResourceFetcher.class); - private final PollingEventSource pollingEventSource = + private final PollingEventSource pollingEventSource = new PollingEventSource<>( SampleExternalResource.class, new PollingConfiguration<>( diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java index c2233d931b..4e4334cc16 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java @@ -52,19 +52,21 @@ public UpdateControl reconcile( @Override public List> prepareEventSources( EventSourceContext context) { - PerResourcePollingEventSource eventSource = - new PerResourcePollingEventSource<>( - String.class, - context, - new PerResourcePollingConfigurationBuilder<>( - (PerResourceEventSourceCustomResource resource) -> { - numberOfFetchExecutions.putIfAbsent(resource.getMetadata().getName(), 0); - numberOfFetchExecutions.compute( - resource.getMetadata().getName(), (s, v) -> v + 1); - return Set.of(UUID.randomUUID().toString()); - }, - Duration.ofMillis(POLL_PERIOD)) - .build()); + PerResourcePollingEventSource + eventSource = + new PerResourcePollingEventSource<>( + String.class, + context, + new PerResourcePollingConfigurationBuilder< + String, PerResourceEventSourceCustomResource, String>( + (PerResourceEventSourceCustomResource resource) -> { + numberOfFetchExecutions.putIfAbsent(resource.getMetadata().getName(), 0); + numberOfFetchExecutions.compute( + resource.getMetadata().getName(), (s, v) -> v + 1); + return Set.of(UUID.randomUUID().toString()); + }, + Duration.ofMillis(POLL_PERIOD)) + .build()); return List.of(eventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalBulkDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalBulkDependentResource.java index d6f3893674..dda70286d8 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalBulkDependentResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalBulkDependentResource.java @@ -31,7 +31,7 @@ import io.javaoperatorsdk.operator.processing.event.ResourceID; public class ExternalBulkDependentResource - extends PollingDependentResource + extends PollingDependentResource implements BulkDependentResource, Creator, Deleter, diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java index fff4f70656..9cf3132635 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java @@ -17,7 +17,9 @@ import java.util.Objects; -public class ExternalResource { +import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; + +public class ExternalResource implements ExternalDependentIDProvider { private final String id; private final String data; @@ -47,4 +49,9 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(id, data); } + + @Override + public String externalResourceId() { + return id; + } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalStateReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalStateReconciler.java index d1a03b0c8e..de485cfc4e 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalStateReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalStateReconciler.java @@ -56,7 +56,7 @@ public class ExternalStateReconciler private final ExternalIDGenServiceMock externalService = ExternalIDGenServiceMock.getInstance(); InformerEventSource configMapEventSource; - PerResourcePollingEventSource + PerResourcePollingEventSource externalResourceEventSource; @Override @@ -158,10 +158,13 @@ public List> prepareEventSources( return externalResource.map(Set::of).orElseGet(Collections::emptySet); }; externalResourceEventSource = - new PerResourcePollingEventSource<>( + new PerResourcePollingEventSource( ExternalResource.class, context, - new PerResourcePollingConfigurationBuilder<>(fetcher, Duration.ofMillis(300L)).build()); + new PerResourcePollingConfigurationBuilder< + ExternalResource, ExternalStateCustomResource, String>( + fetcher, Duration.ofMillis(300L)) + .build()); return Arrays.asList(configMapEventSource, externalResourceEventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalWithStateDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalWithStateDependentResource.java index c264ff52c7..e31578a843 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalWithStateDependentResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/ExternalWithStateDependentResource.java @@ -33,7 +33,8 @@ import io.javaoperatorsdk.operator.support.ExternalResource; public class ExternalWithStateDependentResource - extends PerResourcePollingDependentResource + extends PerResourcePollingDependentResource< + ExternalResource, ExternalStateCustomResource, String> implements DependentResourceWithExplicitState< ExternalResource, ExternalStateCustomResource, ConfigMap>, Updater { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java index 696b02c01e..41a4db2f02 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java @@ -34,7 +34,7 @@ public class BulkDependentResourceExternalWithState extends PerResourcePollingDependentResource< - ExternalResource, ExternalStateBulkDependentCustomResource> + ExternalResource, ExternalStateBulkDependentCustomResource, String> implements BulkDependentResource, CRUDBulkDependentResource, DependentResourceWithExplicitState< diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/AbstractExternalDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/AbstractExternalDependentResource.java index 743e6b94f9..7c39a7db9a 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/AbstractExternalDependentResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/AbstractExternalDependentResource.java @@ -30,7 +30,7 @@ public abstract class AbstractExternalDependentResource extends PollingDependentResource< - ExternalResource, MultipleManagedExternalDependentResourceCustomResource> + ExternalResource, MultipleManagedExternalDependentResourceCustomResource, String> implements Creator, Updater, Deleter { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/MultipleManagedExternalDependentResourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/MultipleManagedExternalDependentResourceReconciler.java index 9380895105..66939a3c49 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/MultipleManagedExternalDependentResourceReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/multiplemanagedexternaldependenttype/MultipleManagedExternalDependentResourceReconciler.java @@ -91,11 +91,13 @@ public int getNumberOfExecutions() { return res; }; - PollingEventSource + PollingEventSource< + ExternalResource, MultipleManagedExternalDependentResourceCustomResource, String> pollingEventSource = new PollingEventSource<>( ExternalResource.class, - new PollingConfigurationBuilder<>(fetcher, Duration.ofMillis(1000L)) + new PollingConfigurationBuilder( + fetcher, Duration.ofMillis(1000L)) .withName(EVENT_SOURCE_NAME) .withCacheKeyMapper(ExternalResource::getId) .build()); diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java index 4c510edee5..6400d312c7 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java @@ -58,7 +58,7 @@ with = ResourcePollerConfig.class, converter = ResourcePollerConfigConverter.class) public class SchemaDependentResource - extends PerResourcePollingDependentResource + extends PerResourcePollingDependentResource implements ConfiguredDependentResource, Creator, Deleter { From cb532df2a0187dd4c737ae6b5db35375c0d98866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Sun, 19 Oct 2025 19:09:20 +0200 Subject: [PATCH 2/5] wip --- .../dependent-resources.md | 6 +++--- ...dentIDProvider.java => ResourceIDProvider.java} | 14 ++++++++------ .../AbstractExternalDependentResource.java | 8 +++----- .../external/AbstractPollingDependentResource.java | 2 +- .../processing/event/source/CacheKeyMapper.java | 13 ++++++------- .../source/ExternalResourceCachingEventSource.java | 6 ++++++ .../polling/PerResourcePollingConfiguration.java | 2 +- .../event/source/polling/PollingConfiguration.java | 2 +- .../event/source/SampleExternalResource.java | 6 +++--- .../polling/PerResourcePollingEventSourceTest.java | 2 +- ...erResourcePollingEventSourceTestReconciler.java | 2 ++ .../bulkdependent/external/ExternalResource.java | 6 +++--- .../operator/support/ExternalResource.java | 6 +++--- .../operator/sample/schema/Schema.java | 6 +++--- 14 files changed, 44 insertions(+), 37 deletions(-) rename operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/{dependent/ExternalDependentIDProvider.java => ResourceIDProvider.java} (61%) diff --git a/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md b/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md index 8a575f716f..a73d600609 100644 --- a/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md +++ b/docs/content/en/docs/documentation/dependent-resource-and-workflows/dependent-resources.md @@ -370,13 +370,13 @@ or we can use a matcher based SSA in most of the cases if the resource is manage Unfortunately this is not true for external resources. So to make sure we are selecting the target resources from an event source, we provide a [mechanism](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java#L114-L138) that helps with that logic. -Your POJO representing an external resource can implement [`ExternalResourceIDProvider`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalDependentIDProvider.java) : +Your POJO representing an external resource can implement [`ResourceIDProvider`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java) : ```java -public interface ExternalDependentIDProvider { +public interface ResourceIDProvider { - T externalResourceId(); + T resourceId(); } ``` diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalDependentIDProvider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java similarity index 61% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalDependentIDProvider.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java index b6c755178d..f2e5e9728b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalDependentIDProvider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.javaoperatorsdk.operator.processing.dependent; +package io.javaoperatorsdk.operator.processing; /** - * Provides the identifier for an object that represents an external resource. This ID is used to - * select target resource for a dependent resource from the resources returned by `{@link - * io.javaoperatorsdk.operator.api.reconciler.Context#getSecondaryResources(Class)}`. + * Provides the identifier for an object that represents resource. This ID is used to select target + * external resource for a dependent resource from the resources returned by `{@link + * io.javaoperatorsdk.operator.api.reconciler.Context#getSecondaryResources(Class)}`. But also for + * {@link io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper} for event sources in + * external resources * * @param */ -public interface ExternalDependentIDProvider { +public interface ResourceIDProvider { - T externalResourceId(); + T resourceId(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java index 2c5be82288..f20a842cad 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; @@ -131,14 +132,11 @@ protected Optional selectTargetSecondaryResource( Set secondaryResources, P primary, Context

context) { R desired = desired(primary, context); List targetResources; - if (desired instanceof ExternalDependentIDProvider desiredWithId) { + if (desired instanceof ResourceIDProvider desiredWithId) { targetResources = secondaryResources.stream() .filter( - r -> - ((ExternalDependentIDProvider) r) - .externalResourceId() - .equals(desiredWithId.externalResourceId())) + r -> ((ResourceIDProvider) r).resourceId().equals(desiredWithId.resourceId())) .toList(); } else { throw new IllegalStateException( 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 22ad401fe7..acf8580e27 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 @@ -53,6 +53,6 @@ public Duration getPollingPeriod() { // for now dependent resources support event sources only with one owned resource. @Override public ID keyFor(R resource) { - return CacheKeyMapper.externalIdProviderMapper().keyFor(resource); + return CacheKeyMapper.resourceIdProviderMapper().keyFor(resource); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java index 6f3b9fd571..069a06d3fc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java @@ -15,15 +15,15 @@ */ package io.javaoperatorsdk.operator.processing.event.source; -import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; public interface CacheKeyMapper { ID keyFor(R resource); /** - * Used if a polling event source handles only single secondary resource. See also docs for: - * {@link ExternalResourceCachingEventSource} + * Used if a polling event source handles only single secondary resource and the id is String. See + * also docs for: {@link ExternalResourceCachingEventSource} * * @return static id mapper, all resources are mapped for same id. * @param secondary resource type @@ -32,11 +32,10 @@ static CacheKeyMapper singleResourceCacheKeyMapper() { return r -> "id"; } - static CacheKeyMapper externalIdProviderMapper() { - + static CacheKeyMapper resourceIdProviderMapper() { return r -> { - if (r instanceof ExternalDependentIDProvider externalDependentIDProvider) { - return (ID) externalDependentIDProvider.externalResourceId(); + if (r instanceof ResourceIDProvider resourceIDProvider) { + return (ID) resourceIDProvider.resourceId(); } else { throw new IllegalStateException( "Resource does not implement ExternalDependentIDProvider: " + r.getClass()); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java index 2a57d9d682..eeaf766459 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java @@ -32,6 +32,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.ResourceID; @@ -72,6 +73,11 @@ protected ExternalResourceCachingEventSource( protected ExternalResourceCachingEventSource( String name, Class resourceClass, CacheKeyMapper cacheKeyMapper) { super(resourceClass, name); + if (cacheKeyMapper == CacheKeyMapper.resourceIdProviderMapper() + && !ResourceIDProvider.class.isAssignableFrom(resourceClass)) { + throw new IllegalArgumentException( + "resource class is not a " + ResourceIDProvider.class.getSimpleName()); + } this.cacheKeyMapper = cacheKeyMapper; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java index b05ea90055..73546dfd4f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java @@ -47,7 +47,7 @@ public PerResourcePollingConfiguration( ? new ScheduledThreadPoolExecutor(DEFAULT_EXECUTOR_THREAD_NUMBER) : executorService; this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.externalIdProviderMapper() : cacheKeyMapper; + cacheKeyMapper == null ? CacheKeyMapper.resourceIdProviderMapper() : cacheKeyMapper; this.resourceFetcher = Objects.requireNonNull(resourceFetcher); this.registerPredicate = registerPredicate; this.defaultPollingPeriod = defaultPollingPeriod; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java index c93b5e43d7..e48d4fd3e1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java @@ -35,6 +35,6 @@ public PollingConfiguration( this.genericResourceFetcher = Objects.requireNonNull(genericResourceFetcher); this.period = period; this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.externalIdProviderMapper() : cacheKeyMapper; + cacheKeyMapper == null ? CacheKeyMapper.resourceIdProviderMapper() : cacheKeyMapper; } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java index 62b3403f2c..4abac62b2e 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/SampleExternalResource.java @@ -18,10 +18,10 @@ import java.io.Serializable; import java.util.Objects; -import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; import io.javaoperatorsdk.operator.processing.event.ResourceID; -public class SampleExternalResource implements Serializable, ExternalDependentIDProvider { +public class SampleExternalResource implements Serializable, ResourceIDProvider { public static final String DEFAULT_VALUE_1 = "value1"; public static final String DEFAULT_VALUE_2 = "value2"; @@ -84,7 +84,7 @@ public int hashCode() { } @Override - public String externalResourceId() { + public String resourceId() { return name; } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index 0a2c413d3b..dbe93da915 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -99,7 +99,7 @@ void registeringTaskOnAPredicate() { supplier, Duration.ofMillis(PERIOD)) .withRegisterPredicate( testCustomResource -> testCustomResource.getMetadata().getGeneration() > 1) - .withCacheKeyMapper(CacheKeyMapper.externalIdProviderMapper()) + .withCacheKeyMapper(CacheKeyMapper.resourceIdProviderMapper()) .build())); source.onResourceCreated(testCustomResource); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java index 4e4334cc16..91aa487063 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java @@ -27,6 +27,7 @@ import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingConfigurationBuilder; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; @@ -66,6 +67,7 @@ public List> prepareEventSo return Set.of(UUID.randomUUID().toString()); }, Duration.ofMillis(POLL_PERIOD)) + .withCacheKeyMapper(CacheKeyMapper.singleResourceCacheKeyMapper()) .build()); return List.of(eventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java index 9cf3132635..a9fb27e56d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/bulkdependent/external/ExternalResource.java @@ -17,9 +17,9 @@ import java.util.Objects; -import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; -public class ExternalResource implements ExternalDependentIDProvider { +public class ExternalResource implements ResourceIDProvider { private final String id; private final String data; @@ -51,7 +51,7 @@ public int hashCode() { } @Override - public String externalResourceId() { + public String resourceId() { return id; } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/ExternalResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/ExternalResource.java index f281fe95db..d581f3c624 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/ExternalResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/ExternalResource.java @@ -18,10 +18,10 @@ import java.util.Objects; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; import io.javaoperatorsdk.operator.processing.event.ResourceID; -public class ExternalResource implements ExternalDependentIDProvider { +public class ExternalResource implements ResourceIDProvider { public static final String EXTERNAL_RESOURCE_NAME_DELIMITER = "#"; @@ -83,7 +83,7 @@ public static String toExternalResourceId(HasMetadata primary) { } @Override - public String externalResourceId() { + public String resourceId() { return id; } } diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/schema/Schema.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/schema/Schema.java index baaa829534..a7c001ffe5 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/schema/Schema.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/schema/Schema.java @@ -18,9 +18,9 @@ import java.io.Serializable; import java.util.Objects; -import io.javaoperatorsdk.operator.processing.dependent.ExternalDependentIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDProvider; -public class Schema implements Serializable, ExternalDependentIDProvider { +public class Schema implements Serializable, ResourceIDProvider { private final String name; private final String characterSet; @@ -57,7 +57,7 @@ public String toString() { } @Override - public String externalResourceId() { + public String resourceId() { return name; } } From d0867e420a4d2cf5c8ef4486dbabc366dc8a2594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 23 Oct 2025 16:20:17 +0200 Subject: [PATCH 3/5] improve: ResourceIDMapper and ResourceIDProvider for external resources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will check if this could be elegantly extended to bulk resources Signed-off-by: Attila Mészáros --- ...heKeyMapper.java => ResourceIDMapper.java} | 12 ++++---- .../processing/ResourceIDProvider.java | 3 +- .../AbstractExternalDependentResource.java | 30 +++++++++++-------- .../AbstractPollingDependentResource.java | 11 ++----- .../PerResourcePollingDependentResource.java | 2 +- .../external/PollingDependentResource.java | 14 ++++----- .../ExternalResourceCachingEventSource.java | 23 +++++++------- .../inbound/CachingInboundEventSource.java | 6 ++-- .../PerResourcePollingConfiguration.java | 10 +++---- ...erResourcePollingConfigurationBuilder.java | 12 ++++---- .../PerResourcePollingEventSource.java | 2 +- .../source/polling/PollingConfiguration.java | 10 +++---- .../polling/PollingConfigurationBuilder.java | 10 +++---- .../source/polling/PollingEventSource.java | 2 +- .../CachingInboundEventSourceTest.java | 10 +++---- .../PerResourcePollingEventSourceTest.java | 6 ++-- ...ourcePollingEventSourceTestReconciler.java | 4 +-- ...ulkDependentResourceExternalWithState.java | 6 +--- 18 files changed, 83 insertions(+), 90 deletions(-) rename operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/{event/source/CacheKeyMapper.java => ResourceIDMapper.java} (77%) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java similarity index 77% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java index 069a06d3fc..ebad96116a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/CacheKeyMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.javaoperatorsdk.operator.processing.event.source; +package io.javaoperatorsdk.operator.processing; -import io.javaoperatorsdk.operator.processing.ResourceIDProvider; +import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; -public interface CacheKeyMapper { +public interface ResourceIDMapper { - ID keyFor(R resource); + ID idFor(R resource); /** * Used if a polling event source handles only single secondary resource and the id is String. See @@ -28,11 +28,11 @@ public interface CacheKeyMapper { * @return static id mapper, all resources are mapped for same id. * @param secondary resource type */ - static CacheKeyMapper singleResourceCacheKeyMapper() { + static ResourceIDMapper singleResourceCacheKeyMapper() { return r -> "id"; } - static CacheKeyMapper resourceIdProviderMapper() { + static ResourceIDMapper resourceIdProviderMapper() { return r -> { if (r instanceof ResourceIDProvider resourceIDProvider) { return (ID) resourceIDProvider.resourceId(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java index f2e5e9728b..dcab1be92a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDProvider.java @@ -19,8 +19,7 @@ * Provides the identifier for an object that represents resource. This ID is used to select target * external resource for a dependent resource from the resources returned by `{@link * io.javaoperatorsdk.operator.api.reconciler.Context#getSecondaryResources(Class)}`. But also for - * {@link io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper} for event sources in - * external resources + * {@link ResourceIDMapper} for event sources in external resources * * @param */ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java index f20a842cad..6d0d76e9c5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractExternalDependentResource.java @@ -22,20 +22,22 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; -import io.javaoperatorsdk.operator.processing.ResourceIDProvider; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; public abstract class AbstractExternalDependentResource< - R, P extends HasMetadata, T extends EventSource> + R, P extends HasMetadata, T extends EventSource, ID> extends AbstractEventSourceHolderDependentResource { private final boolean isDependentResourceWithExplicitState = this instanceof DependentResourceWithExplicitState; private final boolean isBulkDependentResource = this instanceof BulkDependentResource; + protected ResourceIDMapper resourceIDMapper = ResourceIDMapper.resourceIdProviderMapper(); + @SuppressWarnings("rawtypes") private DependentResourceWithExplicitState dependentResourceWithExplicitState; @@ -132,21 +134,23 @@ protected Optional selectTargetSecondaryResource( Set secondaryResources, P primary, Context

context) { R desired = desired(primary, context); List targetResources; - if (desired instanceof ResourceIDProvider desiredWithId) { - targetResources = - secondaryResources.stream() - .filter( - r -> ((ResourceIDProvider) r).resourceId().equals(desiredWithId.resourceId())) - .toList(); - } else { - throw new IllegalStateException( - "Either implement ExternalDependentIDProvider or override this " - + " (selectTargetSecondaryResource) method."); - } + var desiredID = resourceIDMapper.idFor(desired); + targetResources = + secondaryResources.stream() + .filter(r -> resourceIDMapper.idFor(r).equals(desiredID)) + .toList(); if (targetResources.size() > 1) { throw new IllegalStateException( "More than one secondary resource related to primary: " + targetResources); } return targetResources.isEmpty() ? Optional.empty() : Optional.of(targetResources.get(0)); } + + public ResourceIDMapper getResourceIDMapper() { + return resourceIDMapper; + } + + public void setResourceIDMapper(ResourceIDMapper resourceIDMapper) { + this.resourceIDMapper = resourceIDMapper; + } } 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 acf8580e27..1776194e33 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 @@ -20,13 +20,12 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.processing.dependent.AbstractExternalDependentResource; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @Ignore public abstract class AbstractPollingDependentResource - extends AbstractExternalDependentResource> - implements CacheKeyMapper { + extends AbstractExternalDependentResource< + R, P, ExternalResourceCachingEventSource, ID> { public static final Duration DEFAULT_POLLING_PERIOD = Duration.ofMillis(5000); private Duration pollingPeriod; @@ -49,10 +48,4 @@ public void setPollingPeriod(Duration pollingPeriod) { public Duration getPollingPeriod() { return pollingPeriod; } - - // for now dependent resources support event sources only with one owned resource. - @Override - public ID keyFor(R resource) { - return CacheKeyMapper.resourceIdProviderMapper().keyFor(resource); - } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java index 18de989bc1..15ac34aa6e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PerResourcePollingDependentResource.java @@ -47,7 +47,7 @@ protected ExternalResourceCachingEventSource createEventSource( resourceType(), context, new PerResourcePollingConfigurationBuilder(this, getPollingPeriod()) - .withCacheKeyMapper(this) + .withResourceIDMapper(getResourceIDMapper()) .withName(name()) .build()); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java index 339f104a4d..1abeeb1ef2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/PollingDependentResource.java @@ -20,7 +20,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.Ignore; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PollingConfiguration; import io.javaoperatorsdk.operator.processing.event.source.polling.PollingEventSource; @@ -30,17 +30,17 @@ public abstract class PollingDependentResource extends AbstractPollingDependentResource implements PollingEventSource.GenericResourceFetcher { - private final CacheKeyMapper cacheKeyMapper; + private final ResourceIDMapper resourceIDMapper; - public PollingDependentResource(Class resourceType, CacheKeyMapper cacheKeyMapper) { + public PollingDependentResource(Class resourceType, ResourceIDMapper resourceIDMapper) { super(resourceType); - this.cacheKeyMapper = cacheKeyMapper; + this.resourceIDMapper = resourceIDMapper; } public PollingDependentResource( - Class resourceType, Duration pollingPeriod, CacheKeyMapper cacheKeyMapper) { + Class resourceType, Duration pollingPeriod, ResourceIDMapper resourceIDMapper) { super(resourceType, pollingPeriod); - this.cacheKeyMapper = cacheKeyMapper; + this.resourceIDMapper = resourceIDMapper; } @Override @@ -48,6 +48,6 @@ protected ExternalResourceCachingEventSource createEventSource( EventSourceContext

context) { return new PollingEventSource<>( resourceType(), - new PollingConfiguration<>(name(), this, getPollingPeriod(), cacheKeyMapper)); + new PollingConfiguration<>(name(), this, getPollingPeriod(), resourceIDMapper)); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java index eeaf766459..259d6e6f0b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java @@ -32,6 +32,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.ResourceIDProvider; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.ResourceID; @@ -61,24 +62,24 @@ public abstract class ExternalResourceCachingEventSource cacheKeyMapper; + protected final ResourceIDMapper resourceIDMapper; protected Map> cache = new ConcurrentHashMap<>(); protected ExternalResourceCachingEventSource( - Class resourceClass, CacheKeyMapper cacheKeyMapper) { - this(null, resourceClass, cacheKeyMapper); + Class resourceClass, ResourceIDMapper resourceIDMapper) { + this(null, resourceClass, resourceIDMapper); } protected ExternalResourceCachingEventSource( - String name, Class resourceClass, CacheKeyMapper cacheKeyMapper) { + String name, Class resourceClass, ResourceIDMapper resourceIDMapper) { super(resourceClass, name); - if (cacheKeyMapper == CacheKeyMapper.resourceIdProviderMapper() + if (resourceIDMapper == ResourceIDMapper.resourceIdProviderMapper() && !ResourceIDProvider.class.isAssignableFrom(resourceClass)) { throw new IllegalArgumentException( "resource class is not a " + ResourceIDProvider.class.getSimpleName()); } - this.cacheKeyMapper = cacheKeyMapper; + this.resourceIDMapper = resourceIDMapper; } protected synchronized void handleDelete(ResourceID primaryID) { @@ -90,11 +91,11 @@ protected synchronized void handleDelete(ResourceID primaryID) { protected synchronized void handleDeletes(ResourceID primaryID, Set resource) { handleDelete( - primaryID, resource.stream().map(cacheKeyMapper::keyFor).collect(Collectors.toSet())); + primaryID, resource.stream().map(resourceIDMapper::idFor).collect(Collectors.toSet())); } protected synchronized void handleDelete(ResourceID primaryID, R resource) { - handleDelete(primaryID, Set.of(cacheKeyMapper.keyFor(resource))); + handleDelete(primaryID, Set.of(resourceIDMapper.idFor(resource))); } protected synchronized void handleDelete(ResourceID primaryID, Set resourceIDs) { @@ -143,7 +144,7 @@ protected synchronized void handleResources( cachedResources = Collections.emptyMap(); } var newResourcesMap = - newResources.stream().collect(Collectors.toMap(cacheKeyMapper::keyFor, r -> r)); + newResources.stream().collect(Collectors.toMap(resourceIDMapper::idFor, r -> r)); cache.put(primaryID, newResourcesMap); if (propagateEvent && !newResourcesMap.equals(cachedResources) @@ -205,7 +206,7 @@ private boolean acceptedByGenericFiler(R resource) { @Override public synchronized void handleRecentResourceCreate(ResourceID primaryID, R resource) { var actualValues = cache.get(primaryID); - var resourceId = cacheKeyMapper.keyFor(resource); + var resourceId = resourceIDMapper.idFor(resource); if (actualValues == null) { actualValues = new HashMap<>(); cache.put(primaryID, actualValues); @@ -220,7 +221,7 @@ public synchronized void handleRecentResourceUpdate( ResourceID primaryID, R resource, R previousVersionOfResource) { var actualValues = cache.get(primaryID); if (actualValues != null) { - var resourceId = cacheKeyMapper.keyFor(resource); + var resourceId = resourceIDMapper.idFor(resource); R actualResource = actualValues.get(resourceId); if (actualResource.equals(previousVersionOfResource)) { actualValues.put(resourceId, resource); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java index 34d8c51d77..44e0a684b6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSource.java @@ -21,8 +21,8 @@ import java.util.concurrent.ConcurrentHashMap; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.ResourceID; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.source.ResourceEventAware; @@ -35,8 +35,8 @@ public class CachingInboundEventSource public CachingInboundEventSource( ResourceFetcher resourceFetcher, Class resourceClass, - CacheKeyMapper cacheKeyMapper) { - super(resourceClass, cacheKeyMapper); + ResourceIDMapper resourceIDMapper) { + super(resourceClass, resourceIDMapper); this.resourceFetcher = resourceFetcher; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java index 73546dfd4f..599647ff29 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfiguration.java @@ -22,12 +22,12 @@ import java.util.function.Predicate; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; public record PerResourcePollingConfiguration( String name, ScheduledExecutorService executorService, - CacheKeyMapper cacheKeyMapper, + ResourceIDMapper resourceIDMapper, PerResourcePollingEventSource.ResourceFetcher resourceFetcher, Predicate

registerPredicate, Duration defaultPollingPeriod) { @@ -37,7 +37,7 @@ public record PerResourcePollingConfiguration( public PerResourcePollingConfiguration( String name, ScheduledExecutorService executorService, - CacheKeyMapper cacheKeyMapper, + ResourceIDMapper resourceIDMapper, PerResourcePollingEventSource.ResourceFetcher resourceFetcher, Predicate

registerPredicate, Duration defaultPollingPeriod) { @@ -46,8 +46,8 @@ public PerResourcePollingConfiguration( executorService == null ? new ScheduledThreadPoolExecutor(DEFAULT_EXECUTOR_THREAD_NUMBER) : executorService; - this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.resourceIdProviderMapper() : cacheKeyMapper; + this.resourceIDMapper = + resourceIDMapper == null ? ResourceIDMapper.resourceIdProviderMapper() : resourceIDMapper; this.resourceFetcher = Objects.requireNonNull(resourceFetcher); this.registerPredicate = registerPredicate; this.defaultPollingPeriod = defaultPollingPeriod; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java index 7c15904742..6fcf5d2678 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingConfigurationBuilder.java @@ -20,7 +20,7 @@ import java.util.function.Predicate; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; public final class PerResourcePollingConfigurationBuilder { @@ -30,7 +30,7 @@ public final class PerResourcePollingConfigurationBuilder registerPredicate; private ScheduledExecutorService executorService; - private CacheKeyMapper cacheKeyMapper; + private ResourceIDMapper resourceIDMapper; public PerResourcePollingConfigurationBuilder( PerResourcePollingEventSource.ResourceFetcher resourceFetcher, @@ -52,9 +52,9 @@ public PerResourcePollingConfigurationBuilder withRegisterPredicate( return this; } - public PerResourcePollingConfigurationBuilder withCacheKeyMapper( - CacheKeyMapper cacheKeyMapper) { - this.cacheKeyMapper = cacheKeyMapper; + public PerResourcePollingConfigurationBuilder withResourceIDMapper( + ResourceIDMapper resourceIDMapper) { + this.resourceIDMapper = resourceIDMapper; return this; } @@ -67,7 +67,7 @@ public PerResourcePollingConfiguration build() { return new PerResourcePollingConfiguration<>( name, executorService, - cacheKeyMapper, + resourceIDMapper, resourceFetcher, registerPredicate, defaultPollingPeriod); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index d0e8116cb4..0f0eb78a69 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -66,7 +66,7 @@ public PerResourcePollingEventSource( Class resourceClass, EventSourceContext

context, PerResourcePollingConfiguration config) { - super(config.name(), resourceClass, config.cacheKeyMapper()); + super(config.name(), resourceClass, config.resourceIDMapper()); this.primaryResourceCache = context.getPrimaryCache(); this.resourceFetcher = config.resourceFetcher(); this.registerPredicate = config.registerPredicate(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java index e48d4fd3e1..9ac1b8cc96 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfiguration.java @@ -18,23 +18,23 @@ import java.time.Duration; import java.util.Objects; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; public record PollingConfiguration( String name, PollingEventSource.GenericResourceFetcher genericResourceFetcher, Duration period, - CacheKeyMapper cacheKeyMapper) { + ResourceIDMapper resourceIDMapper) { public PollingConfiguration( String name, PollingEventSource.GenericResourceFetcher genericResourceFetcher, Duration period, - CacheKeyMapper cacheKeyMapper) { + ResourceIDMapper resourceIDMapper) { this.name = name; this.genericResourceFetcher = Objects.requireNonNull(genericResourceFetcher); this.period = period; - this.cacheKeyMapper = - cacheKeyMapper == null ? CacheKeyMapper.resourceIdProviderMapper() : cacheKeyMapper; + this.resourceIDMapper = + resourceIDMapper == null ? ResourceIDMapper.resourceIdProviderMapper() : resourceIDMapper; } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java index 783dca99da..39c4ce4e54 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingConfigurationBuilder.java @@ -17,12 +17,12 @@ import java.time.Duration; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; public final class PollingConfigurationBuilder { private final Duration period; private final PollingEventSource.GenericResourceFetcher genericResourceFetcher; - private CacheKeyMapper cacheKeyMapper; + private ResourceIDMapper resourceIDMapper; private String name; public PollingConfigurationBuilder( @@ -32,8 +32,8 @@ public PollingConfigurationBuilder( } public PollingConfigurationBuilder withCacheKeyMapper( - CacheKeyMapper cacheKeyMapper) { - this.cacheKeyMapper = cacheKeyMapper; + ResourceIDMapper resourceIDMapper) { + this.resourceIDMapper = resourceIDMapper; return this; } @@ -43,6 +43,6 @@ public PollingConfigurationBuilder withName(String name) { } public PollingConfiguration build() { - return new PollingConfiguration<>(name, genericResourceFetcher, period, cacheKeyMapper); + return new PollingConfiguration<>(name, genericResourceFetcher, period, resourceIDMapper); } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java index be3b397343..f5e5a79430 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PollingEventSource.java @@ -68,7 +68,7 @@ public class PollingEventSource private final AtomicBoolean healthy = new AtomicBoolean(true); public PollingEventSource(Class resourceClass, PollingConfiguration config) { - super(config.name(), resourceClass, config.cacheKeyMapper()); + super(config.name(), resourceClass, config.resourceIDMapper()); this.genericResourceFetcher = config.genericResourceFetcher(); this.period = config.period(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java index c02f6a288c..9356de626b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/inbound/CachingInboundEventSourceTest.java @@ -21,10 +21,10 @@ import org.junit.jupiter.api.Test; import io.javaoperatorsdk.operator.TestUtils; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.EventHandler; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.AbstractEventSourceTestBase; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; import io.javaoperatorsdk.operator.processing.event.source.SampleExternalResource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -48,7 +48,7 @@ class CachingInboundEventSourceTest supplier = mock(CachingInboundEventSource.ResourceFetcher.class); private final TestCustomResource testCustomResource = TestUtils.testCustomResource(); - private final CacheKeyMapper cacheKeyMapper = + private final ResourceIDMapper resourceIDMapper = r -> r.getName() + "#" + r.getValue(); @BeforeEach @@ -56,7 +56,7 @@ public void setup() { when(supplier.fetchResources(any())).thenReturn(Set.of(SampleExternalResource.testResource1())); setUpSource( - new CachingInboundEventSource<>(supplier, SampleExternalResource.class, cacheKeyMapper)); + new CachingInboundEventSource<>(supplier, SampleExternalResource.class, resourceIDMapper)); } @Test @@ -90,10 +90,10 @@ void propagateEventOnDeletedResource() throws InterruptedException { ResourceID.fromResource(testCustomResource), SampleExternalResource.testResource1()); source.handleResourceDeleteEvent( ResourceID.fromResource(testCustomResource), - cacheKeyMapper.keyFor(SampleExternalResource.testResource1())); + resourceIDMapper.idFor(SampleExternalResource.testResource1())); source.handleResourceDeleteEvent( ResourceID.fromResource(testCustomResource), - cacheKeyMapper.keyFor(SampleExternalResource.testResource2())); + resourceIDMapper.idFor(SampleExternalResource.testResource2())); verify(eventHandler, times(2)).handleEvent(any()); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index dbe93da915..907ed19fe5 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -25,9 +25,9 @@ import io.javaoperatorsdk.operator.TestUtils; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.EventHandler; import io.javaoperatorsdk.operator.processing.event.source.AbstractEventSourceTestBase; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; import io.javaoperatorsdk.operator.processing.event.source.IndexerResourceCache; import io.javaoperatorsdk.operator.processing.event.source.SampleExternalResource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -70,7 +70,7 @@ public void setup() { new PerResourcePollingConfigurationBuilder< SampleExternalResource, TestCustomResource, String>( supplier, Duration.ofMillis(PERIOD)) - .withCacheKeyMapper(r -> r.getName() + "#" + r.getValue()) + .withResourceIDMapper(r -> r.getName() + "#" + r.getValue()) .build())); } @@ -99,7 +99,7 @@ void registeringTaskOnAPredicate() { supplier, Duration.ofMillis(PERIOD)) .withRegisterPredicate( testCustomResource -> testCustomResource.getMetadata().getGeneration() > 1) - .withCacheKeyMapper(CacheKeyMapper.resourceIdProviderMapper()) + .withResourceIDMapper(ResourceIDMapper.resourceIdProviderMapper()) .build())); source.onResourceCreated(testCustomResource); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java index 91aa487063..4c6eff7530 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/perresourceeventsource/PerResourcePollingEventSourceTestReconciler.java @@ -27,7 +27,7 @@ import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import io.javaoperatorsdk.operator.processing.event.source.CacheKeyMapper; +import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingConfigurationBuilder; import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; @@ -67,7 +67,7 @@ public List> prepareEventSo return Set.of(UUID.randomUUID().toString()); }, Duration.ofMillis(POLL_PERIOD)) - .withCacheKeyMapper(CacheKeyMapper.singleResourceCacheKeyMapper()) + .withResourceIDMapper(ResourceIDMapper.singleResourceCacheKeyMapper()) .build()); return List.of(eventSource); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java index 41a4db2f02..569e974bff 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/dependent/externalstate/externalstatebulkdependent/BulkDependentResourceExternalWithState.java @@ -45,6 +45,7 @@ public class BulkDependentResourceExternalWithState public BulkDependentResourceExternalWithState() { super(ExternalResource.class, Duration.ofMillis(300)); + setResourceIDMapper(this::externalResourceIndex); } @Override @@ -159,9 +160,4 @@ private String configMapName( ExternalStateBulkDependentCustomResource primary, ExternalResource resource) { return primary.getMetadata().getName() + DELIMITER + externalResourceIndex(resource); } - - @Override - public String keyFor(ExternalResource resource) { - return externalResourceIndex(resource); - } } From f615a86604060d257e4bd16e40b06b0aa7dbe682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 23 Oct 2025 16:25:04 +0200 Subject: [PATCH 4/5] wip --- .../javaoperatorsdk/operator/processing/ResourceIDMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java index ebad96116a..4dd34844fa 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java @@ -22,8 +22,8 @@ public interface ResourceIDMapper { ID idFor(R resource); /** - * Used if a polling event source handles only single secondary resource and the id is String. See - * also docs for: {@link ExternalResourceCachingEventSource} + * Can be used if a polling event source handles only single secondary resource and the id is + * String. See also docs for: {@link ExternalResourceCachingEventSource} * * @return static id mapper, all resources are mapped for same id. * @param secondary resource type From a620cbe321e7a626833a6899e5ee4924b31a7b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 24 Oct 2025 13:11:06 +0200 Subject: [PATCH 5/5] wip --- .../io/javaoperatorsdk/operator/processing/ResourceIDMapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java index 4dd34844fa..775c99c1ad 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceIDMapper.java @@ -17,6 +17,7 @@ import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; +/** Provides id for the target resource. */ public interface ResourceIDMapper { ID idFor(R resource);