From 0bf061afacbade2d0e5e05c9e6fb241136faf5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 13 Mar 2026 16:02:56 +0100 Subject: [PATCH 1/8] chore: update version to 999-SNAPSHOT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- bootstrapper-maven-plugin/pom.xml | 4 ++-- caffeine-bounded-cache-support/pom.xml | 2 +- micrometer-support/pom.xml | 2 +- operator-framework-bom/pom.xml | 2 +- operator-framework-core/pom.xml | 2 +- operator-framework-junit/pom.xml | 2 +- operator-framework/pom.xml | 2 +- pom.xml | 6 +++--- sample-operators/controller-namespace-deletion/pom.xml | 2 +- sample-operators/leader-election/pom.xml | 2 +- sample-operators/mysql-schema/pom.xml | 2 +- sample-operators/operations/pom.xml | 7 +------ sample-operators/pom.xml | 2 +- sample-operators/tomcat-operator/pom.xml | 2 +- sample-operators/webpage/pom.xml | 2 +- test-index-processor/pom.xml | 2 +- 16 files changed, 19 insertions(+), 24 deletions(-) diff --git a/bootstrapper-maven-plugin/pom.xml b/bootstrapper-maven-plugin/pom.xml index da41ae46d5..9edf011170 100644 --- a/bootstrapper-maven-plugin/pom.xml +++ b/bootstrapper-maven-plugin/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT bootstrapper @@ -32,7 +32,7 @@ 3.15.2 - 3.9.16 + 3.9.15 3.1.0 3.15.2 diff --git a/caffeine-bounded-cache-support/pom.xml b/caffeine-bounded-cache-support/pom.xml index 356fabebd0..be70ab9a2e 100644 --- a/caffeine-bounded-cache-support/pom.xml +++ b/caffeine-bounded-cache-support/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT caffeine-bounded-cache-support diff --git a/micrometer-support/pom.xml b/micrometer-support/pom.xml index 42e94e5cb8..ae3c4d0be1 100644 --- a/micrometer-support/pom.xml +++ b/micrometer-support/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT micrometer-support diff --git a/operator-framework-bom/pom.xml b/operator-framework-bom/pom.xml index c2b97dfba3..30fb73bfa3 100644 --- a/operator-framework-bom/pom.xml +++ b/operator-framework-bom/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk operator-framework-bom - 5.3.6-SNAPSHOT + 999-SNAPSHOT pom Operator SDK - Bill of Materials Java SDK for implementing Kubernetes operators diff --git a/operator-framework-core/pom.xml b/operator-framework-core/pom.xml index 3127d2e9fb..2356433ca9 100644 --- a/operator-framework-core/pom.xml +++ b/operator-framework-core/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT ../pom.xml diff --git a/operator-framework-junit/pom.xml b/operator-framework-junit/pom.xml index 10923adf65..aa18d5c778 100644 --- a/operator-framework-junit/pom.xml +++ b/operator-framework-junit/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT operator-framework-junit diff --git a/operator-framework/pom.xml b/operator-framework/pom.xml index 59abb1a926..f94dfa757d 100644 --- a/operator-framework/pom.xml +++ b/operator-framework/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT operator-framework diff --git a/pom.xml b/pom.xml index 54d1fef54f..8c4f92279f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT pom Operator SDK for Java Java SDK for implementing Kubernetes operators @@ -70,7 +70,7 @@ java-operator-sdk https://sonarcloud.io jdk - 6.1.0 + 6.0.3 7.7.0 2.0.18 2.26.0 @@ -85,7 +85,7 @@ 3.2.4 0.9.14 2.22.0 - 4.17 + 4.16 2.11 3.15.0 diff --git a/sample-operators/controller-namespace-deletion/pom.xml b/sample-operators/controller-namespace-deletion/pom.xml index 430ebe1d46..af4be01972 100644 --- a/sample-operators/controller-namespace-deletion/pom.xml +++ b/sample-operators/controller-namespace-deletion/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-controller-namespace-deletion diff --git a/sample-operators/leader-election/pom.xml b/sample-operators/leader-election/pom.xml index 4354bd3d09..4f896485d1 100644 --- a/sample-operators/leader-election/pom.xml +++ b/sample-operators/leader-election/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-leader-election diff --git a/sample-operators/mysql-schema/pom.xml b/sample-operators/mysql-schema/pom.xml index 63d57a215b..d2872c921a 100644 --- a/sample-operators/mysql-schema/pom.xml +++ b/sample-operators/mysql-schema/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-mysql-schema-operator diff --git a/sample-operators/operations/pom.xml b/sample-operators/operations/pom.xml index 4c78a9614b..1786cf39d0 100644 --- a/sample-operators/operations/pom.xml +++ b/sample-operators/operations/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-operations @@ -106,11 +106,6 @@ operations-operator - - - -Dlog4j.configurationFile=/config/log4j2.xml - - diff --git a/sample-operators/pom.xml b/sample-operators/pom.xml index e7aca4b8db..9313095584 100644 --- a/sample-operators/pom.xml +++ b/sample-operators/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-operators diff --git a/sample-operators/tomcat-operator/pom.xml b/sample-operators/tomcat-operator/pom.xml index 9aae55ef26..ea964a2b07 100644 --- a/sample-operators/tomcat-operator/pom.xml +++ b/sample-operators/tomcat-operator/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-tomcat-operator diff --git a/sample-operators/webpage/pom.xml b/sample-operators/webpage/pom.xml index 3b8ce0ac49..d50e5ef03c 100644 --- a/sample-operators/webpage/pom.xml +++ b/sample-operators/webpage/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk sample-operators - 5.3.6-SNAPSHOT + 999-SNAPSHOT sample-webpage-operator diff --git a/test-index-processor/pom.xml b/test-index-processor/pom.xml index 11cd3b476b..2ae7c5f454 100644 --- a/test-index-processor/pom.xml +++ b/test-index-processor/pom.xml @@ -22,7 +22,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT test-index-processor From c39526296c5b3dab193d8a632ea3ab80443856c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 30 Mar 2026 13:55:55 +0200 Subject: [PATCH 2/8] fix: set migration module version to correct one (#3263) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- migration/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/pom.xml b/migration/pom.xml index 5e32ae2cd9..2afc10ea46 100644 --- a/migration/pom.xml +++ b/migration/pom.xml @@ -21,7 +21,7 @@ io.javaoperatorsdk java-operator-sdk - 5.3.6-SNAPSHOT + 999-SNAPSHOT migration From 881fb19ae7cbfdce53a7ae8ed124de3aefa8fd43 Mon Sep 17 00:00:00 2001 From: Antonio <122279781+afalhambra-hivemq@users.noreply.github.com> Date: Mon, 25 May 2026 19:44:36 +0200 Subject: [PATCH 3/8] feat(core): add by-name secondary resource lookup on Context (#3373) --- .../operator/api/reconciler/Context.java | 83 ++++++ .../api/reconciler/DefaultContext.java | 69 ++++- .../api/reconciler/DefaultContextTest.java | 236 ++++++++++++++++++ 3 files changed, 377 insertions(+), 11 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index 2df74d4298..75480dedb5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -114,6 +114,89 @@ default Stream getSecondaryResourcesAsStream(Class expectedType) { Optional getSecondaryResource(Class expectedType, String eventSourceName); + /** + * Retrieves a specific secondary resource by name and namespace from the event source identified + * by the given name. + * + *

This is a typed convenience over manually retrieving the {@link + * io.javaoperatorsdk.operator.processing.event.source.EventSource} and calling its cache. When + * the underlying event source implements {@link + * io.javaoperatorsdk.operator.processing.event.source.Cache}, the lookup is a direct cache lookup + * and read-cache-after-write consistent. + * + *

{@code eventSourceName} may be {@code null}. When {@code null} and {@code expectedType} is + * part of a managed workflow whose activation condition may not have registered the event source, + * an empty {@link Optional} is returned instead of throwing {@link + * io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException}. + * + * @param expectedType the class representing the type of secondary resource to retrieve + * @param eventSourceName the name of the event source to look in (may be {@code null}) + * @param name the name of the secondary resource + * @param namespace the namespace of the secondary resource (may be {@code null} for + * cluster-scoped resources) + * @param the type of secondary resource to retrieve + * @return an {@link Optional} containing the matching secondary resource, or {@link + * Optional#empty()} if none matches + * @throws io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException if no event + * source is registered for the given type and name (and no workflow activation condition + * accounts for it) + * @since 5.4.0 + */ + Optional getSecondaryResource( + Class expectedType, String eventSourceName, String name, String namespace); + + /** + * Convenience overload of {@link #getSecondaryResource(Class, String, String, String)} that uses + * the primary resource's namespace. + * + *

If the primary resource is cluster-scoped (no namespace), the lookup is performed against + * the cluster scope. To target a specific namespace from a cluster-scoped primary, use {@link + * #getSecondaryResource(Class, String, String, String)} directly. + * + *

{@code eventSourceName} may be {@code null} with the same semantics as in {@link + * #getSecondaryResource(Class, String, String, String)}. + * + * @param expectedType the class representing the type of secondary resource to retrieve + * @param eventSourceName the name of the event source to look in (may be {@code null}) + * @param name the name of the secondary resource (namespace inferred from the primary) + * @param the type of secondary resource to retrieve + * @return an {@link Optional} containing the matching secondary resource, or {@link + * Optional#empty()} if none matches + * @since 5.4.0 + */ + default Optional getSecondaryResource( + Class expectedType, String eventSourceName, String name) { + return getSecondaryResource( + expectedType, eventSourceName, name, getPrimaryResource().getMetadata().getNamespace()); + } + + /** + * Retrieves a {@link Stream} of the secondary resources of the specified type from the event + * source identified by the given name. Useful when several event sources are registered for the + * same type and you need to scope retrieval to one of them, or when you want to apply a custom + * filter at the call site. + * + *

When the underlying event source implements {@link ResourceCache}, the stream is + * read-cache-after-write consistent. + * + *

{@code eventSourceName} may be {@code null} with the same semantics as in {@link + * #getSecondaryResource(Class, String, String, String)}: when {@code null} and {@code + * expectedType} is part of a managed workflow whose activation condition may not have registered + * the event source, an empty {@link Stream} is returned instead of throwing {@link + * io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException}. + * + * @param expectedType the class representing the type of secondary resources to retrieve + * @param eventSourceName the name of the event source to look in (may be {@code null}) + * @param the type of secondary resources to retrieve + * @return a {@link Stream} of secondary resources of the specified type + * @throws io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException if no event + * source is registered for the given type and name (and no workflow activation condition + * accounts for it) + * @since 5.4.0 + */ + Stream getSecondaryResourcesAsStream( + Class expectedType, String eventSourceName); + ControllerConfiguration

getControllerConfiguration(); /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index ac5a7b41b9..ea7bd21874 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -36,6 +36,7 @@ import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException; import io.javaoperatorsdk.operator.processing.event.ResourceID; +import io.javaoperatorsdk.operator.processing.event.source.Cache; public class DefaultContext

implements Context

{ private RetryInfo retryInfo; @@ -95,6 +96,20 @@ public Stream getSecondaryResourcesAsStream(Class expectedType, boolea } } + /** + * Whether a missing event source for the given type is the expected case, in which case callers + * should return an empty result instead of propagating the {@link + * NoEventSourceForClassException}. + * + *

If a workflow has an activation condition there can be event sources which are only + * registered if the activation condition holds, but to provide a consistent API we return an + * empty result instead of throwing an exception. Note that not only the resource which has an + * activation condition might not be registered but dependents which depend on it. + */ + private boolean isMissingEventSourceExpected(String eventSourceName, Class expectedType) { + return eventSourceName == null && controller.workflowContainsDependentForType(expectedType); + } + private Map deduplicatedMap(Stream stream) { return stream.collect( Collectors.toUnmodifiableMap( @@ -120,19 +135,51 @@ public Optional getSecondaryResource(Class expectedType, String eventS .getEventSourceFor(expectedType, eventSourceName) .getSecondaryResource(primaryResource); } catch (NoEventSourceForClassException e) { - /* - * If a workflow has an activation condition there can be event sources which are only - * registered if the activation condition holds, but to provide a consistent API we return an - * Optional instead of throwing an exception. - * - * Note that not only the resource which has an activation condition might not be registered - * but dependents which depend on it. - */ - if (eventSourceName == null && controller.workflowContainsDependentForType(expectedType)) { + if (isMissingEventSourceExpected(eventSourceName, expectedType)) { return Optional.empty(); - } else { - throw e; } + throw e; + } + } + + @Override + public Optional getSecondaryResource( + Class expectedType, String eventSourceName, String name, String namespace) { + try { + final var eventSource = + controller.getEventSourceManager().getEventSourceFor(expectedType, eventSourceName); + final var resourceID = new ResourceID(name, namespace); + if (eventSource instanceof Cache cache) { + return cache.get(resourceID).map(expectedType::cast); + } + return eventSource.getSecondaryResources(primaryResource).stream() + .filter(r -> ResourceID.fromResource(r).equals(resourceID)) + .findFirst(); + } catch (NoEventSourceForClassException e) { + if (isMissingEventSourceExpected(eventSourceName, expectedType)) { + return Optional.empty(); + } + throw e; + } + } + + @Override + public Stream getSecondaryResourcesAsStream( + Class expectedType, String eventSourceName) { + try { + final var eventSource = + controller.getEventSourceManager().getEventSourceFor(expectedType, eventSourceName); + if (eventSource instanceof ResourceCache resourceCache) { + final var ns = primaryResource.getMetadata().getNamespace(); + final Stream stream = ns == null ? resourceCache.list() : resourceCache.list(ns); + return stream.map(expectedType::cast); + } + return eventSource.getSecondaryResources(primaryResource).stream(); + } catch (NoEventSourceForClassException e) { + if (isMissingEventSourceExpected(eventSourceName, expectedType)) { + return Stream.empty(); + } + throw e; } } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContextTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContextTest.java index 4df8df385b..7b9658f98d 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContextTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContextTest.java @@ -16,26 +16,34 @@ package io.javaoperatorsdk.operator.api.reconciler; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodBuilder; import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.SecretBuilder; import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.event.EventSourceManager; import io.javaoperatorsdk.operator.processing.event.NoEventSourceForClassException; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.EventSource; +import io.javaoperatorsdk.operator.processing.event.source.informer.ManagedInformerEventSource; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class DefaultContextTest { @@ -63,6 +71,234 @@ void getSecondaryResourceReturnsEmptyOptionalOnNonActivatedDRType() { assertThat(res).isEmpty(); } + @Test + void getSecondaryResourceByNameAndNamespaceReturnsFromCacheFastPath() { + final var cm = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-foo") + .withNamespace("ns") + .endMetadata() + .build(); + + final ManagedInformerEventSource cachingEventSource = mock(); + when(cachingEventSource.get(new ResourceID("cm-foo", "ns"))).thenReturn(Optional.of(cm)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")).thenReturn(cachingEventSource); + + final var res = context.getSecondaryResource(ConfigMap.class, "es-name", "cm-foo", "ns"); + + assertThat(res).contains(cm); + verify(cachingEventSource).get(new ResourceID("cm-foo", "ns")); + } + + @Test + void getSecondaryResourceByNameAndNamespaceReturnsEmptyOnCacheMiss() { + final ManagedInformerEventSource cachingEventSource = mock(); + when(cachingEventSource.get(new ResourceID("missing", "ns"))).thenReturn(Optional.empty()); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")).thenReturn(cachingEventSource); + + assertThat(context.getSecondaryResource(ConfigMap.class, "es-name", "missing", "ns")).isEmpty(); + } + + @Test + void getSecondaryResourceByNameAndNamespaceFallsBackToGetSecondaryResources() { + final var match = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-foo") + .withNamespace("ns") + .endMetadata() + .build(); + final var other = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-bar") + .withNamespace("ns") + .endMetadata() + .build(); + + final EventSource nonCachingEventSource = mock(); + when(nonCachingEventSource.getSecondaryResources(any())).thenReturn(Set.of(match, other)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenReturn(nonCachingEventSource); + + final var res = context.getSecondaryResource(ConfigMap.class, "es-name", "cm-foo", "ns"); + + assertThat(res).contains(match); + } + + @Test + void getSecondaryResourceByNameAndNamespaceFallbackReturnsEmptyWhenNoMatch() { + final var other = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-other") + .withNamespace("ns") + .endMetadata() + .build(); + + final EventSource nonCachingEventSource = mock(); + when(nonCachingEventSource.getSecondaryResources(any())).thenReturn(Set.of(other)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenReturn(nonCachingEventSource); + + assertThat(context.getSecondaryResource(ConfigMap.class, "es-name", "missing", "ns")).isEmpty(); + } + + @Test + void getSecondaryResourceByNameAndNamespaceRethrowsWhenNoEventSourceAndNotWorkflowManaged() { + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenThrow(new NoEventSourceForClassException(ConfigMap.class)); + + assertThatThrownBy( + () -> context.getSecondaryResource(ConfigMap.class, "es-name", "cm-foo", "ns")) + .isInstanceOf(NoEventSourceForClassException.class); + } + + @Test + void getSecondaryResourceByNameAndNamespaceReturnsEmptyWhenNoEventSourceButWorkflowManaged() { + when(mockManager.getEventSourceFor(ConfigMap.class, null)) + .thenThrow(new NoEventSourceForClassException(ConfigMap.class)); + when(mockController.workflowContainsDependentForType(ConfigMap.class)).thenReturn(true); + + final var res = context.getSecondaryResource(ConfigMap.class, null, "cm-foo", "ns"); + + assertThat(res).isEmpty(); + } + + @Test + void getSecondaryResourceByNameUsesPrimaryNamespace() { + final var primaryNamespace = "primary-ns"; + final var namespacedPrimary = + new SecretBuilder() + .withNewMetadata() + .withName("primary") + .withNamespace(primaryNamespace) + .endMetadata() + .build(); + final DefaultContext namespacedContext = + new DefaultContext<>(null, mockController, namespacedPrimary, false, false); + + final var cm = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-foo") + .withNamespace(primaryNamespace) + .endMetadata() + .build(); + + final ManagedInformerEventSource cachingEventSource = mock(); + when(cachingEventSource.get(new ResourceID("cm-foo", primaryNamespace))) + .thenReturn(Optional.of(cm)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")).thenReturn(cachingEventSource); + + final var res = namespacedContext.getSecondaryResource(ConfigMap.class, "es-name", "cm-foo"); + + assertThat(res).contains(cm); + } + + @Test + void getSecondaryResourcesAsStreamByEventSourceUsesResourceCacheFastPath() { + final var primaryNamespace = "primary-ns"; + final var namespacedPrimary = + new SecretBuilder() + .withNewMetadata() + .withName("primary") + .withNamespace(primaryNamespace) + .endMetadata() + .build(); + final DefaultContext namespacedContext = + new DefaultContext<>(null, mockController, namespacedPrimary, false, false); + + final var cm1 = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-1") + .withNamespace(primaryNamespace) + .endMetadata() + .build(); + final var cm2 = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-2") + .withNamespace(primaryNamespace) + .endMetadata() + .build(); + + final ManagedInformerEventSource resourceCacheEventSource = mock(); + when(resourceCacheEventSource.list(primaryNamespace)).thenReturn(Stream.of(cm1, cm2)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenReturn(resourceCacheEventSource); + + final var res = + namespacedContext.getSecondaryResourcesAsStream(ConfigMap.class, "es-name").toList(); + + assertThat(res).containsExactlyInAnyOrder(cm1, cm2); + verify(resourceCacheEventSource).list(primaryNamespace); + } + + @Test + void getSecondaryResourcesAsStreamByEventSourceFastPathOnClusterScopedPrimary() { + // cluster-scoped primary: has metadata but no namespace set. + final var clusterScopedPrimary = + new SecretBuilder().withNewMetadata().withName("primary").endMetadata().build(); + final DefaultContext clusterScopedContext = + new DefaultContext<>(null, mockController, clusterScopedPrimary, false, false); + + final var cm1 = new ConfigMapBuilder().withNewMetadata().withName("cm-1").endMetadata().build(); + + final ManagedInformerEventSource resourceCacheEventSource = mock(); + when(resourceCacheEventSource.list()).thenReturn(Stream.of(cm1)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenReturn(resourceCacheEventSource); + + final var res = + clusterScopedContext.getSecondaryResourcesAsStream(ConfigMap.class, "es-name").toList(); + + assertThat(res).containsExactly(cm1); + verify(resourceCacheEventSource).list(); + verify(resourceCacheEventSource, never()).list(any(String.class)); + } + + @Test + void getSecondaryResourcesAsStreamByEventSourceFallsBackToGetSecondaryResources() { + final var cm1 = + new ConfigMapBuilder() + .withNewMetadata() + .withName("cm-1") + .withNamespace("ns") + .endMetadata() + .build(); + + final EventSource nonCacheEventSource = mock(); + when(nonCacheEventSource.getSecondaryResources(any())).thenReturn(Set.of(cm1)); + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")).thenReturn(nonCacheEventSource); + + final var res = context.getSecondaryResourcesAsStream(ConfigMap.class, "es-name").toList(); + + assertThat(res).containsExactly(cm1); + } + + @Test + void getSecondaryResourcesAsStreamByEventSourceRethrowsWhenNotWorkflowManaged() { + when(mockManager.getEventSourceFor(ConfigMap.class, "es-name")) + .thenThrow(new NoEventSourceForClassException(ConfigMap.class)); + + assertThatThrownBy(() -> context.getSecondaryResourcesAsStream(ConfigMap.class, "es-name")) + .isInstanceOf(NoEventSourceForClassException.class); + } + + @Test + void getSecondaryResourcesAsStreamByEventSourceReturnsEmptyWhenWorkflowManaged() { + when(mockManager.getEventSourceFor(ConfigMap.class, null)) + .thenThrow(new NoEventSourceForClassException(ConfigMap.class)); + when(mockController.workflowContainsDependentForType(ConfigMap.class)).thenReturn(true); + + final var res = context.getSecondaryResourcesAsStream(ConfigMap.class, null).toList(); + + assertThat(res).isEmpty(); + } + @Test void setRetryInfo() { RetryInfo retryInfo = mock(); From 41be22b6cd04c840a4b42754d5c49bceec6b159d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Tue, 26 May 2026 10:34:02 +0200 Subject: [PATCH 4/8] improve: getSecondaryResourcesAsStream(expectedType,eventSourceName) does not have to be Kubernetes resources (#3377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../io/javaoperatorsdk/operator/api/reconciler/Context.java | 3 +-- .../operator/api/reconciler/DefaultContext.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index 75480dedb5..75d12eb1ad 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -194,8 +194,7 @@ default Optional getSecondaryResource( * accounts for it) * @since 5.4.0 */ - Stream getSecondaryResourcesAsStream( - Class expectedType, String eventSourceName); + Stream getSecondaryResourcesAsStream(Class expectedType, String eventSourceName); ControllerConfiguration

getControllerConfiguration(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index ea7bd21874..2d9a22b6fa 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -164,7 +164,7 @@ public Optional getSecondaryResource( } @Override - public Stream getSecondaryResourcesAsStream( + public Stream getSecondaryResourcesAsStream( Class expectedType, String eventSourceName) { try { final var eventSource = From 3a58e7a11a26d31285b20cfc3bf4c093baafb24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 28 May 2026 12:07:16 +0200 Subject: [PATCH 5/8] improve: reconciliation counts as retry attempt only if close to retry deadline (#3380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../documentation/error-handling-retries.md | 3 + .../processing/event/EventProcessor.java | 16 +++ .../retry/GenericRetryExecution.java | 15 +++ .../processing/retry/RetryExecution.java | 12 ++ .../processing/event/EventProcessorTest.java | 92 +++++++++++++++ .../retry/GenericRetryExecutionTest.java | 66 +++++++++-- ...etryIntervalHonoredOnFrequentEventsIT.java | 107 ++++++++++++++++++ .../retry/RetryTestCustomReconciler.java | 11 ++ 8 files changed, 313 insertions(+), 9 deletions(-) create mode 100644 operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryIntervalHonoredOnFrequentEventsIT.java diff --git a/docs/content/en/docs/documentation/error-handling-retries.md b/docs/content/en/docs/documentation/error-handling-retries.md index eeecf54751..7bd4ad2e22 100644 --- a/docs/content/en/docs/documentation/error-handling-retries.md +++ b/docs/content/en/docs/documentation/error-handling-retries.md @@ -135,6 +135,9 @@ these features: 2. In case an exception is thrown, a retry is initiated. However, if an event is received meanwhile, it will be reconciled instantly, and this execution won't count as a retry attempt. + If that event-triggered reconciliation also fails inside the current retry window, the + existing retry deadline is preserved rather than reset — the failure does not advance the + retry counter unless the original deadline is imminent. 3. If the retry limit is reached (so no more automatic retry would happen), but a new event received, the reconciliation will still happen, but won't reset the retry, and will still be marked as the last attempt in the retry info. The point (1) still holds - thus successful reconciliation will reset the retry - but no retry will happen in case of an error. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java index 5af48a1694..c8322e47e5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java @@ -49,6 +49,13 @@ public class EventProcessor

implements EventHandler, Life private static final Logger log = LoggerFactory.getLogger(EventProcessor.class); private static final long MINIMAL_RATE_LIMIT_RESCHEDULE_DURATION = 50; + /** + * Threshold below which an event-driven failed reconciliation that lands inside the current retry + * window is allowed to consume a retry attempt (i.e. advance the retry counter). Above this + * threshold the existing retry deadline is preserved instead. + */ + private static final long RETRY_DEADLINE_PRESERVE_THRESHOLD_MILLIS = 5_000; + private volatile boolean running; private final ControllerConfiguration controllerConfiguration; private final ReconciliationDispatcher

reconciliationDispatcher; @@ -377,6 +384,15 @@ private void handleRetryOnException(ExecutionScope

executionScope, Exception submitReconciliationExecution(state); return; } + Optional remaining = state.getRetry().remainingDurationUntilNextRetry(); + if (remaining.isPresent() + && remaining.get().toMillis() > RETRY_DEADLINE_PRESERVE_THRESHOLD_MILLIS) { + log.debug( + "Preserving existing retry deadline; remaining: {} ms. Not consuming a retry attempt.", + remaining.get().toMillis()); + retryEventSource().scheduleOnce(resourceID, remaining.get().toMillis()); + return; + } Optional nextDelay = state.getRetry().nextDelay(); nextDelay.ifPresentOrElse( delay -> { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java index 4bdce57a77..fadc022de7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java @@ -15,6 +15,7 @@ */ package io.javaoperatorsdk.operator.processing.retry; +import java.time.Duration; import java.util.Optional; public class GenericRetryExecution implements RetryExecution { @@ -23,6 +24,7 @@ public class GenericRetryExecution implements RetryExecution { private int lastAttemptIndex = 0; private long currentInterval; + private Long lastNextDelayCallEpochMillis; public GenericRetryExecution(GenericRetry genericRetry) { this.genericRetry = genericRetry; @@ -40,6 +42,7 @@ public Optional nextDelay() { } } lastAttemptIndex++; + lastNextDelayCallEpochMillis = System.currentTimeMillis(); return Optional.of(currentInterval); } @@ -52,4 +55,16 @@ public boolean isLastAttempt() { public int getAttemptCount() { return lastAttemptIndex; } + + @Override + public Optional remainingDurationUntilNextRetry() { + if (lastNextDelayCallEpochMillis == null) { + return Optional.empty(); + } + long remaining = (lastNextDelayCallEpochMillis + currentInterval) - System.currentTimeMillis(); + if (remaining <= 0) { + return Optional.empty(); + } + return Optional.of(Duration.ofMillis(remaining)); + } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java index caf71d7a33..a644a274ba 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java @@ -15,6 +15,7 @@ */ package io.javaoperatorsdk.operator.processing.retry; +import java.time.Duration; import java.util.Optional; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; @@ -25,4 +26,15 @@ public interface RetryExecution extends RetryInfo { * @return the time to wait until the next execution in milliseconds */ Optional nextDelay(); + + /** + * Remaining time of the currently scheduled retry interval, i.e. the time until the previously + * computed retry delay would elapse. Returns an empty {@link Optional} if no retry has been + * scheduled yet (i.e. {@link #nextDelay()} has never been called) or if the deadline has already + * passed. + * + *

Used to decide whether an event-driven failed reconciliation that lands well inside the + * retry window should consume a retry attempt or simply be re-scheduled on the original deadline. + */ + Optional remainingDurationUntilNextRetry(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java index fb8f7c0805..f7864f2f16 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventProcessorTest.java @@ -465,6 +465,98 @@ void schedulesRetryForMarReconciliationIntervalIfRetryExhausted() { verify(retryTimerEventSourceMock, times(1)).scheduleOnce((ResourceID) any(), anyLong()); } + @Test + void preservesRetryDeadlineWhenRemainingDurationAboveThreshold() { + RetryExecution mockRetryExecution = mock(RetryExecution.class); + when(mockRetryExecution.nextDelay()).thenReturn(Optional.of(60_000L)); + when(mockRetryExecution.remainingDurationUntilNextRetry()) + .thenReturn(Optional.of(Duration.ofMillis(50_000))); + Retry retry = mock(Retry.class); + when(retry.initExecution()).thenReturn(mockRetryExecution); + eventProcessorWithRetry = + spy( + new EventProcessor( + controllerConfiguration(retry, LinearRateLimiter.deactivatedRateLimiter()), + reconciliationDispatcherMock, + eventSourceManagerMock, + metricsMock)); + eventProcessorWithRetry.start(); + when(eventProcessorWithRetry.retryEventSource()).thenReturn(retryTimerEventSourceMock); + + TestCustomResource customResource = testCustomResource(); + ExecutionScope executionScope = + new ExecutionScope(null, null, false, false).setResource(customResource); + PostExecutionControl postExecutionControl = + PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); + + eventProcessorWithRetry.eventProcessingFinished(executionScope, postExecutionControl); + + verify(mockRetryExecution, never()).nextDelay(); + verify(retryTimerEventSourceMock, times(1)) + .scheduleOnce(eq(ResourceID.fromResource(customResource)), eq(50_000L)); + } + + @Test + void consumesRetryAttemptWhenRemainingDurationAtOrBelowThreshold() { + RetryExecution mockRetryExecution = mock(RetryExecution.class); + when(mockRetryExecution.nextDelay()).thenReturn(Optional.of(60_000L)); + when(mockRetryExecution.remainingDurationUntilNextRetry()) + .thenReturn(Optional.of(Duration.ofMillis(2_000))); + Retry retry = mock(Retry.class); + when(retry.initExecution()).thenReturn(mockRetryExecution); + eventProcessorWithRetry = + spy( + new EventProcessor( + controllerConfiguration(retry, LinearRateLimiter.deactivatedRateLimiter()), + reconciliationDispatcherMock, + eventSourceManagerMock, + metricsMock)); + eventProcessorWithRetry.start(); + when(eventProcessorWithRetry.retryEventSource()).thenReturn(retryTimerEventSourceMock); + + TestCustomResource customResource = testCustomResource(); + ExecutionScope executionScope = + new ExecutionScope(null, null, false, false).setResource(customResource); + PostExecutionControl postExecutionControl = + PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); + + eventProcessorWithRetry.eventProcessingFinished(executionScope, postExecutionControl); + + verify(mockRetryExecution, times(1)).nextDelay(); + verify(retryTimerEventSourceMock, times(1)) + .scheduleOnce(eq(ResourceID.fromResource(customResource)), eq(60_000L)); + } + + @Test + void firstFailureSchedulesUsingNextDelayWhenNoRemainingDuration() { + RetryExecution mockRetryExecution = mock(RetryExecution.class); + when(mockRetryExecution.nextDelay()).thenReturn(Optional.of(60_000L)); + when(mockRetryExecution.remainingDurationUntilNextRetry()).thenReturn(Optional.empty()); + Retry retry = mock(Retry.class); + when(retry.initExecution()).thenReturn(mockRetryExecution); + eventProcessorWithRetry = + spy( + new EventProcessor( + controllerConfiguration(retry, LinearRateLimiter.deactivatedRateLimiter()), + reconciliationDispatcherMock, + eventSourceManagerMock, + metricsMock)); + eventProcessorWithRetry.start(); + when(eventProcessorWithRetry.retryEventSource()).thenReturn(retryTimerEventSourceMock); + + TestCustomResource customResource = testCustomResource(); + ExecutionScope executionScope = + new ExecutionScope(null, null, false, false).setResource(customResource); + PostExecutionControl postExecutionControl = + PostExecutionControl.exceptionDuringExecution(new RuntimeException("test")); + + eventProcessorWithRetry.eventProcessingFinished(executionScope, postExecutionControl); + + verify(mockRetryExecution, times(1)).nextDelay(); + verify(retryTimerEventSourceMock, times(1)) + .scheduleOnce(eq(ResourceID.fromResource(customResource)), eq(60_000L)); + } + @Test void executionOfReconciliationShouldNotStartIfProcessorStopped() throws InterruptedException { when(reconciliationDispatcherMock.handleExecution(any())) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecutionTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecutionTest.java index 8f5a446788..8d7ec55e37 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecutionTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecutionTest.java @@ -21,10 +21,10 @@ import static org.assertj.core.api.Assertions.assertThat; -public class GenericRetryExecutionTest { +class GenericRetryExecutionTest { @Test - public void noNextDelayIfMaxAttemptLimitReached() { + void noNextDelayIfMaxAttemptLimitReached() { RetryExecution retryExecution = GenericRetry.defaultLimitedExponentialRetry().setMaxAttempts(3).initExecution(); Optional res = callNextDelayNTimes(retryExecution, 2); @@ -35,7 +35,7 @@ public void noNextDelayIfMaxAttemptLimitReached() { } @Test - public void canLimitMaxIntervalLength() { + void canLimitMaxIntervalLength() { RetryExecution retryExecution = GenericRetry.defaultLimitedExponentialRetry() .setInitialInterval(2000) @@ -49,13 +49,13 @@ public void canLimitMaxIntervalLength() { } @Test - public void supportsNoRetry() { + void supportsNoRetry() { RetryExecution retryExecution = GenericRetry.noRetry().initExecution(); assertThat(retryExecution.nextDelay()).isEmpty(); } @Test - public void supportsIsLastExecution() { + void supportsIsLastExecution() { GenericRetryExecution execution = new GenericRetry().setMaxAttempts(2).initExecution(); assertThat(execution.isLastAttempt()).isFalse(); @@ -65,7 +65,7 @@ public void supportsIsLastExecution() { } @Test - public void returnAttemptIndex() { + void returnAttemptIndex() { RetryExecution retryExecution = GenericRetry.defaultLimitedExponentialRetry().initExecution(); assertThat(retryExecution.getAttemptCount()).isEqualTo(0); @@ -73,11 +73,59 @@ public void returnAttemptIndex() { assertThat(retryExecution.getAttemptCount()).isEqualTo(1); } - private RetryExecution getDefaultRetryExecution() { - return GenericRetry.defaultLimitedExponentialRetry().initExecution(); + @Test + void remainingDurationEmptyBeforeFirstNextDelay() { + RetryExecution retryExecution = GenericRetry.defaultLimitedExponentialRetry().initExecution(); + + assertThat(retryExecution.remainingDurationUntilNextRetry()).isEmpty(); + } + + @Test + void remainingDurationPresentAfterNextDelay() { + long interval = 60_000L; + RetryExecution retryExecution = new GenericRetry().setInitialInterval(interval).initExecution(); + + retryExecution.nextDelay(); + + Optional remaining = retryExecution.remainingDurationUntilNextRetry(); + assertThat(remaining).isPresent(); + assertThat(remaining.get().toMillis()).isPositive().isLessThanOrEqualTo(interval); + } + + @Test + void remainingDurationEmptyAfterIntervalElapsed() throws InterruptedException { + RetryExecution retryExecution = new GenericRetry().setInitialInterval(20).initExecution(); + + retryExecution.nextDelay(); + Thread.sleep(60); + + assertThat(retryExecution.remainingDurationUntilNextRetry()).isEmpty(); + } + + @Test + void remainingDurationReflectsUpdatedIntervalAfterSubsequentNextDelay() { + long initialInterval = 1000L; + double multiplier = 2.0; + RetryExecution retryExecution = + new GenericRetry() + .setInitialInterval(initialInterval) + .setIntervalMultiplier(multiplier) + .initExecution(); + + // first two calls keep the initial interval (multiplier only kicks in after attempt 1) + retryExecution.nextDelay(); + retryExecution.nextDelay(); + // third call doubles the interval to 2000ms + retryExecution.nextDelay(); + + Optional remaining = retryExecution.remainingDurationUntilNextRetry(); + assertThat(remaining).isPresent(); + assertThat(remaining.get().toMillis()) + .isPositive() + .isLessThanOrEqualTo((long) (initialInterval * multiplier)); } - public Optional callNextDelayNTimes(RetryExecution retryExecution, int n) { + Optional callNextDelayNTimes(RetryExecution retryExecution, int n) { for (int i = 0; i < n; i++) { retryExecution.nextDelay(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryIntervalHonoredOnFrequentEventsIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryIntervalHonoredOnFrequentEventsIT.java new file mode 100644 index 0000000000..df525e8056 --- /dev/null +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryIntervalHonoredOnFrequentEventsIT.java @@ -0,0 +1,107 @@ +/* + * Copyright Java Operator SDK Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.javaoperatorsdk.operator.baseapi.retry; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.javaoperatorsdk.annotation.Sample; +import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension; +import io.javaoperatorsdk.operator.processing.retry.GenericRetry; + +import static io.javaoperatorsdk.operator.baseapi.retry.RetryIT.createTestCustomResource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +@Sample( + tldr = "Retry Interval Honored Despite Frequent Reconciliation Triggers", + description = + """ + Verifies that with a low max attempts (3) and a high retry interval (1 minute), \ + reconciliations triggered by external events (e.g. resource updates) during the retry \ + window do not consume retry attempts. The retry counter should only advance when the \ + scheduled retry deadline is approached, so the configured interval is honored. + """) +class RetryIntervalHonoredOnFrequentEventsIT { + + private static final Logger log = + LoggerFactory.getLogger(RetryIntervalHonoredOnFrequentEventsIT.class); + + public static final int MAX_RETRY_ATTEMPTS = 3; + public static final int RETRY_INTERVAL_MILLIS = 60_000; + public static final int ALL_EXECUTIONS_TO_FAIL = 99; + public static final int NUMBER_OF_UPDATES = 5; + + RetryTestCustomReconciler reconciler = new RetryTestCustomReconciler(ALL_EXECUTIONS_TO_FAIL); + + @RegisterExtension + LocallyRunOperatorExtension operator = + LocallyRunOperatorExtension.builder() + .withReconciler( + reconciler, + new GenericRetry() + .setInitialInterval(RETRY_INTERVAL_MILLIS) + .withLinearRetry() + .setMaxAttempts(MAX_RETRY_ATTEMPTS)) + .build(); + + @Test + void frequentEventsDuringRetryWindowDoNotExhaustRetryCounter() { + RetryTestCustomResource resource = createTestCustomResource("frequent-events"); + var created = operator.create(resource); + + // Wait until the initial reconciliation has been executed and failed; the retry timer is now + // armed for RETRY_INTERVAL_MILLIS in the future, retry counter is at 1. + await() + .pollInterval(Duration.ofMillis(50)) + .atMost(5, TimeUnit.SECONDS) + .untilAsserted( + () -> assertThat(reconciler.getNumberOfExecutions()).isGreaterThanOrEqualTo(1)); + + // Trigger several updates spaced apart so each results in its own reconciliation cycle. Each + // failed reconciliation lands well inside the 1 minute retry window, so the retry counter + // must NOT advance — only the original retry deadline matters. + IntStream.rangeClosed(1, NUMBER_OF_UPDATES) + .forEach( + i -> { + log.debug("replacing resource, iteration: {}", i); + var latest = + operator.get(RetryTestCustomResource.class, created.getMetadata().getName()); + latest.getSpec().setValue("update-" + i); + operator.replace(latest); + int expectedExecutions = i + 1; + await() + .pollInterval(Duration.ofMillis(50)) + .atMost(5, TimeUnit.SECONDS) + .untilAsserted( + () -> + assertThat(reconciler.getNumberOfExecutions()) + .isGreaterThanOrEqualTo(expectedExecutions)); + }); + + // Reconciliations did happen for every event (so events are not lost) but the retry counter + // observed inside the reconciler never went past 1: the configured 1 minute interval is + // honored even under a steady stream of external events. + assertThat(reconciler.getNumberOfExecutions()).isGreaterThanOrEqualTo(NUMBER_OF_UPDATES + 1); + assertThat(reconciler.getMaxObservedRetryAttempt()).isEqualTo(1); + } +} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryTestCustomReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryTestCustomReconciler.java index 30a339fc4d..f981b9e1cb 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryTestCustomReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/retry/RetryTestCustomReconciler.java @@ -32,6 +32,7 @@ public class RetryTestCustomReconciler private static final Logger log = LoggerFactory.getLogger(RetryTestCustomReconciler.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); + private final AtomicInteger maxObservedRetryAttempt = new AtomicInteger(0); private final AtomicInteger numberOfExecutionFails; @@ -43,6 +44,12 @@ public RetryTestCustomReconciler(int numberOfExecutionFails) { public UpdateControl reconcile( RetryTestCustomResource resource, Context context) { numberOfExecutions.addAndGet(1); + context + .getRetryInfo() + .ifPresent( + info -> + maxObservedRetryAttempt.updateAndGet( + prev -> Math.max(prev, info.getAttemptCount()))); log.info("Value: " + resource.getSpec().getValue()); @@ -70,4 +77,8 @@ private void ensureStatusExists(RetryTestCustomResource resource) { public int getNumberOfExecutions() { return numberOfExecutions.get(); } + + public int getMaxObservedRetryAttempt() { + return maxObservedRetryAttempt.get(); + } } From b19869d93c61ecd92c67429e84674bd9dfbc9ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 18 Jun 2026 15:26:29 +0200 Subject: [PATCH 6/8] feat: marking public APIs with annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../source/cache/CaffeineBoundedCache.java | 3 ++ .../cache/CaffeineBoundedItemStores.java | 2 ++ docs/content/en/docs/documentation/_index.md | 1 + .../micrometer/MicrometerMetrics.java | 2 ++ .../micrometer/MicrometerMetricsV2.java | 2 ++ .../operator/AggregatedOperatorException.java | 3 ++ .../operator/MissingCRDException.java | 3 ++ .../io/javaoperatorsdk/operator/Operator.java | 2 ++ .../operator/OperatorException.java | 3 ++ .../operator/RegisteredController.java | 2 ++ .../javaoperatorsdk/operator/RuntimeInfo.java | 2 ++ .../api/{reconciler => }/Experimental.java | 8 ++--- .../operator/api/Internal.java | 32 +++++++++++++++++++ .../javaoperatorsdk/operator/api/Public.java | 29 +++++++++++++++++ .../config/AbstractConfigurationService.java | 2 ++ .../api/config/AnnotationConfigurable.java | 3 ++ .../api/config/BaseConfigurationService.java | 2 ++ .../operator/api/config/Cloner.java | 2 ++ .../api/config/ConfigurationService.java | 2 ++ .../config/ConfigurationServiceOverrider.java | 2 ++ .../api/config/ControllerConfiguration.java | 2 ++ .../ControllerConfigurationOverrider.java | 2 ++ .../config/DefaultResourceClassResolver.java | 2 ++ .../operator/api/config/Informable.java | 2 ++ .../api/config/InformerStoppedHandler.java | 2 ++ .../config/LeaderElectionConfiguration.java | 2 ++ .../LeaderElectionConfigurationBuilder.java | 2 ++ .../api/config/NamespaceChangeable.java | 3 ++ .../ResolvedControllerConfiguration.java | 2 ++ .../api/config/ResourceClassResolver.java | 2 ++ .../operator/api/config/Version.java | 3 ++ .../dependent/ConfigurationConverter.java | 2 ++ .../api/config/dependent/Configured.java | 3 ++ .../dependent/DependentResourceSpec.java | 2 ++ .../operator/api/config/informer/Field.java | 3 ++ .../api/config/informer/FieldSelector.java | 3 ++ .../config/informer/FieldSelectorBuilder.java | 3 ++ .../api/config/informer/Informer.java | 2 ++ .../informer/InformerConfiguration.java | 2 ++ .../InformerEventSourceConfiguration.java | 2 ++ .../api/config/workflow/WorkflowSpec.java | 2 ++ .../api/monitoring/AggregatedMetrics.java | 2 ++ .../operator/api/monitoring/Metrics.java | 2 ++ .../operator/api/reconciler/BaseControl.java | 3 ++ .../operator/api/reconciler/Cleaner.java | 2 ++ .../operator/api/reconciler/Constants.java | 3 ++ .../operator/api/reconciler/Context.java | 2 ++ .../api/reconciler/ContextInitializer.java | 2 ++ .../reconciler/ControllerConfiguration.java | 2 ++ .../api/reconciler/DefaultContext.java | 5 +++ .../api/reconciler/DeleteControl.java | 3 ++ .../reconciler/ErrorStatusUpdateControl.java | 2 ++ .../api/reconciler/EventSourceContext.java | 2 ++ .../api/reconciler/EventSourceUtils.java | 2 ++ .../operator/api/reconciler/Ignore.java | 3 ++ .../api/reconciler/IndexedResourceCache.java | 2 ++ .../reconciler/MaxReconciliationInterval.java | 3 ++ ...NonComparableResourceVersionException.java | 2 ++ .../PrimaryUpdateAndCacheUtils.java | 2 ++ .../operator/api/reconciler/Reconciler.java | 2 ++ .../api/reconciler/ResourceCache.java | 2 ++ .../api/reconciler/ResourceOperations.java | 2 ++ .../operator/api/reconciler/RetryInfo.java | 3 ++ .../api/reconciler/UpdateControl.java | 2 ++ .../operator/api/reconciler/Workflow.java | 2 ++ .../api/reconciler/dependent/Deleter.java | 2 ++ .../api/reconciler/dependent/Dependent.java | 2 ++ .../dependent/DependentResource.java | 2 ++ .../dependent/DependentResourceFactory.java | 2 ++ .../EventSourceNotFoundException.java | 2 ++ .../dependent/EventSourceReferencer.java | 2 ++ .../dependent/GarbageCollected.java | 2 ++ .../api/reconciler/dependent/NameSetter.java | 3 ++ .../dependent/RecentOperationCacheFiller.java | 2 ++ .../reconciler/dependent/ReconcileResult.java | 2 ++ .../managed/ConfiguredDependentResource.java | 3 ++ ...edWorkflowAndDependentResourceContext.java | 2 ++ .../ManagedDependentResourceException.java | 2 ++ ...edWorkflowAndDependentResourceContext.java | 2 ++ .../operator/health/ControllerHealthInfo.java | 2 ++ .../health/EventSourceHealthIndicator.java | 3 ++ .../health/InformerHealthIndicator.java | 3 ++ ...merWrappingEventSourceHealthIndicator.java | 2 ++ .../operator/health/Status.java | 3 ++ .../operator/processing/GroupVersionKind.java | 2 ++ .../operator/processing/ResourceIDMapper.java | 2 ++ .../processing/ResourceIDProvider.java | 3 ++ .../dependent/AbstractDependentResource.java | 2 ++ ...actEventSourceHolderDependentResource.java | 2 ++ .../AbstractExternalDependentResource.java | 2 ++ .../dependent/BulkDependentResource.java | 2 ++ .../processing/dependent/BulkUpdater.java | 2 ++ .../dependent/CRUDBulkDependentResource.java | 2 ++ .../CRUDExternalBulkDependentResource.java | 2 ++ .../CRUDKubernetesBulkDependentResource.java | 2 ++ .../processing/dependent/Creator.java | 2 ++ .../dependent/DependentResourceException.java | 2 ++ .../DependentResourceWithExplicitState.java | 2 ++ .../ExternalBulkDependentResource.java | 2 ++ .../KubernetesBulkDependentResource.java | 2 ++ .../processing/dependent/Matcher.java | 2 ++ ...ResourceIDMapperBulkDependentResource.java | 2 ++ .../processing/dependent/Updater.java | 2 ++ .../AbstractPollingDependentResource.java | 2 ++ .../PerResourcePollingDependentResource.java | 2 ++ .../external/PollingDependentResource.java | 2 ++ .../kubernetes/BooleanWithUndefined.java | 3 ++ .../CRUDKubernetesDependentResource.java | 2 ++ .../CRUDNoGCKubernetesDependentResource.java | 2 ++ .../GenericKubernetesDependentResource.java | 2 ++ .../GenericKubernetesResourceMatcher.java | 2 ++ .../kubernetes/GenericResourceUpdater.java | 2 ++ .../kubernetes/GroupVersionKindPlural.java | 2 ++ .../kubernetes/KubernetesDependent.java | 2 ++ .../KubernetesDependentResource.java | 2 ++ .../KubernetesDependentResourceConfig.java | 2 ++ ...ernetesDependentResourceConfigBuilder.java | 2 ++ .../kubernetes/ResourceComparators.java | 2 ++ ...BasedGenericKubernetesResourceMatcher.java | 2 ++ .../CRDPresentActivationCondition.java | 2 ++ .../dependent/workflow/Condition.java | 2 ++ .../dependent/workflow/DetailedCondition.java | 2 ++ .../KubernetesResourceDeletedCondition.java | 2 ++ .../dependent/workflow/ManagedWorkflow.java | 2 ++ .../workflow/ManagedWorkflowFactory.java | 2 ++ .../dependent/workflow/Workflow.java | 2 ++ .../dependent/workflow/WorkflowBuilder.java | 2 ++ .../workflow/WorkflowCleanupResult.java | 2 ++ .../workflow/WorkflowReconcileResult.java | 2 ++ .../dependent/workflow/WorkflowResult.java | 2 ++ .../operator/processing/event/Event.java | 3 ++ .../processing/event/EventHandler.java | 2 ++ .../event/EventSourceRetriever.java | 2 ++ .../event/NoEventSourceForClassException.java | 2 ++ .../operator/processing/event/ResourceID.java | 2 ++ .../event/rate/LinearRateLimiter.java | 2 ++ .../processing/event/rate/RateLimited.java | 3 ++ .../processing/event/rate/RateLimiter.java | 2 ++ .../event/source/AbstractEventSource.java | 2 ++ .../processing/event/source/Cache.java | 2 ++ .../processing/event/source/Configurable.java | 3 ++ .../processing/event/source/EventSource.java | 2 ++ .../source/EventSourceStartPriority.java | 3 ++ .../ExternalResourceCachingEventSource.java | 5 +++ .../event/source/IndexerResourceCache.java | 2 ++ .../source/PrimaryToSecondaryMapper.java | 2 ++ .../event/source/ResourceAction.java | 3 ++ .../event/source/ResourceEventAware.java | 2 ++ .../source/SecondaryToPrimaryMapper.java | 2 ++ .../event/source/UpdatableCache.java | 2 ++ .../event/source/cache/BoundedCache.java | 3 ++ .../event/source/cache/BoundedItemStore.java | 2 ++ .../cache/KubernetesResourceFetcher.java | 2 ++ .../event/source/cache/ResourceFetcher.java | 3 ++ .../controller/ResourceDeleteEvent.java | 2 ++ .../source/controller/ResourceEvent.java | 2 ++ .../event/source/filter/GenericFilter.java | 3 ++ .../event/source/filter/OnAddFilter.java | 3 ++ .../event/source/filter/OnDeleteFilter.java | 3 ++ .../event/source/filter/OnUpdateFilter.java | 3 ++ .../inbound/CachingInboundEventSource.java | 4 +++ .../inbound/SimpleInboundEventSource.java | 2 ++ .../source/informer/InformerEventSource.java | 9 ++++++ .../event/source/informer/Mappers.java | 2 ++ .../PerResourcePollingConfiguration.java | 2 ++ ...erResourcePollingConfigurationBuilder.java | 2 ++ .../PerResourcePollingEventSource.java | 6 ++++ .../source/polling/PollingConfiguration.java | 2 ++ .../polling/PollingConfigurationBuilder.java | 2 ++ .../source/polling/PollingEventSource.java | 2 ++ .../event/source/timer/TimerEventSource.java | 2 ++ .../processing/expectation/Expectation.java | 4 +-- .../expectation/ExpectationManager.java | 4 +-- .../PeriodicCleanerExpectationManager.java | 4 +-- .../processing/retry/GenericRetry.java | 2 ++ .../retry/GenericRetryExecution.java | 3 ++ .../processing/retry/GradualRetry.java | 3 ++ .../operator/processing/retry/Retry.java | 3 ++ .../processing/retry/RetryExecution.java | 2 ++ .../junit/AbstractOperatorExtension.java | 2 ++ .../ClusterDeployedOperatorExtension.java | 2 ++ .../junit/DefaultNamespaceNameSupplier.java | 2 ++ .../DefaultPerClassNamespaceNameSupplier.java | 2 ++ .../operator/junit/HasKubernetesClient.java | 2 ++ .../operator/junit/InClusterCurl.java | 2 ++ .../junit/LocallyRunOperatorExtension.java | 2 ++ .../operator/config/loader/ConfigLoader.java | 2 ++ .../config/loader/ConfigProvider.java | 3 ++ .../AggregatePriorityListConfigProvider.java | 2 ++ .../loader/provider/EnvVarConfigProvider.java | 2 ++ .../provider/PropertiesConfigProvider.java | 2 ++ .../loader/provider/YamlConfigProvider.java | 2 ++ .../runtime/DefaultConfigurationService.java | 2 ++ 193 files changed, 502 insertions(+), 10 deletions(-) rename operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/{reconciler => }/Experimental.java (85%) create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Internal.java create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Public.java diff --git a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCache.java b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCache.java index 40c9f8ef08..31cf882273 100644 --- a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCache.java +++ b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedCache.java @@ -15,9 +15,12 @@ */ package io.javaoperatorsdk.operator.processing.event.source.cache; +import io.javaoperatorsdk.operator.api.Public; + import com.github.benmanes.caffeine.cache.Cache; /** Caffeine cache wrapper to be used in a {@link BoundedItemStore} */ +@Public public class CaffeineBoundedCache implements BoundedCache { private final Cache cache; diff --git a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java index a73fb5275a..9544574f85 100644 --- a/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java +++ b/caffeine-bounded-cache-support/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/CaffeineBoundedItemStores.java @@ -19,6 +19,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; @@ -41,6 +42,7 @@ * resources are usually reconciled too, they might need to be fetched and populated to the cache, * and will remain there for some time, for subsequent reconciliations. */ +@Public public class CaffeineBoundedItemStores { private CaffeineBoundedItemStores() {} diff --git a/docs/content/en/docs/documentation/_index.md b/docs/content/en/docs/documentation/_index.md index c0805dfa2f..b57a55d437 100644 --- a/docs/content/en/docs/documentation/_index.md +++ b/docs/content/en/docs/documentation/_index.md @@ -26,5 +26,6 @@ This section contains detailed documentation for all Java Operator SDK features - **[Accessing Resources in Caches](working-with-es-caches/)** - How to access resources in caches - **[Operations](operations/)** - Helm chart, metrics, logging, configurations, leader election - **[Other Features](features/)** - Additional capabilities and integrations +- **[Public API and Versioning](api-stability/)** - What is covered by semantic versioning Each guide includes practical examples and best practices to help you build robust, production-ready operators. diff --git a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java index 60f58b411f..d0763f5f80 100644 --- a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java +++ b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java @@ -24,6 +24,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.monitoring.Metrics; import io.javaoperatorsdk.operator.api.reconciler.Constants; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; @@ -43,6 +44,7 @@ * @deprecated Use {@link MicrometerMetricsV2} instead */ @Deprecated(forRemoval = true) +@Public public class MicrometerMetrics implements Metrics { private static final String PREFIX = "operator.sdk."; diff --git a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetricsV2.java b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetricsV2.java index deb6c98c9e..5d57336458 100644 --- a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetricsV2.java +++ b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetricsV2.java @@ -24,6 +24,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.monitoring.Metrics; import io.javaoperatorsdk.operator.api.reconciler.Constants; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; @@ -39,6 +40,7 @@ /** * @since 5.3.0 */ +@Public public class MicrometerMetricsV2 implements Metrics { private static final String CONTROLLER_NAME = "controller.name"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java index 4ebbfde8c1..6b5e507b09 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/AggregatedOperatorException.java @@ -22,6 +22,9 @@ import java.util.Map.Entry; import java.util.stream.Collectors; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class AggregatedOperatorException extends OperatorException { private final Map causes; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/MissingCRDException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/MissingCRDException.java index 32b98eebe1..4dec33555a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/MissingCRDException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/MissingCRDException.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class MissingCRDException extends OperatorException { private final String crdName; private final String specVersion; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 1e9f927f79..5a1f76c55d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -28,6 +28,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.Version; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; @@ -37,6 +38,7 @@ import io.javaoperatorsdk.operator.processing.LifecycleAware; @SuppressWarnings("rawtypes") +@Public public class Operator implements LifecycleAware { private static final Logger log = LoggerFactory.getLogger(Operator.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/OperatorException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/OperatorException.java index bd243e8539..6b8b0840e6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/OperatorException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/OperatorException.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class OperatorException extends RuntimeException { public OperatorException() {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java index ac5b7cd468..f2026d0cd2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RegisteredController.java @@ -16,10 +16,12 @@ package io.javaoperatorsdk.operator; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.NamespaceChangeable; import io.javaoperatorsdk.operator.health.ControllerHealthInfo; +@Public public interface RegisteredController

extends NamespaceChangeable { ControllerConfiguration

getConfiguration(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java index ba874bdc07..4c5521a118 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/RuntimeInfo.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.health.EventSourceHealthIndicator; import io.javaoperatorsdk.operator.health.InformerWrappingEventSourceHealthIndicator; import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerEventSource; @@ -30,6 +31,7 @@ * check that. */ @SuppressWarnings("rawtypes") +@Public public class RuntimeInfo { private static final Logger log = LoggerFactory.getLogger(RuntimeInfo.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Experimental.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Experimental.java similarity index 85% rename from operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Experimental.java rename to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Experimental.java index 963c56b47b..37d45a00d1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Experimental.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Experimental.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.javaoperatorsdk.operator.api.reconciler; +package io.javaoperatorsdk.operator.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -21,10 +21,10 @@ import java.lang.annotation.Target; /** - * Marks experimental features. + * Marks experimental all API. * - *

Experimental features are not yet stable and may change in future releases. Usually based on - * the feedback of the users. + *

Experimental API are not yet stable and may change in future releases. Usually based on the + * feedback of the users. */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PACKAGE}) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Internal.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Internal.java new file mode 100644 index 0000000000..4da108661d --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Internal.java @@ -0,0 +1,32 @@ +/* + * Copyright Java Operator SDK Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.javaoperatorsdk.operator.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks API as internal. Such API should not be used by end users and/or are not subject of + * semantic versioning. + * + *

The intention with this annotation is not to mark all internal APIs, just make exceptions for + * classes that are marked as {@link Public}. + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PACKAGE}) +public @interface Internal {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Public.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Public.java new file mode 100644 index 0000000000..744dde05c4 --- /dev/null +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Public.java @@ -0,0 +1,29 @@ +/* + * Copyright Java Operator SDK Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.javaoperatorsdk.operator.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks API as public. Such API is subject of semantic versioning. If a class is marked, it means + * all it's public methods are part of the public API. + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PACKAGE}) +public @interface Public {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java index a1b37d6fe9..8f2f4f35b9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java @@ -23,12 +23,14 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; /** * An abstract implementation of {@link ConfigurationService} meant to ease custom implementations */ @SuppressWarnings("rawtypes") +@Public public class AbstractConfigurationService implements ConfigurationService { private final Map configurations = new ConcurrentHashMap<>(); private final Version version; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationConfigurable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationConfigurable.java index 6ab7094584..d114372652 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationConfigurable.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationConfigurable.java @@ -17,6 +17,9 @@ import java.lang.annotation.Annotation; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface AnnotationConfigurable { void initFrom(A configuration); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java index c27b13714e..ccc31da068 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java @@ -29,6 +29,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.Utils.Configurator; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfigurationResolver; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; @@ -51,6 +52,7 @@ * use {@link AbstractConfigurationService} instead as a base for your {@code ConfigurationService} * implementation. */ +@Public public class BaseConfigurationService extends AbstractConfigurationService { private static final Logger logger = LoggerFactory.getLogger(BaseConfigurationService.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java index 9ebf467251..61d4edb6b8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Cloner.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface Cloner { R clone(R object); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java index 6ed9b7ff64..8c0515685e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationService.java @@ -34,6 +34,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.utils.KubernetesSerialization; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.monitoring.Metrics; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @@ -45,6 +46,7 @@ import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerEventSource; /** An interface from which to retrieve configuration information. */ +@Public public interface ConfigurationService { Logger log = LoggerFactory.getLogger(ConfigurationService.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java index cd9cdafb39..96418ad7c4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ConfigurationServiceOverrider.java @@ -27,10 +27,12 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.Operator; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.monitoring.Metrics; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResourceFactory; @SuppressWarnings({"unused", "UnusedReturnValue"}) +@Public public class ConfigurationServiceOverrider { private static final Logger log = LoggerFactory.getLogger(ConfigurationServiceOverrider.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java index 63177b614f..955d40aea8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java @@ -21,6 +21,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec; import io.javaoperatorsdk.operator.api.reconciler.MaxReconciliationInterval; @@ -29,6 +30,7 @@ import io.javaoperatorsdk.operator.processing.retry.GenericRetry; import io.javaoperatorsdk.operator.processing.retry.Retry; +@Public public interface ControllerConfiguration

extends Informable

{ @SuppressWarnings("rawtypes") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java index 7856654f1e..34a5622fbd 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java @@ -24,6 +24,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.informers.cache.ItemStore; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter; @@ -33,6 +34,7 @@ import io.javaoperatorsdk.operator.processing.retry.Retry; @SuppressWarnings({"rawtypes", "unused", "UnusedReturnValue"}) +@Public public class ControllerConfigurationOverrider { private final ControllerConfiguration original; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java index f016be2136..de5159803b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceClassResolver.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +@Public public class DefaultResourceClassResolver implements ResourceClassResolver { @SuppressWarnings("unchecked") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java index 12c6b4fe06..1cd82e4f09 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +@Public public interface Informable { default String getResourceTypeName() { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/InformerStoppedHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/InformerStoppedHandler.java index d1c9a39952..84eb8f0d1f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/InformerStoppedHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/InformerStoppedHandler.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.client.informers.SharedIndexInformer; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface InformerStoppedHandler { @SuppressWarnings("rawtypes") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java index ca777bd2cc..c9558473fb 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfiguration.java @@ -19,7 +19,9 @@ import java.util.Optional; import io.fabric8.kubernetes.client.extended.leaderelection.LeaderCallbacks; +import io.javaoperatorsdk.operator.api.Public; +@Public public class LeaderElectionConfiguration { public static final Duration LEASE_DURATION_DEFAULT_VALUE = Duration.ofSeconds(15); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java index 51ee40d84c..d883324819 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/LeaderElectionConfigurationBuilder.java @@ -18,10 +18,12 @@ import java.time.Duration; import io.fabric8.kubernetes.client.extended.leaderelection.LeaderCallbacks; +import io.javaoperatorsdk.operator.api.Public; import static io.javaoperatorsdk.operator.api.config.LeaderElectionConfiguration.*; @SuppressWarnings("unused") +@Public public final class LeaderElectionConfigurationBuilder { private final String leaseName; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java index e39eaf6f32..37b7498090 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/NamespaceChangeable.java @@ -17,8 +17,11 @@ import java.util.Set; +import io.javaoperatorsdk.operator.api.Public; + import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET; +@Public public interface NamespaceChangeable { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java index 3e620f8f91..90333a7e05 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java @@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec; @@ -30,6 +31,7 @@ import io.javaoperatorsdk.operator.processing.retry.Retry; @SuppressWarnings("rawtypes") +@Public public class ResolvedControllerConfiguration

implements io.javaoperatorsdk.operator.api.config.ControllerConfiguration

{ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java index d28616f118..15bfc5c35d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceClassResolver.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +@Public public interface ResourceClassResolver {

Class

getPrimaryResourceClass( diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java index 8106a1fc83..a14e76e0a3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java @@ -18,7 +18,10 @@ import java.time.Instant; import java.util.Date; +import io.javaoperatorsdk.operator.api.Public; + /** A class encapsulating the version information associated with this SDK instance. */ +@Public public class Version { public static final Version UNKNOWN = new Version("unknown", Date.from(Instant.EPOCH)); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java index 3bb84662fc..3c94e896d5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/ConfigurationConverter.java @@ -17,8 +17,10 @@ import java.lang.annotation.Annotation; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +@Public public interface ConfigurationConverter { C configFrom( diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Configured.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Configured.java index b0ea5cee0c..65ec9ba311 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Configured.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/Configured.java @@ -19,7 +19,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import io.javaoperatorsdk.operator.api.Public; + @Retention(RetentionPolicy.RUNTIME) +@Public public @interface Configured { Class by(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java index adb829633a..6b7d48addd 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/dependent/DependentResourceSpec.java @@ -20,9 +20,11 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition; +@Public public class DependentResourceSpec { private final Class> dependentResourceClass; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Field.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Field.java index ba08ae325a..2f73c8d38d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Field.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Field.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.api.config.informer; +import io.javaoperatorsdk.operator.api.Public; + +@Public public @interface Field { String path(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelector.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelector.java index 022bb59ef0..94cbb40ee3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelector.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelector.java @@ -18,6 +18,9 @@ import java.util.Arrays; import java.util.List; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class FieldSelector { private final List fields; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelectorBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelectorBuilder.java index 827a26cde6..0e1b0e759e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelectorBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/FieldSelectorBuilder.java @@ -18,6 +18,9 @@ import java.util.ArrayList; import java.util.List; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class FieldSelectorBuilder { private final List fields = new ArrayList<>(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java index 7f0d266684..f9d8194fd4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/Informer.java @@ -21,6 +21,7 @@ import java.lang.annotation.Target; import io.fabric8.kubernetes.client.informers.cache.ItemStore; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Constants; import io.javaoperatorsdk.operator.processing.event.source.cache.BoundedItemStore; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; @@ -36,6 +37,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface Informer { String name() default NO_VALUE_SET; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java index 20d7df7136..65db5bc083 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.client.informers.cache.ItemStore; import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.Utils; import io.javaoperatorsdk.operator.api.reconciler.Constants; @@ -39,6 +40,7 @@ import static io.javaoperatorsdk.operator.api.reconciler.Constants.*; @SuppressWarnings("unused") +@Public public class InformerConfiguration { private final Builder builder = new Builder(); private final Class resourceClass; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java index 1a1d8956fc..e2c532ab1f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerEventSourceConfiguration.java @@ -24,6 +24,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.informers.cache.ItemStore; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.Informable; import io.javaoperatorsdk.operator.processing.GroupVersionKind; import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper; @@ -38,6 +39,7 @@ import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_ALL_NAMESPACE_SET; import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE_SET; +@Public public interface InformerEventSourceConfiguration extends Informable { static Builder from( diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/workflow/WorkflowSpec.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/workflow/WorkflowSpec.java index 05ca089516..56ea1b0a52 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/workflow/WorkflowSpec.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/workflow/WorkflowSpec.java @@ -17,8 +17,10 @@ import java.util.List; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; +@Public public interface WorkflowSpec { @SuppressWarnings("rawtypes") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/AggregatedMetrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/AggregatedMetrics.java index 6ae3ebe65a..f9df99bb6e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/AggregatedMetrics.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/AggregatedMetrics.java @@ -20,6 +20,7 @@ import java.util.Objects; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.event.Event; @@ -44,6 +45,7 @@ * * @see Metrics */ +@Public public final class AggregatedMetrics implements Metrics { private final List metricsList; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java index fbbb20d92d..d3a8f741e7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java @@ -18,6 +18,7 @@ import java.util.Map; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; import io.javaoperatorsdk.operator.processing.Controller; @@ -29,6 +30,7 @@ * An interface that metrics providers can implement and that the SDK will call at different times * of its execution cycle. */ +@Public public interface Metrics { /** The default Metrics provider: a no-operation implementation. */ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java index 6ac46ee0a6..a988705b5b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java @@ -19,6 +19,9 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; +import io.javaoperatorsdk.operator.api.Public; + +@Public public abstract class BaseControl> { public static final Long INSTANT_RESCHEDULE = 0L; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java index 38e25010bd..978f9b441e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Cleaner.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.reconciler; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface Cleaner

{ /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Constants.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Constants.java index fad19d2021..0598262657 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Constants.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Constants.java @@ -19,6 +19,9 @@ import java.util.Collections; import java.util.Set; +import io.javaoperatorsdk.operator.api.Public; + +@Public public final class Constants { public static final String WATCH_CURRENT_NAMESPACE = "JOSDK_WATCH_CURRENT"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java index 75d12eb1ad..38acfa43cd 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Context.java @@ -22,11 +22,13 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedWorkflowAndDependentResourceContext; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.source.IndexerResourceCache; +@Public public interface Context

{ Optional getRetryInfo(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ContextInitializer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ContextInitializer.java index 15c8e2c37b..9999940c3b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ContextInitializer.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ContextInitializer.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.reconciler; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface ContextInitializer

{ void initContext(P primary, Context

context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java index d305c28824..18c322d0a3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java @@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.Informer; import io.javaoperatorsdk.operator.processing.event.rate.LinearRateLimiter; import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter; @@ -32,6 +33,7 @@ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface ControllerConfiguration { String name() default Constants.NO_VALUE_SET; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java index 2d9a22b6fa..803c8c3f4c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java @@ -28,6 +28,8 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; +import io.javaoperatorsdk.operator.api.Internal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedWorkflowAndDependentResourceContext; @@ -38,6 +40,7 @@ import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.Cache; +@Public public class DefaultContext

implements Context

{ private RetryInfo retryInfo; private final Controller

controller; @@ -242,11 +245,13 @@ public boolean isPrimaryResourceFinalStateUnknown() { return primaryResourceFinalStateUnknown; } + @Internal public DefaultContext

setRetryInfo(RetryInfo retryInfo) { this.retryInfo = retryInfo; return this; } + @Internal @SuppressWarnings("unchecked") public R getOrComputeDesiredStateFor( DependentResource dependentResource, Function desiredStateComputer) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java index 87a5d79a31..4d514db1f6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DeleteControl.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.api.reconciler; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class DeleteControl extends BaseControl { private final boolean removeFinalizer; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusUpdateControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusUpdateControl.java index 2636fea879..b0d367a093 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusUpdateControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusUpdateControl.java @@ -19,7 +19,9 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public class ErrorStatusUpdateControl

extends BaseControl> { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java index c2c5462e44..f1ce938eb2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java @@ -17,6 +17,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.IndexerResourceCache; @@ -26,6 +27,7 @@ * * @param

the type associated with the primary resource that is handled by your reconciler */ +@Public public class EventSourceContext

{ private final IndexerResourceCache

primaryCache; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java index 658c01d1d9..d9f749f10e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceUtils.java @@ -18,10 +18,12 @@ import java.util.*; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.dependent.workflow.Workflow; import io.javaoperatorsdk.operator.processing.event.source.EventSource; +@Public public class EventSourceUtils { @SuppressWarnings("unchecked") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Ignore.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Ignore.java index a15e66acd1..cf566b2aa9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Ignore.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Ignore.java @@ -20,6 +20,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.javaoperatorsdk.operator.api.Public; + /** * An annotation for downstream tooling to ignore the annotated {@link Reconciler}. This allows to * mark some implementations as not provided by user and should therefore be ignored by processes @@ -27,4 +29,5 @@ */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface Ignore {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexedResourceCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexedResourceCache.java index 01e3ffb7c8..6f3b4a249d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexedResourceCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/IndexedResourceCache.java @@ -19,7 +19,9 @@ import java.util.stream.Stream; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface IndexedResourceCache extends ResourceCache { List byIndex(String indexName, String indexKey); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/MaxReconciliationInterval.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/MaxReconciliationInterval.java index 29a0273ae6..529c9b5215 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/MaxReconciliationInterval.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/MaxReconciliationInterval.java @@ -21,8 +21,11 @@ import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; +import io.javaoperatorsdk.operator.api.Public; + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface MaxReconciliationInterval { long DEFAULT_INTERVAL = 10; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/NonComparableResourceVersionException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/NonComparableResourceVersionException.java index 03045ed88a..da2fb0107a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/NonComparableResourceVersionException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/NonComparableResourceVersionException.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.reconciler; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class NonComparableResourceVersionException extends OperatorException { public NonComparableResourceVersionException(String message) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index f74cd49ee7..ef541e04dc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -31,6 +31,7 @@ import io.fabric8.kubernetes.client.dsl.base.PatchContext; import io.fabric8.kubernetes.client.dsl.base.PatchType; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID; @@ -50,6 +51,7 @@ * versions of methods. */ @Deprecated(forRemoval = true) +@Public public class PrimaryUpdateAndCacheUtils { public static final int DEFAULT_MAX_RETRY = 10; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java index 582d0029fd..94e940249c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Reconciler.java @@ -18,8 +18,10 @@ import java.util.*; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.source.EventSource; +@Public public interface Reconciler

{ /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceCache.java index 672b48e540..148b0da9bc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceCache.java @@ -19,8 +19,10 @@ import java.util.stream.Stream; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.source.Cache; +@Public @SuppressWarnings("unchecked") public interface ResourceCache extends Cache { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java index b9ef475509..b14a225235 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.client.dsl.base.PatchContext; import io.fabric8.kubernetes.client.dsl.base.PatchType; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; import io.javaoperatorsdk.operator.processing.event.source.informer.ManagedInformerEventSource; @@ -42,6 +43,7 @@ * * @param

the resource type on which this object operates */ +@Public public class ResourceOperations

{ public static final int DEFAULT_MAX_RETRY = 10; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java index fbe85333a9..784730fce1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/RetryInfo.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.api.reconciler; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface RetryInfo { /** * @return current retry attempt count. 0 if the current execution is not a retry. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java index 08611ff06f..279dec2039 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java @@ -19,7 +19,9 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.api.Public; +@Public public class UpdateControl

extends BaseControl> { private final P resource; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Workflow.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Workflow.java index 5e3ca0ecf0..9629ae5ba8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Workflow.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/Workflow.java @@ -22,6 +22,7 @@ import java.lang.annotation.Target; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowCleanupResult; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; @@ -29,6 +30,7 @@ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface Workflow { Dependent[] dependents(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Deleter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Deleter.java index 9b3c3a21ef..98f574c467 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Deleter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Deleter.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; /** @@ -25,6 +26,7 @@ * @param

primary resource type */ @FunctionalInterface +@Public public interface Deleter

{ void delete(P primary, Context

context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Dependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Dependent.java index 6ec75b15dc..c0f72e65a7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Dependent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/Dependent.java @@ -15,6 +15,7 @@ */ package io.javaoperatorsdk.operator.api.reconciler.dependent; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition; import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_VALUE_SET; @@ -23,6 +24,7 @@ * The annotation used to create managed {@link DependentResource} associated with a given {@link * io.javaoperatorsdk.operator.api.reconciler.Reconciler} */ +@Public public @interface Dependent { @SuppressWarnings("rawtypes") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java index 5209309019..b4de6f5215 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java @@ -18,6 +18,7 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.source.EventSource; @@ -28,6 +29,7 @@ * @param the dependent resource type * @param

the associated primary resource type */ +@Public public interface DependentResource { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceFactory.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceFactory.java index 34d737fada..a2433ef943 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceFactory.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResourceFactory.java @@ -15,12 +15,14 @@ */ package io.javaoperatorsdk.operator.api.reconciler.dependent; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.Utils; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ConfiguredDependentResource; import io.javaoperatorsdk.operator.processing.dependent.workflow.DependentResourceNode; +@Public @SuppressWarnings({"rawtypes", "unchecked"}) public interface DependentResourceFactory< C extends ControllerConfiguration, D extends DependentResourceSpec> { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceNotFoundException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceNotFoundException.java index 297d53134a..e85bf62f29 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceNotFoundException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceNotFoundException.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class EventSourceNotFoundException extends OperatorException { private final String eventSourceName; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceReferencer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceReferencer.java index 2cfe1e7b30..64dd3a0ce6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceReferencer.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceReferencer.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; +@Public public interface EventSourceReferencer

{ default void useEventSourceWithName(String name) {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/GarbageCollected.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/GarbageCollected.java index 63cf05f917..9a83713763 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/GarbageCollected.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/GarbageCollected.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; /** @@ -36,4 +37,5 @@ * * @param

primary resource type */ +@Public public interface GarbageCollected

extends Deleter

{} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/NameSetter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/NameSetter.java index f948323436..727c2539af 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/NameSetter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/NameSetter.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.api.reconciler.dependent; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface NameSetter { void setName(String name); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/RecentOperationCacheFiller.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/RecentOperationCacheFiller.java index 9cf1fce287..b632f49680 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/RecentOperationCacheFiller.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/RecentOperationCacheFiller.java @@ -15,8 +15,10 @@ */ package io.javaoperatorsdk.operator.api.reconciler.dependent; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; +@Public public interface RecentOperationCacheFiller { void handleRecentResourceCreate(ResourceID resourceID, R resource); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/ReconcileResult.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/ReconcileResult.java index 7849085c5c..91695da6ee 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/ReconcileResult.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/ReconcileResult.java @@ -19,8 +19,10 @@ import java.util.stream.Collectors; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; +@Public public class ReconcileResult { private final Map resourceOperations; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ConfiguredDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ConfiguredDependentResource.java index d3910a2f6f..9d35507e5a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ConfiguredDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ConfiguredDependentResource.java @@ -17,6 +17,9 @@ import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface ConfiguredDependentResource { void configureWith(C config); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedWorkflowAndDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedWorkflowAndDependentResourceContext.java index 98fc720867..61afceed54 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedWorkflowAndDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedWorkflowAndDependentResourceContext.java @@ -22,11 +22,13 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.processing.Controller; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowCleanupResult; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; +@Public @SuppressWarnings("rawtypes") public class DefaultManagedWorkflowAndDependentResourceContext

implements ManagedWorkflowAndDependentResourceContext { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceException.java index 1f63e89c95..accfeeb0e4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceException.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent.managed; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class ManagedDependentResourceException extends OperatorException { private final String associatedDependentName; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedWorkflowAndDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedWorkflowAndDependentResourceContext.java index 430d61ab05..da2f556770 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedWorkflowAndDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedWorkflowAndDependentResourceContext.java @@ -17,6 +17,7 @@ import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowCleanupResult; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; @@ -25,6 +26,7 @@ * Contextual information related to {@link DependentResource} either to retrieve the actual * implementations to interact with them or to pass information between them and/or the reconciler */ +@Public public interface ManagedWorkflowAndDependentResourceContext { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/ControllerHealthInfo.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/ControllerHealthInfo.java index f2a9359e04..78abf6d6cf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/ControllerHealthInfo.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/ControllerHealthInfo.java @@ -21,10 +21,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.EventSourceManager; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerEventSource; +@Public @SuppressWarnings("rawtypes") public class ControllerHealthInfo { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/EventSourceHealthIndicator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/EventSourceHealthIndicator.java index c2d83096e5..08c8b8e020 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/EventSourceHealthIndicator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/EventSourceHealthIndicator.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.health; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface EventSourceHealthIndicator { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerHealthIndicator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerHealthIndicator.java index 0bb03246e8..23df791c25 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerHealthIndicator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerHealthIndicator.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.health; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface InformerHealthIndicator extends EventSourceHealthIndicator { boolean hasSynced(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerWrappingEventSourceHealthIndicator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerWrappingEventSourceHealthIndicator.java index f56e649181..ccf3996ab8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerWrappingEventSourceHealthIndicator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/InformerWrappingEventSourceHealthIndicator.java @@ -18,7 +18,9 @@ import java.util.Map; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface InformerWrappingEventSourceHealthIndicator extends EventSourceHealthIndicator { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/Status.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/Status.java index ac5792982c..9d41ed4fe2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/Status.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/health/Status.java @@ -15,9 +15,12 @@ */ package io.javaoperatorsdk.operator.health; +import io.javaoperatorsdk.operator.api.Public; + /** * The health status of an {@link io.javaoperatorsdk.operator.processing.event.source.EventSource} */ +@Public public enum Status { HEALTHY, UNHEALTHY, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/GroupVersionKind.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/GroupVersionKind.java index be3869a64f..4f91cec684 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/GroupVersionKind.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/GroupVersionKind.java @@ -20,7 +20,9 @@ import java.util.concurrent.ConcurrentHashMap; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public class GroupVersionKind { private static final String SEPARATOR = "/"; private final String group; 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 396d16c032..0be5a163c0 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 @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @@ -31,6 +32,7 @@ * * @see ResourceIDProvider */ +@Public public interface ResourceIDMapper { /** 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 b784f35744..f42bd6a439 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 @@ -15,6 +15,8 @@ */ package io.javaoperatorsdk.operator.processing; +import io.javaoperatorsdk.operator.api.Public; + /** * Provides the identifier for an object that represents a resource. This ID is used: * @@ -31,6 +33,7 @@ * @see ResourceIDMapper * @param type of the id */ +@Public public interface ResourceIDProvider { /** ID for the resource POJO that implement this interface. */ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java index 8dc62b4ca7..ab0b0f23c8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java @@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.DefaultContext; import io.javaoperatorsdk.operator.api.reconciler.Ignore; @@ -41,6 +42,7 @@ * @param

the associated primary resource type */ @Ignore +@Public public abstract class AbstractDependentResource implements DependentResource, NameSetter { private static final Logger log = LoggerFactory.getLogger(AbstractDependentResource.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java index 269a9b2279..d833c67b99 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java @@ -18,6 +18,7 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.Utils; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; @@ -30,6 +31,7 @@ import io.javaoperatorsdk.operator.processing.event.source.EventSource; @Ignore +@Public public abstract class AbstractEventSourceHolderDependentResource< R, P extends HasMetadata, T extends EventSource> extends AbstractDependentResource implements EventSourceReferencer

{ 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 7b83a377c1..42e62254ce 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 @@ -20,6 +20,7 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; @@ -28,6 +29,7 @@ import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; +@Public public abstract class AbstractExternalDependentResource< R, P extends HasMetadata, T extends EventSource, ID> extends AbstractEventSourceHolderDependentResource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java index e13614df2e..4c2ab994d5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java @@ -18,6 +18,7 @@ import java.util.Map; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.processing.dependent.Matcher.Result; @@ -31,6 +32,7 @@ * @param the dependent resource type * @param

the primary resource type */ +@Public public interface BulkDependentResource { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkUpdater.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkUpdater.java index 9d7d9b8b20..e3d8606ff5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkUpdater.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkUpdater.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; /** @@ -25,6 +26,7 @@ * @param secondary resource type * @param

primary resource type */ +@Public public interface BulkUpdater extends Updater { default Matcher.Result match(R actualResource, P primary, Context

context) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDBulkDependentResource.java index 59545f63d2..c64cb765df 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDBulkDependentResource.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; +@Public public interface CRUDBulkDependentResource extends BulkDependentResource, Creator, BulkUpdater, Deleter

{} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDExternalBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDExternalBulkDependentResource.java index f290bcbbbc..fe1b6a0096 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDExternalBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDExternalBulkDependentResource.java @@ -16,9 +16,11 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.processing.ResourceIDProvider; +@Public public interface CRUDExternalBulkDependentResource< R extends ResourceIDProvider, P extends HasMetadata, ID> extends ExternalBulkDependentResource, Creator, BulkUpdater, Deleter

{} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDKubernetesBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDKubernetesBulkDependentResource.java index be15faf645..49a5edeb3a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDKubernetesBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/CRUDKubernetesBulkDependentResource.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.processing.event.ResourceID; +@Public public interface CRUDKubernetesBulkDependentResource extends BulkDependentResource, Creator, BulkUpdater, Deleter

{} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Creator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Creator.java index 4eed6d5a43..0e269c1d39 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Creator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Creator.java @@ -16,9 +16,11 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; @FunctionalInterface +@Public public interface Creator { R create(R desired, P primary, Context

context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceException.java index f14a44b35b..225ef40bc4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceException.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class DependentResourceException extends OperatorException { public DependentResourceException() {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceWithExplicitState.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceWithExplicitState.java index 52451f92af..8752e5c427 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceWithExplicitState.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DependentResourceWithExplicitState.java @@ -18,6 +18,7 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; /** @@ -31,6 +32,7 @@ * @param

the primary resource type * @param the state type */ +@Public public interface DependentResourceWithExplicitState extends Creator, Deleter

{ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalBulkDependentResource.java index 4ac15980f7..d8d5c00b4d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ExternalBulkDependentResource.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.ResourceIDProvider; @@ -23,6 +24,7 @@ * Specialized interface for bulk dependent resources where resource implement {@link * ResourceIDProvider}. */ +@Public public interface ExternalBulkDependentResource< R extends ResourceIDProvider, P extends HasMetadata, ID> extends ResourceIDMapperBulkDependentResource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesBulkDependentResource.java index 025c4c65ff..67993764d8 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/KubernetesBulkDependentResource.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.ResourceID; @@ -25,6 +26,7 @@ * resources you can still choose a different ID type and directly implement {@link * BulkDependentResource}. */ +@Public public interface KubernetesBulkDependentResource extends ResourceIDMapperBulkDependentResource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Matcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Matcher.java index 3aa6eb3c01..a8289cd487 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Matcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Matcher.java @@ -18,6 +18,7 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; /** @@ -31,6 +32,7 @@ * io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource} implementation is * associated */ +@Public public interface Matcher { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ResourceIDMapperBulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ResourceIDMapperBulkDependentResource.java index 7cdd861cf6..40bdfd9ead 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ResourceIDMapperBulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/ResourceIDMapperBulkDependentResource.java @@ -21,10 +21,12 @@ import java.util.stream.Collectors; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; +@Public public interface ResourceIDMapperBulkDependentResource extends BulkDependentResource, DependentResource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Updater.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Updater.java index 94584f5570..ec2d4a63ec 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Updater.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/Updater.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.processing.dependent; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; +@Public public interface Updater extends Matcher { R update(R actual, R desired, P primary, Context

context); 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 1776194e33..948e221242 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 @@ -18,11 +18,13 @@ import java.time.Duration; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.processing.dependent.AbstractExternalDependentResource; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @Ignore +@Public public abstract class AbstractPollingDependentResource extends AbstractExternalDependentResource< R, P, ExternalResourceCachingEventSource, ID> { 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 6b9aaf9c1e..af81544365 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 @@ -18,6 +18,7 @@ import java.time.Duration; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; @@ -26,6 +27,7 @@ import io.javaoperatorsdk.operator.processing.event.source.polling.PerResourcePollingEventSource; @Ignore +@Public public abstract class PerResourcePollingDependentResource extends AbstractPollingDependentResource implements PerResourcePollingEventSource.ResourceFetcher { 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 894e359d57..6905d1ff82 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 @@ -18,6 +18,7 @@ import java.time.Duration; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; @@ -26,6 +27,7 @@ import io.javaoperatorsdk.operator.processing.event.source.polling.PollingEventSource; @Ignore +@Public public abstract class PollingDependentResource extends AbstractPollingDependentResource implements PollingEventSource.GenericResourceFetcher { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/BooleanWithUndefined.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/BooleanWithUndefined.java index 6aba2e2cd7..b224097a42 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/BooleanWithUndefined.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/BooleanWithUndefined.java @@ -15,7 +15,10 @@ */ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; +import io.javaoperatorsdk.operator.api.Public; + /** A replacement for {@link Boolean}, which can't be used in annotations. */ +@Public public enum BooleanWithUndefined { TRUE, FALSE, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDKubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDKubernetesDependentResource.java index 48d5cced5a..dcbda35ba2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDKubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDKubernetesDependentResource.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected; import io.javaoperatorsdk.operator.processing.dependent.Creator; @@ -29,6 +30,7 @@ * @param

the type of the associated primary resource */ @Ignore +@Public public abstract class CRUDKubernetesDependentResource extends KubernetesDependentResource implements Creator, Updater, GarbageCollected

{ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDNoGCKubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDNoGCKubernetesDependentResource.java index a161b4d31d..a7e1b42e41 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDNoGCKubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/CRUDNoGCKubernetesDependentResource.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Ignore; import io.javaoperatorsdk.operator.api.reconciler.dependent.Deleter; import io.javaoperatorsdk.operator.processing.dependent.Creator; @@ -32,6 +33,7 @@ * @param

the type of the associated primary resource */ @Ignore +@Public public class CRUDNoGCKubernetesDependentResource extends KubernetesDependentResource implements Creator, Updater, Deleter

{ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java index fe7ec967aa..c113c95ba6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesDependentResource.java @@ -17,10 +17,12 @@ import io.fabric8.kubernetes.api.model.GenericKubernetesResource; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.GroupVersionKind; +@Public public class GenericKubernetesDependentResource

extends KubernetesDependentResource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java index 5562c883e2..05222e6181 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java @@ -21,11 +21,13 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.zjsonpatch.JsonDiff; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.processing.dependent.Matcher; import com.fasterxml.jackson.databind.JsonNode; +@Public public class GenericKubernetesResourceMatcher { private static final String SPEC = "/spec"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdater.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdater.java index fe826da0ee..2d63c83da7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdater.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericResourceUpdater.java @@ -19,8 +19,10 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.utils.KubernetesSerialization; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; +@Public public class GenericResourceUpdater { private static final String METADATA = "metadata"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GroupVersionKindPlural.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GroupVersionKindPlural.java index a3ed4d2d97..9d26923b8a 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GroupVersionKindPlural.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GroupVersionKindPlural.java @@ -20,12 +20,14 @@ import io.fabric8.kubernetes.api.Pluralize; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.GroupVersionKind; /** * An extension of {@link GroupVersionKind} that also records the associated plural form which is * useful when dealing with Kubernetes RBACs. Downstream projects might leverage that information. */ +@Public public class GroupVersionKindPlural extends GroupVersionKind { private final String plural; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java index 35bcde9052..884ae46672 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java @@ -20,10 +20,12 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.Informer; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) +@Public public @interface KubernetesDependent { /** Creates the resource only if did not exist before, this applies only if SSA is used. */ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java index f8d7c07b01..b8b619077b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java @@ -25,6 +25,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.Namespaced; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.dependent.Configured; import io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Context; @@ -45,6 +46,7 @@ by = KubernetesDependent.class, with = KubernetesDependentResourceConfig.class, converter = KubernetesDependentConverter.class) +@Public public abstract class KubernetesDependentResource extends AbstractEventSourceHolderDependentResource> implements ConfiguredDependentResource> { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java index 05ff71335c..e0732409e9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +@Public public class KubernetesDependentResourceConfig { public static final boolean DEFAULT_CREATE_RESOURCE_ONLY_IF_NOT_EXISTING_WITH_SSA = true; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java index bdd6b068b3..06260ce67f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java @@ -16,8 +16,10 @@ package io.javaoperatorsdk.operator.processing.dependent.kubernetes; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +@Public public final class KubernetesDependentResourceConfigBuilder { private boolean createResourceOnlyIfNotExistingWithSSA; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/ResourceComparators.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/ResourceComparators.java index eabfd9acf3..731865a4a9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/ResourceComparators.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/ResourceComparators.java @@ -19,7 +19,9 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.Secret; +import io.javaoperatorsdk.operator.api.Public; +@Public public class ResourceComparators { public static boolean compareConfigMapData(ConfigMap c1, ConfigMap c2) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcher.java index d3e5b6dbc5..c275606eed 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcher.java @@ -40,6 +40,7 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet; import io.fabric8.kubernetes.client.utils.KubernetesSerialization; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.processing.LoggingUtils; @@ -65,6 +66,7 @@ // https://github.com/kubernetes-sigs/structured-merge-diff // https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-field-management.html // see also: https://kubernetes.slack.com/archives/C0123CNN8F3/p1686141087220719 +@Public public class SSABasedGenericKubernetesResourceMatcher { public static final String APPLY_OPERATION = "Apply"; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/CRDPresentActivationCondition.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/CRDPresentActivationCondition.java index 025c64f2ab..af0f17ac26 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/CRDPresentActivationCondition.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/CRDPresentActivationCondition.java @@ -23,6 +23,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @@ -36,6 +37,7 @@ * @param

the primary resource type associated with the reconciler processing dependents * associated with this condition */ +@Public public class CRDPresentActivationCondition implements Condition { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Condition.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Condition.java index 0906ab920a..b70f5310fd 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Condition.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Condition.java @@ -16,9 +16,11 @@ package io.javaoperatorsdk.operator.processing.dependent.workflow; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; +@Public public interface Condition { enum Type { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DetailedCondition.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DetailedCondition.java index 993f974b60..bff47bf09c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DetailedCondition.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DetailedCondition.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent.workflow; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @@ -27,6 +28,7 @@ * part of * @param the type of the extra information returned by the condition */ +@Public public interface DetailedCondition extends Condition { /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/KubernetesResourceDeletedCondition.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/KubernetesResourceDeletedCondition.java index f2c9b58359..c11b281836 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/KubernetesResourceDeletedCondition.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/KubernetesResourceDeletedCondition.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.processing.dependent.workflow; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @@ -23,6 +24,7 @@ * resources to prevent the workflow from proceeding until the associated resource is actually * deleted from the server. */ +@Public public class KubernetesResourceDeletedCondition implements Condition { @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflow.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflow.java index ec5a8c81b4..a516d9a154 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflow.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflow.java @@ -20,9 +20,11 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; +@Public public interface ManagedWorkflow

{ @SuppressWarnings({"unused", "rawtypes"}) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowFactory.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowFactory.java index ffc22f0c55..26fac12ba3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowFactory.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowFactory.java @@ -17,9 +17,11 @@ import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec; +@Public public interface ManagedWorkflowFactory> { @SuppressWarnings({"rawtypes", "unchecked"}) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Workflow.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Workflow.java index ff10b2c2ed..1698b5b164 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Workflow.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/Workflow.java @@ -20,9 +20,11 @@ import java.util.Map; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; +@Public public interface Workflow

{ boolean THROW_EXCEPTION_AUTOMATICALLY_DEFAULT = true; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowBuilder.java index 199d515087..31e2e8e3da 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowBuilder.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowBuilder.java @@ -22,11 +22,13 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import static io.javaoperatorsdk.operator.processing.dependent.workflow.Workflow.THROW_EXCEPTION_AUTOMATICALLY_DEFAULT; @SuppressWarnings({"rawtypes", "unchecked"}) +@Public public class WorkflowBuilder

{ private final Map> dependentResourceNodes = new HashMap<>(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupResult.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupResult.java index 0cba15d679..af4187cd1c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupResult.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupResult.java @@ -17,9 +17,11 @@ import java.util.List; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @SuppressWarnings("rawtypes") +@Public public interface WorkflowCleanupResult extends WorkflowResult { WorkflowCleanupResult EMPTY = new WorkflowCleanupResult() {}; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileResult.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileResult.java index 5db8afaed3..a05c72c7a9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileResult.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileResult.java @@ -18,9 +18,11 @@ import java.util.List; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @SuppressWarnings("rawtypes") +@Public public interface WorkflowReconcileResult extends WorkflowResult { WorkflowReconcileResult EMPTY = new WorkflowReconcileResult() {}; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowResult.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowResult.java index 45d34a206a..a9847dc0b1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowResult.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowResult.java @@ -18,9 +18,11 @@ import java.util.Map; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; @SuppressWarnings("rawtypes") +@Public public interface WorkflowResult { default Map getErroredDependents() { return Map.of(); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/Event.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/Event.java index 036274c5d3..ede7d441e1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/Event.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/Event.java @@ -17,6 +17,9 @@ import java.util.Objects; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class Event { private final ResourceID relatedCustomResource; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java index 07ce0aeb9b..9f07ee385f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java @@ -15,6 +15,8 @@ */ package io.javaoperatorsdk.operator.processing.event; +import io.javaoperatorsdk.operator.api.Public; + public interface EventHandler { void handleEvent(Event event); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java index 98a3bc687d..05a9059338 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java @@ -19,10 +19,12 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.source.EventSource; import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerEventSource; +@Public public interface EventSourceRetriever

{ default EventSource getEventSourceFor(Class dependentType) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/NoEventSourceForClassException.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/NoEventSourceForClassException.java index 3bc2f40f8d..21796408bd 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/NoEventSourceForClassException.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/NoEventSourceForClassException.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.processing.event; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class NoEventSourceForClassException extends OperatorException { private Class clazz; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java index da408322f1..3a39603f74 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ResourceID.java @@ -21,7 +21,9 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.OwnerReference; +import io.javaoperatorsdk.operator.api.Public; +@Public public class ResourceID implements Serializable { public static ResourceID fromResource(HasMetadata resource) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/LinearRateLimiter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/LinearRateLimiter.java index 25af46b5d8..b6dbc9d012 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/LinearRateLimiter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/LinearRateLimiter.java @@ -19,9 +19,11 @@ import java.time.LocalDateTime; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.AnnotationConfigurable; /** A simple rate limiter that limits the number of permission for a time interval. */ +@Public public class LinearRateLimiter implements RateLimiter, AnnotationConfigurable { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimited.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimited.java index 1fde1c402c..7a97ae9304 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimited.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimited.java @@ -22,6 +22,9 @@ import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; +import io.javaoperatorsdk.operator.api.Public; + +@Public @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimiter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimiter.java index 9a2d87b571..54a4be83d6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimiter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/rate/RateLimiter.java @@ -18,8 +18,10 @@ import java.time.Duration; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter.RateLimitState; +@Public public interface RateLimiter { interface RateLimitState {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/AbstractEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/AbstractEventSource.java index c89ef6cad4..f771ba5bbf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/AbstractEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/AbstractEventSource.java @@ -17,12 +17,14 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.EventHandler; import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter; import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter; +@Public public abstract class AbstractEventSource implements EventSource { private final Class resourceClass; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Cache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Cache.java index b2c2d2692d..ed8c9d2dbf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Cache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Cache.java @@ -19,9 +19,11 @@ import java.util.function.Predicate; import java.util.stream.Stream; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; @SuppressWarnings({"rawtypes", "unchecked"}) +@Public public interface Cache { Predicate TRUE = (a) -> true; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Configurable.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Configurable.java index c0097fa5ce..de66237033 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Configurable.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/Configurable.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface Configurable { C configuration(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java index 9bd301d77a..5ba1980b0d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSource.java @@ -19,6 +19,7 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.health.EventSourceHealthIndicator; import io.javaoperatorsdk.operator.health.Status; import io.javaoperatorsdk.operator.processing.LifecycleAware; @@ -37,6 +38,7 @@ * @param

the primary resource type which reconciler needs to be triggered when events occur on * resources of type R */ +@Public public interface EventSource extends LifecycleAware, EventSourceHealthIndicator { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSourceStartPriority.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSourceStartPriority.java index 3d1521275c..1dedd8c3bc 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSourceStartPriority.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/EventSourceStartPriority.java @@ -15,10 +15,13 @@ */ package io.javaoperatorsdk.operator.processing.event.source; +import io.javaoperatorsdk.operator.api.Public; + /** * Defines priority levels for {@link EventSource} implementation to ensure that some sources are * started before others */ +@Public public enum EventSourceStartPriority { /** 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 8a4c476443..61260beef2 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 @@ -31,6 +31,8 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Internal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.ResourceIDProvider; @@ -57,6 +59,7 @@ * @param type of polled external secondary resource * @param

primary resource */ +@Public public abstract class ExternalResourceCachingEventSource extends AbstractEventSource implements RecentOperationCacheFiller { @@ -207,6 +210,7 @@ private boolean acceptedByGenericFiler(R resource) { } @Override + @Internal public synchronized void handleRecentResourceCreate(ResourceID primaryID, R resource) { var actualValues = cache.get(primaryID); var resourceId = resourceIDMapper.idFor(resource); @@ -220,6 +224,7 @@ public synchronized void handleRecentResourceCreate(ResourceID primaryID, R reso } @Override + @Internal public synchronized void handleRecentResourceUpdate( ResourceID primaryID, R resource, R previousVersionOfResource) { var actualValues = cache.get(primaryID); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/IndexerResourceCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/IndexerResourceCache.java index 96c8d37593..d37faa30b4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/IndexerResourceCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/IndexerResourceCache.java @@ -20,8 +20,10 @@ import java.util.function.Function; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.IndexedResourceCache; +@Public public interface IndexerResourceCache extends IndexedResourceCache { void addIndexers(Map>> indexers); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/PrimaryToSecondaryMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/PrimaryToSecondaryMapper.java index 30d3b711d9..16a509ad02 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/PrimaryToSecondaryMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/PrimaryToSecondaryMapper.java @@ -18,6 +18,7 @@ import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration; import io.javaoperatorsdk.operator.processing.event.ResourceID; @@ -46,6 +47,7 @@ * * @param

primary resource type */ +@Public public interface PrimaryToSecondaryMapper

{ Set toSecondaryResourceIDs(P primary); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceAction.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceAction.java index fff8680913..17638716b3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceAction.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceAction.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source; +import io.javaoperatorsdk.operator.api.Public; + +@Public public enum ResourceAction { ADDED, UPDATED, diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventAware.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventAware.java index 52bcb6e1c5..d3a7167ebf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventAware.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventAware.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.processing.event.source; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface ResourceEventAware { default void onResourceCreated(T resource) {} diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/SecondaryToPrimaryMapper.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/SecondaryToPrimaryMapper.java index 0c6126105c..7b2952463d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/SecondaryToPrimaryMapper.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/SecondaryToPrimaryMapper.java @@ -17,6 +17,7 @@ import java.util.Set; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; /** @@ -25,6 +26,7 @@ * @param secondary resource type */ @FunctionalInterface +@Public public interface SecondaryToPrimaryMapper { /** * @param resource - secondary diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/UpdatableCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/UpdatableCache.java index debaf8d74b..fa6547c684 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/UpdatableCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/UpdatableCache.java @@ -15,8 +15,10 @@ */ package io.javaoperatorsdk.operator.processing.event.source; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; +@Public public interface UpdatableCache extends Cache { T remove(ResourceID key); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCache.java index d43fa15630..081d2e006d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedCache.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.cache; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface BoundedCache { R get(K key); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedItemStore.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedItemStore.java index abf12bcf58..bfc8970157 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedItemStore.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/BoundedItemStore.java @@ -30,8 +30,10 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.informers.cache.Cache; import io.fabric8.kubernetes.client.informers.cache.ItemStore; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.Utils; +@Public public class BoundedItemStore implements ItemStore { private static final Logger log = LoggerFactory.getLogger(BoundedItemStore.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/KubernetesResourceFetcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/KubernetesResourceFetcher.java index f0f4557701..74830d8912 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/KubernetesResourceFetcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/KubernetesResourceFetcher.java @@ -19,8 +19,10 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; +@Public public class KubernetesResourceFetcher implements ResourceFetcher { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/ResourceFetcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/ResourceFetcher.java index f7c9d94f4a..5eb2c0aa47 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/ResourceFetcher.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/cache/ResourceFetcher.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.cache; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface ResourceFetcher { R fetchResource(K key); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceDeleteEvent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceDeleteEvent.java index 6219207faf..2148467323 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceDeleteEvent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceDeleteEvent.java @@ -18,6 +18,7 @@ import java.util.Objects; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.ResourceAction; @@ -25,6 +26,7 @@ * Extends ResourceEvent for informer Delete events, it holds also information if the final state is * unknown for the deleted resource. */ +@Public public class ResourceDeleteEvent extends ResourceEvent { private final boolean deletedFinalStateUnknown; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceEvent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceEvent.java index 88f9bf8716..18f4924336 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceEvent.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ResourceEvent.java @@ -19,10 +19,12 @@ import java.util.Optional; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.ResourceAction; +@Public public class ResourceEvent extends Event { private final ResourceAction action; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/GenericFilter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/GenericFilter.java index 01a050f6d0..7fd4b550fb 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/GenericFilter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/GenericFilter.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.filter; +import io.javaoperatorsdk.operator.api.Public; + +@Public @FunctionalInterface public interface GenericFilter { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnAddFilter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnAddFilter.java index 26dfd7199f..19dec29b8b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnAddFilter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnAddFilter.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.filter; +import io.javaoperatorsdk.operator.api.Public; + +@Public @FunctionalInterface public interface OnAddFilter { boolean accept(R resource); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnDeleteFilter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnDeleteFilter.java index bde05783c2..02e3d60b2b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnDeleteFilter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnDeleteFilter.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.filter; +import io.javaoperatorsdk.operator.api.Public; + +@Public @FunctionalInterface public interface OnDeleteFilter { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnUpdateFilter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnUpdateFilter.java index 596565086c..dd132dc444 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnUpdateFilter.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/filter/OnUpdateFilter.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.event.source.filter; +import io.javaoperatorsdk.operator.api.Public; + +@Public @FunctionalInterface public interface OnUpdateFilter { 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 44e0a684b6..98784fbc82 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,11 +21,14 @@ import java.util.concurrent.ConcurrentHashMap; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Internal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; import io.javaoperatorsdk.operator.processing.event.source.ResourceEventAware; +@Public public class CachingInboundEventSource extends ExternalResourceCachingEventSource implements ResourceEventAware

{ @@ -53,6 +56,7 @@ public void handleResourceDeleteEvent(ResourceID primaryID, ID resourceID) { } @Override + @Internal public void onResourceDeleted(P resource) { var resourceID = ResourceID.fromResource(resource); fetchedForPrimaries.remove(resourceID); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/SimpleInboundEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/SimpleInboundEventSource.java index b1515b1adb..7e650ba237 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/SimpleInboundEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/inbound/SimpleInboundEventSource.java @@ -21,10 +21,12 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.event.Event; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.AbstractEventSource; +@Public public class SimpleInboundEventSource

extends AbstractEventSource { private static final Logger log = LoggerFactory.getLogger(SimpleInboundEventSource.class); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java index c425a4d413..0eeb31cf12 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java @@ -26,6 +26,8 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.javaoperatorsdk.operator.api.Internal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.Event; @@ -43,6 +45,7 @@ * @param resource type being watched * @param

type of the associated primary resource */ +@Public public class InformerEventSource extends ManagedInformerEventSource> implements ResourceEventHandler { @@ -85,6 +88,7 @@ public InformerEventSource( } @Override + @Internal public void onAdd(R newResource) { withMDC( newResource, @@ -98,6 +102,7 @@ public void onAdd(R newResource) { } @Override + @Internal public void onUpdate(R oldObject, R newObject) { withMDC( newObject, @@ -113,6 +118,7 @@ public void onUpdate(R oldObject, R newObject) { } @Override + @Internal public synchronized void onDelete(R resource, boolean deletedFinalStateUnknown) { withMDC( resource, @@ -247,12 +253,14 @@ public Set getSecondaryResources(P primary) { } @Override + @Internal public void handleRecentResourceUpdate( ResourceID resourceID, R resource, R previousVersionOfResource) { handleRecentCreateOrUpdate(resource); } @Override + @Internal public void handleRecentResourceCreate(ResourceID resourceID, R resource) { handleRecentCreateOrUpdate(resource); } @@ -267,6 +275,7 @@ private boolean useSecondaryToPrimaryIndex() { } @Override + @Internal public boolean allowsNamespaceChanges() { return configuration().followControllerNamespaceChanges(); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/Mappers.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/Mappers.java index efc6a981c3..460e6c0b81 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/Mappers.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/Mappers.java @@ -20,12 +20,14 @@ import java.util.stream.Collectors; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.GroupVersionKind; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper; import static io.javaoperatorsdk.operator.ReconcilerUtilsInternal.getGroup; +@Public public class Mappers { public static final String DEFAULT_ANNOTATION_FOR_NAME = "io.javaoperatorsdk/primary-name"; 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 599647ff29..454047bbd3 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,8 +22,10 @@ import java.util.function.Predicate; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; +@Public public record PerResourcePollingConfiguration( String name, ScheduledExecutorService executorService, 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 6fcf5d2678..b0638b241e 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,8 +20,10 @@ import java.util.function.Predicate; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; +@Public public final class PerResourcePollingConfigurationBuilder { private final Duration 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 0f0eb78a69..1a51d41e4e 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 @@ -32,6 +32,8 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Internal; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.Cache; @@ -48,6 +50,7 @@ * @param the resource polled by the event source * @param

related custom resource */ +@Public public class PerResourcePollingEventSource extends ExternalResourceCachingEventSource implements ResourceEventAware

{ @@ -95,16 +98,19 @@ private void scheduleNextExecution(P primary, Set actualResources) { } @Override + @Internal public void onResourceCreated(P resource) { checkAndRegisterTask(resource); } @Override + @Internal public void onResourceUpdated(P newResource, P oldResource) { checkAndRegisterTask(newResource); } @Override + @Internal public void onResourceDeleted(P resource) { var resourceID = ResourceID.fromResource(resource); var scheduledFuture = scheduledFutures.remove(resourceID); 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 9ac1b8cc96..13936fb722 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,8 +18,10 @@ import java.time.Duration; import java.util.Objects; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; +@Public public record PollingConfiguration( String name, PollingEventSource.GenericResourceFetcher genericResourceFetcher, 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 0e68876b60..bd9adeccb7 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,8 +17,10 @@ import java.time.Duration; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.processing.ResourceIDMapper; +@Public public final class PollingConfigurationBuilder { private final Duration period; private final PollingEventSource.GenericResourceFetcher genericResourceFetcher; 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 f5e5a79430..78a5abf669 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 @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.OperatorException; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.health.Status; import io.javaoperatorsdk.operator.processing.event.ResourceID; import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource; @@ -57,6 +58,7 @@ * @param type of the polled resource * @param

primary resource type */ +@Public public class PollingEventSource extends ExternalResourceCachingEventSource { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/timer/TimerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/timer/TimerEventSource.java index eae9663fe6..05ffe0f21c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/timer/TimerEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/timer/TimerEventSource.java @@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Internal; import io.javaoperatorsdk.operator.api.reconciler.BaseControl; import io.javaoperatorsdk.operator.health.Status; import io.javaoperatorsdk.operator.processing.event.Event; @@ -72,6 +73,7 @@ public void scheduleOnce(ResourceID resourceID, long delay) { } @Override + @Internal public void onResourceDeleted(R resource) { // for triggerReconcilerOnAllEvents the cancelOnceSchedule will be called on // successful delete event processing diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/Expectation.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/Expectation.java index 8f0b622880..45b2382afe 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/Expectation.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/Expectation.java @@ -18,10 +18,10 @@ import java.util.function.BiPredicate; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Experimental; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.Experimental; -import static io.javaoperatorsdk.operator.api.reconciler.Experimental.API_MIGHT_CHANGE; +import static io.javaoperatorsdk.operator.api.Experimental.API_MIGHT_CHANGE; /** * Expectation is basically a named predicate, that has access to the reconciliation context. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/ExpectationManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/ExpectationManager.java index 1dfcd6d177..65d62a2b1c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/ExpectationManager.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/ExpectationManager.java @@ -21,11 +21,11 @@ import java.util.concurrent.ConcurrentHashMap; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Experimental; import io.javaoperatorsdk.operator.api.reconciler.Context; -import io.javaoperatorsdk.operator.api.reconciler.Experimental; import io.javaoperatorsdk.operator.processing.event.ResourceID; -import static io.javaoperatorsdk.operator.api.reconciler.Experimental.API_MIGHT_CHANGE; +import static io.javaoperatorsdk.operator.api.Experimental.API_MIGHT_CHANGE; @Experimental(API_MIGHT_CHANGE) public class ExpectationManager

{ diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/PeriodicCleanerExpectationManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/PeriodicCleanerExpectationManager.java index cabf697e20..88cefc6193 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/PeriodicCleanerExpectationManager.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/PeriodicCleanerExpectationManager.java @@ -21,11 +21,11 @@ import java.util.concurrent.TimeUnit; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Experimental; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Experimental; import io.javaoperatorsdk.operator.api.reconciler.IndexedResourceCache; -import static io.javaoperatorsdk.operator.api.reconciler.Experimental.API_MIGHT_CHANGE; +import static io.javaoperatorsdk.operator.api.Experimental.API_MIGHT_CHANGE; /** * Expectation manager implementation that works without enabling {@link diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetry.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetry.java index 5ee016b34f..d09d7c0c60 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetry.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetry.java @@ -17,8 +17,10 @@ import java.time.Duration; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.AnnotationConfigurable; +@Public public class GenericRetry implements Retry, AnnotationConfigurable { private int maxAttempts = GradualRetry.DEFAULT_MAX_ATTEMPTS; private long initialInterval = GradualRetry.DEFAULT_INITIAL_INTERVAL; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java index fadc022de7..f9d4a29355 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GenericRetryExecution.java @@ -18,6 +18,9 @@ import java.time.Duration; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; + +@Public public class GenericRetryExecution implements RetryExecution { private final GenericRetry genericRetry; diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GradualRetry.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GradualRetry.java index 740c385a46..e3936f22d7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GradualRetry.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/GradualRetry.java @@ -21,6 +21,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.javaoperatorsdk.operator.api.Public; + +@Public @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/Retry.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/Retry.java index 21f728f133..310e5392f7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/Retry.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/Retry.java @@ -15,6 +15,9 @@ */ package io.javaoperatorsdk.operator.processing.retry; +import io.javaoperatorsdk.operator.api.Public; + +@Public @FunctionalInterface public interface Retry { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java index a644a274ba..a4914acac7 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/retry/RetryExecution.java @@ -18,8 +18,10 @@ import java.time.Duration; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.reconciler.RetryInfo; +@Public public interface RetryExecution extends RetryInfo { /** diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java index 288b937c98..54e08780b0 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java @@ -39,8 +39,10 @@ import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.utils.Utils; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider; +@Public public abstract class AbstractOperatorExtension implements HasKubernetesClient, BeforeAllCallback, diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java index 84e5442096..e44f20f238 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java @@ -36,7 +36,9 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; +import io.javaoperatorsdk.operator.api.Public; +@Public public class ClusterDeployedOperatorExtension extends AbstractOperatorExtension { private static final Logger LOGGER = diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultNamespaceNameSupplier.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultNamespaceNameSupplier.java index 680c6e6f00..bbb1a20e83 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultNamespaceNameSupplier.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultNamespaceNameSupplier.java @@ -22,9 +22,11 @@ import org.junit.jupiter.api.extension.ExtensionContext; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; +import io.javaoperatorsdk.operator.api.Public; import static io.javaoperatorsdk.operator.junit.AbstractOperatorExtension.MAX_NAMESPACE_NAME_LENGTH; +@Public public class DefaultNamespaceNameSupplier implements Function { public static final int RANDOM_SUFFIX_LENGTH = 5; diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultPerClassNamespaceNameSupplier.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultPerClassNamespaceNameSupplier.java index cc41f01c83..4be7a98290 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultPerClassNamespaceNameSupplier.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/DefaultPerClassNamespaceNameSupplier.java @@ -22,11 +22,13 @@ import org.junit.jupiter.api.extension.ExtensionContext; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; +import io.javaoperatorsdk.operator.api.Public; import static io.javaoperatorsdk.operator.junit.AbstractOperatorExtension.MAX_NAMESPACE_NAME_LENGTH; import static io.javaoperatorsdk.operator.junit.DefaultNamespaceNameSupplier.DELIMITER; import static io.javaoperatorsdk.operator.junit.DefaultNamespaceNameSupplier.RANDOM_SUFFIX_LENGTH; +@Public public class DefaultPerClassNamespaceNameSupplier implements Function { public static final int MAX_CLASS_NAME_LENGTH = diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java index 2904983608..a5da9fa00c 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java @@ -16,7 +16,9 @@ package io.javaoperatorsdk.operator.junit; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.Public; +@Public public interface HasKubernetesClient { /** * Returns the main Kubernetes client that is used to deploy the operator to the cluster. diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/InClusterCurl.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/InClusterCurl.java index 8b00188bc3..b83e32d274 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/InClusterCurl.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/InClusterCurl.java @@ -21,10 +21,12 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.extended.run.RunConfigBuilder; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; +import io.javaoperatorsdk.operator.api.Public; import static java.util.concurrent.TimeUnit.MINUTES; import static org.awaitility.Awaitility.await; +@Public public class InClusterCurl { private final KubernetesClient client; diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java index 2b2c3bec48..6f2734653f 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java @@ -49,6 +49,7 @@ import io.javaoperatorsdk.operator.Operator; import io.javaoperatorsdk.operator.ReconcilerUtilsInternal; import io.javaoperatorsdk.operator.RegisteredController; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider; import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @@ -57,6 +58,7 @@ import static io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider.override; @SuppressWarnings("rawtypes") +@Public public class LocallyRunOperatorExtension extends AbstractOperatorExtension { private static final Logger LOGGER = LoggerFactory.getLogger(LocallyRunOperatorExtension.class); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigLoader.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigLoader.java index d66b9139d4..6d8a864b42 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigLoader.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigLoader.java @@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.ConfigurationServiceOverrider; import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider; import io.javaoperatorsdk.operator.api.config.LeaderElectionConfigurationBuilder; @@ -33,6 +34,7 @@ import io.javaoperatorsdk.operator.processing.event.rate.LinearRateLimiter; import io.javaoperatorsdk.operator.processing.retry.GenericRetry; +@Public public class ConfigLoader { private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigProvider.java index 000131ff3b..c7b7138ac6 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/ConfigProvider.java @@ -17,6 +17,9 @@ import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; + +@Public public interface ConfigProvider { /** diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/AggregatePriorityListConfigProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/AggregatePriorityListConfigProvider.java index 081e14302f..def6f0f348 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/AggregatePriorityListConfigProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/AggregatePriorityListConfigProvider.java @@ -18,12 +18,14 @@ import java.util.List; import java.util.Optional; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.config.loader.ConfigProvider; /** * A {@link ConfigProvider} that delegates to an ordered list of providers. Providers are queried in * list order; the first non-empty result wins. */ +@Public public class AggregatePriorityListConfigProvider implements ConfigProvider { private final List providers; diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/EnvVarConfigProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/EnvVarConfigProvider.java index 916ee6391d..f57935f88a 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/EnvVarConfigProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/EnvVarConfigProvider.java @@ -18,6 +18,7 @@ import java.util.Optional; import java.util.function.Function; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.config.loader.ConfigProvider; /** @@ -30,6 +31,7 @@ *

Supported value types are: {@link String}, {@link Boolean}, {@link Integer}, {@link Long}, * {@link Double}, and {@link java.time.Duration} (ISO-8601 format, e.g. {@code PT30S}). */ +@Public public class EnvVarConfigProvider implements ConfigProvider { private final Function envLookup; diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/PropertiesConfigProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/PropertiesConfigProvider.java index 8670b88f06..7e25f437c3 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/PropertiesConfigProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/PropertiesConfigProvider.java @@ -26,6 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.config.loader.ConfigProvider; /** @@ -35,6 +36,7 @@ * String}, {@link Boolean}, {@link Integer}, {@link Long}, {@link Double}, and {@link * java.time.Duration} (ISO-8601 format, e.g. {@code PT30S}). */ +@Public public class PropertiesConfigProvider implements ConfigProvider { private static final Logger log = LoggerFactory.getLogger(PropertiesConfigProvider.class); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/YamlConfigProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/YamlConfigProvider.java index fc80e46a43..fb98b29cc8 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/YamlConfigProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/loader/provider/YamlConfigProvider.java @@ -26,6 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.config.loader.ConfigProvider; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,6 +41,7 @@ * types are: {@link String}, {@link Boolean}, {@link Integer}, {@link Long}, {@link Double}, and * {@link java.time.Duration} (ISO-8601 format, e.g. {@code PT30S}). */ +@Public public class YamlConfigProvider implements ConfigProvider { private static final Logger log = LoggerFactory.getLogger(YamlConfigProvider.class); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java index a1d88975ad..1b457fd8c8 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java @@ -16,11 +16,13 @@ package io.javaoperatorsdk.operator.config.runtime; import io.fabric8.kubernetes.api.model.HasMetadata; +import io.javaoperatorsdk.operator.api.Public; import io.javaoperatorsdk.operator.api.config.BaseConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.ResolvedControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +@Public public class DefaultConfigurationService extends BaseConfigurationService { @Override From e6350ad72040725b7da1642a4464fd8b32a1ac17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 18 Jun 2026 15:27:35 +0200 Subject: [PATCH 7/8] docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../en/docs/documentation/api-stability.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/content/en/docs/documentation/api-stability.md diff --git a/docs/content/en/docs/documentation/api-stability.md b/docs/content/en/docs/documentation/api-stability.md new file mode 100644 index 0000000000..2c69845782 --- /dev/null +++ b/docs/content/en/docs/documentation/api-stability.md @@ -0,0 +1,70 @@ +--- +title: Public API and versioning +weight: 58 +--- + +The Java Operator SDK (JOSDK) follows [semantic versioning](https://semver.org/). The +guarantees that come with semantic versioning — most importantly, that no breaking changes are +introduced in minor or patch releases — apply to the **public API** only. To make it explicit +which parts of the codebase are part of that public API, JOSDK uses a small set of source-level +annotations. + +## `@Public` + +Types that are part of the public API are marked with +[`@Public`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Public.java). +Such API is subject to semantic versioning: it will not be changed in a backwards-incompatible way +within a major version. + +Marking a type with `@Public` is enough — it means that all of its public members (methods and +fields) are part of the public API. There is no need to annotate the individual members. + +```java +@Public +public interface Reconciler

{ + // ... +} +``` + +## `@Internal` + +Everything that is **not** marked with `@Public` should be considered internal: it may change or be +removed at any time, in any release, and should not be relied upon by end users. + +The +[`@Internal`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Internal.java) +annotation is used as an *exception marker*: it flags a member (or nested type) of an otherwise +`@Public` type as internal, signalling that the member is not covered by the semantic-versioning +guarantees even though the enclosing type is. It is not meant to be put on every internal class +— internal classes are simply left without the `@Public` annotation. + +A typical case is a public type that has to expose framework callbacks (for example, methods invoked +by the underlying informer or by the framework's eventing machinery) which operator authors are never +expected to call themselves: + +```java +@Public +public class InformerEventSource // ... + implements ResourceEventHandler { + + @Override + @Internal // called by the informer, not by end users + public void onAdd(R newResource) { + // ... + } +} +``` + +## `@Experimental` + +[`@Experimental`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Experimental.java) +marks API that is available and intended to be maintained, but is not yet stable. Such API may still +change between releases — usually based on user feedback — even though it is technically +reachable. Experimental API is therefore **not** subject to the semantic-versioning guarantees and is +not marked `@Public`. + +## Note for contributors + +When you add new API that is meant to be used by operator authors, annotate the type with `@Public` +so that it becomes part of the versioning contract. If a public type exposes a member that is only +there for internal use, mark that member with `@Internal`. Leave purely internal classes unannotated. From e6dabe6dd20eba5c7311c3933f85893540751b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 18 Jun 2026 15:33:21 +0200 Subject: [PATCH 8/8] wip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../javaoperatorsdk/operator/processing/event/EventHandler.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java index 9f07ee385f..07ce0aeb9b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventHandler.java @@ -15,8 +15,6 @@ */ package io.javaoperatorsdk.operator.processing.event; -import io.javaoperatorsdk.operator.api.Public; - public interface EventHandler { void handleEvent(Event event);