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 1283896a42..9680bc7e8d 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
@@ -213,8 +213,9 @@ public
RegisteredController
register(Reconciler
re
controllerManager.add(controller);
- final var watchedNS = configuration.watchAllNamespaces() ? "[all namespaces]"
- : configuration.getEffectiveNamespaces();
+ final var informerConfig = configuration.getInformerConfig();
+ final var watchedNS = informerConfig.watchAllNamespaces() ? "[all namespaces]"
+ : informerConfig.getEffectiveNamespaces(configuration);
log.info(
"Registered reconciler: '{}' for resource: '{}' for namespace(s): {}",
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 20beef7f90..4204cb6faf 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
@@ -280,7 +280,7 @@ private
ResolvedControllerConfiguration
controllerCon
.buildForController();
return new ResolvedControllerConfiguration
(
- resourceClass, name, generationAware,
+ name, generationAware,
associatedReconcilerClass, retry, rateLimiter,
ResolvedControllerConfiguration.getMaxReconciliationInterval(interval, timeUnit),
valueOrDefaultFromAnnotation(annotation,
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 0bd1607213..ff06ad338f 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
@@ -364,7 +364,7 @@ default ExecutorServiceManager getExecutorServiceManager() {
* SSA based create/update can be still used with the legacy matching, just overriding the match
* method of Kubernetes Dependent Resource.
*
- * @return if SSA should be used for dependent resources
+ * @return {@code true} if SSA should be used for dependent resources, {@code false} otherwise
* @since 4.4.0
*/
default boolean ssaBasedCreateUpdateMatchForDependentResources() {
@@ -395,6 +395,8 @@ default Set> defaultNonSSAResource() {
*
* @return if special annotation should be used for dependent resource to filter events
* @since 4.5.0
+ *
+ * @return if special annotation should be used for dependent resource to filter events
*/
default boolean previousAnnotationForDependentResourcesEventFiltering() {
return true;
@@ -411,6 +413,8 @@ default boolean previousAnnotationForDependentResourcesEventFiltering() {
*
* @return if resource version should be parsed (as integer)
* @since 4.5.0
+ *
+ * @return if resource version should be parsed (as integer)
*/
default boolean parseResourceVersionsForEventFilteringAndCaching() {
return false;
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 aa74d7ea1a..e03cf5626e 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
@@ -14,7 +14,7 @@
import io.javaoperatorsdk.operator.processing.retry.GenericRetry;
import io.javaoperatorsdk.operator.processing.retry.Retry;
-public interface ControllerConfiguration extends ResourceConfiguration
{
+public interface ControllerConfiguration
extends Informable
{
@SuppressWarnings("rawtypes")
RateLimiter DEFAULT_RATE_LIMITER = LinearRateLimiter.deactivatedRateLimiter();
@@ -74,19 +74,9 @@ default Optional maxReconciliationInterval() {
ConfigurationService getConfigurationService();
- @SuppressWarnings("unchecked")
- @Override
- default Class getResourceClass() {
- // note that this implementation at the end not used within the boundaries of the core
- // framework, should be removed in the future, (and marked as an API changed, or behavior
- // change)
- return (Class
) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(),
- ControllerConfiguration.class);
- }
-
@SuppressWarnings("unused")
default Set getEffectiveNamespaces() {
- return ResourceConfiguration.super.getEffectiveNamespaces(this);
+ return getInformerConfig().getEffectiveNamespaces(this);
}
/**
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 423867107a..3d3eef5990 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
@@ -35,15 +35,8 @@ public class ControllerConfigurationOverrider {
private ControllerConfigurationOverrider(ControllerConfiguration original) {
this.finalizer = original.getFinalizerName();
this.generationAware = original.isGenerationAware();
- this.config = InformerConfiguration.builder(original.getResourceClass())
- .withName(name)
- .withNamespaces(original.getNamespaces())
- .withLabelSelector(original.getLabelSelector())
- .withOnAddFilter(original.onAddFilter().orElse(null))
- .withOnUpdateFilter(original.onUpdateFilter().orElse(null))
- .withGenericFilter(original.genericFilter().orElse(null))
- .withInformerListLimit(original.getInformerListLimit().orElse(null))
- .withItemStore(original.getItemStore().orElse(null));
+ final var informerConfig = original.getInformerConfig();
+ this.config = InformerConfiguration.builder(informerConfig);
this.retry = original.getRetry();
this.reconciliationMaxInterval = original.maxReconciliationInterval().orElse(null);
this.original = original;
@@ -194,7 +187,7 @@ public ControllerConfigurationOverrider replacingNamedDependentResourceConfig
}
public ControllerConfiguration build() {
- return new ResolvedControllerConfiguration<>(original.getResourceClass(),
+ return new ResolvedControllerConfiguration<>(
name,
generationAware, original.getAssociatedReconcilerClassName(), retry, rateLimiter,
reconciliationMaxInterval,
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceConfiguration.java
deleted file mode 100644
index c0d725f746..0000000000
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/DefaultResourceConfiguration.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package io.javaoperatorsdk.operator.api.config;
-
-
-import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
-import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.javaoperatorsdk.operator.ReconcilerUtils;
-import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
-
-public class DefaultResourceConfiguration
- implements ResourceConfiguration {
-
- private final Class resourceClass;
- private final String resourceTypeName;
- private final InformerConfiguration informerConfig;
-
- protected DefaultResourceConfiguration(Class resourceClass,
- InformerConfiguration informerConfig) {
- this.resourceClass = resourceClass;
- this.resourceTypeName = resourceClass.isAssignableFrom(GenericKubernetesResource.class)
- // in general this is irrelevant now for secondary resources it is used just by controller
- // where GenericKubernetesResource now does not apply
- ? GenericKubernetesResource.class.getSimpleName()
- : ReconcilerUtils.getResourceTypeName(resourceClass);
- this.informerConfig = informerConfig;
- }
-
- @Override
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- @Override
- public Class getResourceClass() {
- return resourceClass;
- }
-
- @Override
- public InformerConfiguration getInformerConfig() {
- return informerConfig;
- }
-}
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
new file mode 100644
index 0000000000..5b58836483
--- /dev/null
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Informable.java
@@ -0,0 +1,18 @@
+package io.javaoperatorsdk.operator.api.config;
+
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
+
+public interface Informable {
+
+ default String getResourceTypeName() {
+ return getInformerConfig().getResourceTypeName();
+ }
+
+ InformerConfiguration getInformerConfig();
+
+ default Class getResourceClass() {
+ return getInformerConfig().getResourceClass();
+ }
+}
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 9bb7efb5cf..7e8415f584 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
@@ -16,9 +16,9 @@
@SuppressWarnings("rawtypes")
public class ResolvedControllerConfiguration
- extends DefaultResourceConfiguration
implements io.javaoperatorsdk.operator.api.config.ControllerConfiguration
{
+ private final InformerConfiguration
informerConfig;
private final String name;
private final boolean generationAware;
private final String associatedReconcilerClassName;
@@ -31,8 +31,8 @@ public class ResolvedControllerConfiguration
private final String fieldManager;
private WorkflowSpec workflowSpec;
- public ResolvedControllerConfiguration(Class
resourceClass, ControllerConfiguration
other) {
- this(resourceClass, other.getName(), other.isGenerationAware(),
+ public ResolvedControllerConfiguration(ControllerConfiguration
other) {
+ this(other.getName(), other.isGenerationAware(),
other.getAssociatedReconcilerClassName(), other.getRetry(), other.getRateLimiter(),
other.maxReconciliationInterval().orElse(null),
other.getFinalizerName(), Collections.emptyMap(),
@@ -42,7 +42,7 @@ public ResolvedControllerConfiguration(Class
resourceClass, ControllerConfigu
other.getWorkflowSpec().orElse(null));
}
- public ResolvedControllerConfiguration(Class
resourceClass, String name,
+ public ResolvedControllerConfiguration(String name,
boolean generationAware, String associatedReconcilerClassName, Retry retry,
RateLimiter rateLimiter, Duration maxReconciliationInterval,
String finalizer,
@@ -51,19 +51,19 @@ public ResolvedControllerConfiguration(Class
resourceClass, String name,
ConfigurationService configurationService,
InformerConfiguration
informerConfig,
WorkflowSpec workflowSpec) {
- this(resourceClass, name, generationAware, associatedReconcilerClassName, retry, rateLimiter,
+ this(name, generationAware, associatedReconcilerClassName, retry, rateLimiter,
maxReconciliationInterval, finalizer, configurations, fieldManager,
configurationService, informerConfig);
setWorkflowSpec(workflowSpec);
}
- protected ResolvedControllerConfiguration(Class
resourceClass, String name,
+ protected ResolvedControllerConfiguration(String name,
boolean generationAware, String associatedReconcilerClassName, Retry retry,
RateLimiter rateLimiter, Duration maxReconciliationInterval, String finalizer,
Map configurations,
String fieldManager,
ConfigurationService configurationService, InformerConfiguration informerConfig) {
- super(resourceClass, informerConfig);
+ this.informerConfig = informerConfig;
this.configurationService = configurationService;
this.name = ControllerConfiguration.ensureValidName(name, associatedReconcilerClassName);
this.generationAware = generationAware;
@@ -79,11 +79,16 @@ protected ResolvedControllerConfiguration(Class
resourceClass, String name,
protected ResolvedControllerConfiguration(Class
resourceClass, String name,
Class extends Reconciler> reconcilerClas, ConfigurationService configurationService) {
- this(resourceClass, name, false, getAssociatedReconcilerClassName(reconcilerClas), null, null,
+ this(name, false, getAssociatedReconcilerClassName(reconcilerClas), null, null,
null, null, null, null, configurationService,
InformerConfiguration.builder(resourceClass).buildForController());
}
+ @Override
+ public InformerConfiguration
getInformerConfig() {
+ return informerConfig;
+ }
+
public static Duration getMaxReconciliationInterval(long interval, TimeUnit timeUnit) {
return interval > 0 ? Duration.of(interval, timeUnit.toChronoUnit()) : null;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java
deleted file mode 100644
index cac44c93db..0000000000
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResourceConfiguration.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package io.javaoperatorsdk.operator.api.config;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.fabric8.kubernetes.client.informers.cache.ItemStore;
-import io.javaoperatorsdk.operator.OperatorException;
-import io.javaoperatorsdk.operator.ReconcilerUtils;
-import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
-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;
-import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
-import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;
-
-import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET;
-import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE_SET;
-
-public interface ResourceConfiguration {
-
- default String getResourceTypeName() {
- return ReconcilerUtils.getResourceTypeName(getResourceClass());
- }
-
- InformerConfiguration getInformerConfig();
-
- default Optional> onAddFilter() {
- return Optional.ofNullable(getInformerConfig().getOnAddFilter());
- }
-
- default Optional> onUpdateFilter() {
- return Optional.ofNullable(getInformerConfig().getOnUpdateFilter());
- }
-
- default Optional> genericFilter() {
- return Optional.ofNullable(getInformerConfig().getGenericFilter());
- }
-
- /**
- * Retrieves the label selector that is used to filter which resources are actually watched by the
- * associated event source. See the official documentation on the
- * topic
- * for more details on syntax.
- *
- * @return the label selector filtering watched resources
- */
- default String getLabelSelector() {
- return getInformerConfig().getLabelSelector();
- }
-
- static String ensureValidLabelSelector(String labelSelector) {
- // might want to implement validation here?
- return labelSelector;
- }
-
- @SuppressWarnings("unchecked")
- default Class getResourceClass() {
- return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(),
- ResourceConfiguration.class);
- }
-
- default Set getNamespaces() {
- return getInformerConfig().getNamespaces();
- }
-
- default boolean watchAllNamespaces() {
- return allNamespacesWatched(getNamespaces());
- }
-
- static boolean allNamespacesWatched(Set namespaces) {
- failIfNotValid(namespaces);
- return DEFAULT_NAMESPACES_SET.equals(namespaces);
- }
-
- default boolean watchCurrentNamespace() {
- return currentNamespaceWatched(getNamespaces());
- }
-
- static boolean currentNamespaceWatched(Set namespaces) {
- failIfNotValid(namespaces);
- return WATCH_CURRENT_NAMESPACE_SET.equals(namespaces);
- }
-
- static void failIfNotValid(Set namespaces) {
- if (namespaces != null && !namespaces.isEmpty()) {
- final var present = namespaces.contains(Constants.WATCH_CURRENT_NAMESPACE)
- || namespaces.contains(Constants.WATCH_ALL_NAMESPACES);
- if (!present || namespaces.size() == 1) {
- return;
- }
- }
- throw new IllegalArgumentException(
- "Must specify namespaces. To watch all namespaces, use only '"
- + Constants.WATCH_ALL_NAMESPACES
- + "'. To watch only the namespace in which the operator is deployed, use only '"
- + Constants.WATCH_CURRENT_NAMESPACE + "'");
- }
-
- static Set ensureValidNamespaces(Collection namespaces) {
- if (namespaces != null && !namespaces.isEmpty()) {
- return namespaces.stream().map(String::trim).collect(Collectors.toSet());
- } else {
- return Constants.DEFAULT_NAMESPACES_SET;
- }
- }
-
- /**
- * Computes the effective namespaces based on the set specified by the user, in particular
- * retrieves the current namespace from the client when the user specified that they wanted to
- * watch the current namespace only.
- *
- * @return a Set of namespace names the associated controller will watch
- */
- default Set getEffectiveNamespaces(ControllerConfiguration> controllerConfiguration) {
- var targetNamespaces = getNamespaces();
- if (watchCurrentNamespace()) {
- final String namespace =
- controllerConfiguration.getConfigurationService().getKubernetesClient().getConfiguration()
- .getNamespace();
- if (namespace == null) {
- throw new OperatorException(
- "Couldn't retrieve the currently connected namespace. Make sure it's correctly set in your ~/.kube/config file, using, e.g. 'kubectl config set-context --namespace='");
- }
- targetNamespaces = Collections.singleton(namespace);
- }
- return targetNamespaces;
- }
-
- /**
- * Replaces the item store in informer. See underlying method
- * in fabric8 client informer implementation.
- *
- *
- * The main goal, is to be able to use limited caches or provide any custom implementation.
- *
- *
- *
- * See {@link BoundedItemStore} and CaffeineBoundedCache
- *
- *
- * @return Optional {@link ItemStore} implementation. If present this item store will be used by
- * the informers.
- */
- default Optional> getItemStore() {
- return Optional.ofNullable(getInformerConfig().getItemStore());
- }
-
- /**
- * The maximum amount of items to return for a single list call when starting an informer. If this
- * is a not null it will result in paginating for the initial load of the informer cache.
- */
- default Optional getInformerListLimit() {
- return Optional.ofNullable(getInformerConfig().getInformerListLimit());
- }
-}
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 363200bea5..57da4f41a6 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
@@ -13,7 +13,7 @@
import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;
-import static io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration.DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE;
+import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_LONG_VALUE_SET;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.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 0cb6892ebe..8d7b232889 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
@@ -1,12 +1,19 @@
package io.javaoperatorsdk.operator.api.config.informer;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Set;
+import java.util.stream.Collectors;
+import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
-import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
+import io.javaoperatorsdk.operator.OperatorException;
+import io.javaoperatorsdk.operator.ReconcilerUtils;
+import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.config.Utils;
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;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
@@ -18,6 +25,8 @@
@SuppressWarnings("unused")
public class InformerConfiguration {
private final Builder builder = new Builder();
+ private final Class resourceClass;
+ private final String resourceTypeName;
private String name;
private Set namespaces;
private Boolean followControllerNamespacesOnChange;
@@ -29,11 +38,12 @@ public class InformerConfiguration {
private ItemStore itemStore;
private Long informerListLimit;
- public InformerConfiguration(String name, Set namespaces,
+ protected InformerConfiguration(Class resourceClass, String name, Set namespaces,
boolean followControllerNamespacesOnChange,
String labelSelector, OnAddFilter super R> onAddFilter,
OnUpdateFilter super R> onUpdateFilter, OnDeleteFilter super R> onDeleteFilter,
GenericFilter super R> genericFilter, ItemStore itemStore, Long informerListLimit) {
+ this(resourceClass);
this.name = name;
this.namespaces = namespaces;
this.followControllerNamespacesOnChange = followControllerNamespacesOnChange;
@@ -46,28 +56,80 @@ public InformerConfiguration(String name, Set namespaces,
this.informerListLimit = informerListLimit;
}
- private InformerConfiguration() {}
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- public static InformerConfiguration.Builder builder() {
- return new InformerConfiguration().builder;
+ private InformerConfiguration(Class resourceClass) {
+ this.resourceClass = resourceClass;
+ this.resourceTypeName = resourceClass.isAssignableFrom(GenericKubernetesResource.class)
+ // in general this is irrelevant now for secondary resources it is used just by controller
+ // where GenericKubernetesResource now does not apply
+ ? GenericKubernetesResource.class.getSimpleName()
+ : ReconcilerUtils.getResourceTypeName(resourceClass);
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static InformerConfiguration.Builder builder(
Class resourceClass) {
- return new InformerConfiguration().builder;
+ return new InformerConfiguration(resourceClass).builder;
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static InformerConfiguration.Builder builder(
InformerConfiguration original) {
- return new InformerConfiguration(original.name, original.namespaces,
+ return new InformerConfiguration(original.resourceClass, original.name, original.namespaces,
original.followControllerNamespacesOnChange, original.labelSelector, original.onAddFilter,
original.onUpdateFilter, original.onDeleteFilter, original.genericFilter,
original.itemStore, original.informerListLimit).builder;
}
+ public static String ensureValidLabelSelector(String labelSelector) {
+ // might want to implement validation here?
+ return labelSelector;
+ }
+
+ public static boolean allNamespacesWatched(Set namespaces) {
+ failIfNotValid(namespaces);
+ return DEFAULT_NAMESPACES_SET.equals(namespaces);
+ }
+
+ public static boolean currentNamespaceWatched(Set namespaces) {
+ failIfNotValid(namespaces);
+ return WATCH_CURRENT_NAMESPACE_SET.equals(namespaces);
+ }
+
+ public static void failIfNotValid(Set namespaces) {
+ if (namespaces != null && !namespaces.isEmpty()) {
+ final var present = namespaces.contains(WATCH_CURRENT_NAMESPACE)
+ || namespaces.contains(WATCH_ALL_NAMESPACES);
+ if (!present || namespaces.size() == 1) {
+ return;
+ }
+ }
+ throw new IllegalArgumentException(
+ "Must specify namespaces. To watch all namespaces, use only '"
+ + WATCH_ALL_NAMESPACES
+ + "'. To watch only the namespace in which the operator is deployed, use only '"
+ + WATCH_CURRENT_NAMESPACE + "'");
+ }
+
+ public static Set ensureValidNamespaces(Collection namespaces) {
+ if (namespaces != null && !namespaces.isEmpty()) {
+ return namespaces.stream().map(String::trim).collect(Collectors.toSet());
+ } else {
+ return Constants.DEFAULT_NAMESPACES_SET;
+ }
+ }
+
+ public static boolean inheritsNamespacesFromController(Set namespaces) {
+ return SAME_AS_CONTROLLER_NAMESPACES_SET.equals(namespaces);
+ }
+
+ public Class getResourceClass() {
+ return resourceClass;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
public String getName() {
return name;
}
@@ -76,10 +138,64 @@ public Set getNamespaces() {
return namespaces;
}
+ public boolean watchAllNamespaces() {
+ return InformerConfiguration.allNamespacesWatched(getNamespaces());
+ }
+
+ public boolean watchCurrentNamespace() {
+ return InformerConfiguration.currentNamespaceWatched(getNamespaces());
+ }
+
+ public boolean inheritsNamespacesFromController() {
+ return inheritsNamespacesFromController(getNamespaces());
+ }
+
+ /**
+ * Computes the effective namespaces based on the set specified by the user, in particular
+ * retrieves the current namespace from the client when the user specified that they wanted to
+ * watch the current namespace only.
+ *
+ * @return a Set of namespace names the associated controller will watch
+ */
+ public Set getEffectiveNamespaces(ControllerConfiguration> controllerConfiguration) {
+ if (inheritsNamespacesFromController()) {
+ return controllerConfiguration.getEffectiveNamespaces();
+ }
+
+ var targetNamespaces = getNamespaces();
+ if (watchCurrentNamespace()) {
+ final String namespace =
+ controllerConfiguration.getConfigurationService().getKubernetesClient().getConfiguration()
+ .getNamespace();
+ if (namespace == null) {
+ throw new OperatorException(
+ "Couldn't retrieve the currently connected namespace. Make sure it's correctly set in your ~/.kube/config file, using, e.g. 'kubectl config set-context --namespace='");
+ }
+ targetNamespaces = Collections.singleton(namespace);
+ }
+ return targetNamespaces;
+ }
+
+ /**
+ * Used in case the watched namespaces are changed dynamically, thus when operator is running (See
+ * {@link io.javaoperatorsdk.operator.RegisteredController}). If true, changing the target
+ * namespaces of a controller would result to change target namespaces for the
+ * InformerEventSource.
+ *
+ * @return if namespace changes should be followed
+ */
public boolean isFollowControllerNamespacesOnChange() {
return followControllerNamespacesOnChange;
}
+ /**
+ * Retrieves the label selector that is used to filter which resources are actually watched by the
+ * associated informer. See the official documentation on the
+ * topic
+ * for more details on syntax.
+ *
+ * @return the label selector filtering watched resources
+ */
public String getLabelSelector() {
return labelSelector;
}
@@ -100,10 +216,31 @@ public GenericFilter super R> getGenericFilter() {
return genericFilter;
}
+ /**
+ * Replaces the item store in informer. See underlying method
+ * in fabric8 client informer implementation.
+ *
+ *
+ * The main goal, is to be able to use limited caches or provide any custom implementation.
+ *
+ *
+ *
+ * See {@link BoundedItemStore} and CaffeineBoundedCache
+ *
+ *
+ * @return Optional {@link ItemStore} implementation. If present this item store will be used by
+ * the informers.
+ */
public ItemStore getItemStore() {
return itemStore;
}
+ /**
+ * The maximum amount of items to return for a single list call when starting an informer. If this
+ * is a not null it will result in paginating for the initial load of the informer cache.
+ */
public Long getInformerListLimit() {
return informerListLimit;
}
@@ -116,9 +253,11 @@ public InformerConfiguration buildForController() {
// if the informer config uses the default "same as controller" value, reset the namespaces to
// the default set for controllers
if (namespaces == null || namespaces.isEmpty()
- || InformerEventSourceConfiguration.inheritsNamespacesFromController(namespaces)) {
+ || inheritsNamespacesFromController(namespaces)) {
namespaces = Constants.DEFAULT_NAMESPACES_SET;
}
+ // to avoid potential NPE
+ followControllerNamespacesOnChange = false;
return InformerConfiguration.this;
}
@@ -128,7 +267,7 @@ public InformerConfiguration buildForInformerEventSource() {
}
if (followControllerNamespacesOnChange == null) {
followControllerNamespacesOnChange =
- InformerEventSourceConfiguration.DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE;
+ DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE;
}
return InformerConfiguration.this;
}
@@ -184,7 +323,7 @@ public Builder withName(String name) {
public Builder withNamespaces(Set namespaces) {
InformerConfiguration.this.namespaces =
- ResourceConfiguration.ensureValidNamespaces(namespaces);
+ ensureValidNamespaces(namespaces);
return this;
}
@@ -239,7 +378,7 @@ public Builder withFollowControllerNamespacesOnChange(boolean followChanges) {
public Builder withLabelSelector(String labelSelector) {
InformerConfiguration.this.labelSelector =
- ResourceConfiguration.ensureValidLabelSelector(labelSelector);
+ ensureValidLabelSelector(labelSelector);
return this;
}
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 1e5e1ce666..20e6c7f131 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
@@ -2,31 +2,18 @@
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
import java.util.function.Consumer;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
-import io.javaoperatorsdk.operator.api.config.DefaultResourceConfiguration;
-import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
-import io.javaoperatorsdk.operator.api.config.Utils;
+import io.javaoperatorsdk.operator.api.config.Informable;
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
import io.javaoperatorsdk.operator.processing.event.source.PrimaryToSecondaryMapper;
import io.javaoperatorsdk.operator.processing.event.source.SecondaryToPrimaryMapper;
-import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;
-import static io.javaoperatorsdk.operator.api.reconciler.Constants.SAME_AS_CONTROLLER_NAMESPACES_SET;
-
public interface InformerEventSourceConfiguration
- extends ResourceConfiguration {
-
- boolean DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE = true;
-
- static boolean inheritsNamespacesFromController(Set namespaces) {
- return SAME_AS_CONTROLLER_NAMESPACES_SET.equals(namespaces);
- }
+ extends Informable {
static Builder from(
Class resourceClass, Class extends HasMetadata> primaryResourceClass) {
@@ -62,10 +49,6 @@ default boolean followControllerNamespaceChanges() {
*/
SecondaryToPrimaryMapper getSecondaryToPrimaryMapper();
- default Optional> onDeleteFilter() {
- return Optional.ofNullable(getInformerConfig().getOnDeleteFilter());
- }
-
PrimaryToSecondaryMapper
getPrimaryToSecondaryMapper();
Optional getGroupVersionKind();
@@ -74,39 +57,32 @@ default String name() {
return getInformerConfig().getName();
}
- @SuppressWarnings("unchecked")
- @Override
- default Class getResourceClass() {
- return (Class) Utils.getFirstTypeArgumentFromSuperClassOrInterface(getClass(),
- InformerEventSourceConfiguration.class);
- }
-
- class DefaultInformerEventSourceConfiguration extends
- DefaultResourceConfiguration implements InformerEventSourceConfiguration {
+ class DefaultInformerEventSourceConfiguration
+ implements InformerEventSourceConfiguration {
private final PrimaryToSecondaryMapper> primaryToSecondaryMapper;
private final SecondaryToPrimaryMapper secondaryToPrimaryMapper;
private final GroupVersionKind groupVersionKind;
+ private final InformerConfiguration informerConfig;
protected DefaultInformerEventSourceConfiguration(
- Class resourceClass,
GroupVersionKind groupVersionKind,
PrimaryToSecondaryMapper> primaryToSecondaryMapper,
SecondaryToPrimaryMapper secondaryToPrimaryMapper,
InformerConfiguration informerConfig) {
- super(resourceClass, informerConfig);
+ this.informerConfig = Objects.requireNonNull(informerConfig);
this.groupVersionKind = groupVersionKind;
this.primaryToSecondaryMapper = primaryToSecondaryMapper;
this.secondaryToPrimaryMapper = secondaryToPrimaryMapper;
}
@Override
- public SecondaryToPrimaryMapper getSecondaryToPrimaryMapper() {
- return secondaryToPrimaryMapper;
+ public InformerConfiguration getInformerConfig() {
+ return informerConfig;
}
@Override
- public Optional> onDeleteFilter() {
- return Optional.ofNullable(getInformerConfig().getOnDeleteFilter());
+ public SecondaryToPrimaryMapper getSecondaryToPrimaryMapper() {
+ return secondaryToPrimaryMapper;
}
@Override
@@ -119,19 +95,6 @@ public PrimaryToSecondaryMapper
getPrimaryToSecondary
public Optional getGroupVersionKind() {
return Optional.ofNullable(groupVersionKind);
}
-
- public boolean inheritsNamespacesFromController() {
- return InformerEventSourceConfiguration.inheritsNamespacesFromController(getNamespaces());
- }
-
- @Override
- public Set getEffectiveNamespaces(ControllerConfiguration> controllerConfiguration) {
- if (inheritsNamespacesFromController()) {
- return controllerConfiguration.getEffectiveNamespaces();
- } else {
- return super.getEffectiveNamespaces(controllerConfiguration);
- }
- }
}
@@ -223,7 +186,7 @@ public InformerEventSourceConfiguration build() {
"If GroupVersionKind is set the resource type must be GenericKubernetesDependentResource");
}
- return new DefaultInformerEventSourceConfiguration<>(resourceClass,
+ return new DefaultInformerEventSourceConfiguration<>(
groupVersionKind,
primaryToSecondaryMapper,
Objects.requireNonNullElse(secondaryToPrimaryMapper,
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 594fcddd09..8003d8f836 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
@@ -25,6 +25,7 @@ public final class Constants {
public static final String RESOURCE_GVK_KEY = "josdk.resource.gvk";
public static final String CONTROLLER_NAME = "controller.name";
+ public static final boolean DEFAULT_FOLLOW_CONTROLLER_NAMESPACES_ON_CHANGE = true;
private Constants() {}
}
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 105d2b6c75..cc9a1dd6c3 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
@@ -6,11 +6,11 @@
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ConfiguredDependentResource;
@SuppressWarnings({"rawtypes", "unchecked"})
-public interface DependentResourceFactory> {
+public interface DependentResourceFactory, D extends DependentResourceSpec> {
DependentResourceFactory DEFAULT = new DependentResourceFactory() {};
- default DependentResource createFrom(DependentResourceSpec spec, C controllerConfiguration) {
+ default DependentResource createFrom(D spec, C controllerConfiguration) {
final var dependentResourceClass = spec.getDependentResourceClass();
return Utils.instantiateAndConfigureIfNeeded(dependentResourceClass,
DependentResource.class,
@@ -18,8 +18,7 @@ default DependentResource createFrom(DependentResourceSpec spec, C controllerCon
(instance) -> configure(instance, spec, controllerConfiguration));
}
- default void configure(DependentResource instance, DependentResourceSpec spec,
- C controllerConfiguration) {
+ default void configure(DependentResource instance, D spec, C controllerConfiguration) {
if (instance instanceof ConfiguredDependentResource configurable) {
final var config = controllerConfiguration.getConfigurationFor(spec);
if (config != null) {
@@ -27,4 +26,12 @@ default void configure(DependentResource instance, DependentResourceSpec spec,
}
}
}
+
+ default Class> associatedResourceType(D spec) {
+ final var dependentResourceClass = spec.getDependentResourceClass();
+ final var dr = Utils.instantiateAndConfigureIfNeeded(dependentResourceClass,
+ DependentResource.class,
+ null, null);
+ return dr != null ? dr.resourceType() : null;
+ }
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentConverter.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentConverter.java
index 36625b0689..3bfa8351d3 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentConverter.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentConverter.java
@@ -43,7 +43,10 @@ private InformerConfiguration createInformerConfig(
Class extends KubernetesDependentResource, ?>> dependentResourceClass =
(Class extends KubernetesDependentResource, ?>>) spec.getDependentResourceClass();
- InformerConfiguration.Builder config = InformerConfiguration.builder();
+ final var resourceType = controllerConfig.getConfigurationService().dependentResourceFactory()
+ .associatedResourceType(spec);
+
+ InformerConfiguration.Builder config = InformerConfiguration.builder(resourceType);
if (configAnnotation != null) {
final var informerConfig = configAnnotation.informer();
final var context = Utils.contextFor(controllerConfig, dependentResourceClass,
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java
index 2bb8c7a39a..174ffa0978 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceManager.java
@@ -173,16 +173,16 @@ public void broadcastOnResourceEvent(ResourceAction action, P resource, P oldRes
}
public void changeNamespaces(Set namespaces) {
- eventSources.controllerEventSource()
- .changeNamespaces(namespaces);
- executorServiceManager.boundedExecuteAndWaitForAllToComplete(eventSources
+ eventSources.controllerEventSource().changeNamespaces(namespaces);
+ final var namespaceChangeables = eventSources
.additionalEventSources()
.filter(NamespaceChangeable.class::isInstance)
.map(NamespaceChangeable.class::cast)
- .filter(NamespaceChangeable::allowsNamespaceChanges), e -> {
- e.changeNamespaces(namespaces);
- return null;
- },
+ .filter(NamespaceChangeable::allowsNamespaceChanges);
+ executorServiceManager.boundedExecuteAndWaitForAllToComplete(namespaceChangeables, e -> {
+ e.changeNamespaces(namespaces);
+ return null;
+ },
getEventSourceThreadNamer("changeNamespace"));
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java
index db457a4e41..07e5bd3fa2 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java
@@ -43,11 +43,12 @@ public ControllerEventSource(Controller controller) {
.or(onUpdateMarkedForDeletion());
// by default the on add should be processed in all cases regarding internal filters
- config.onAddFilter().ifPresent(this::setOnAddFilter);
- config.onUpdateFilter()
+ final var informerConfig = config.getInformerConfig();
+ Optional.ofNullable(informerConfig.getOnAddFilter()).ifPresent(this::setOnAddFilter);
+ Optional.ofNullable(informerConfig.getOnUpdateFilter())
.ifPresentOrElse(filter -> setOnUpdateFilter(filter.and(internalOnUpdateFilter)),
() -> setOnUpdateFilter(internalOnUpdateFilter));
- config.genericFilter().ifPresent(this::setGenericFilter);
+ Optional.ofNullable(informerConfig.getGenericFilter()).ifPresent(this::setGenericFilter);
setControllerConfiguration(config);
}
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 db3b9d6601..2568683600 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
@@ -106,10 +106,11 @@ private InformerEventSource(InformerEventSourceConfiguration configuration,
primaryToSecondaryIndex = NOOPPrimaryToSecondaryIndex.getInstance();
}
- onAddFilter = configuration.onAddFilter().orElse(null);
- onUpdateFilter = configuration.onUpdateFilter().orElse(null);
- onDeleteFilter = configuration.onDeleteFilter().orElse(null);
- genericFilter = configuration.genericFilter().orElse(null);
+ final var informerConfig = configuration.getInformerConfig();
+ onAddFilter = informerConfig.getOnAddFilter();
+ onUpdateFilter = informerConfig.getOnUpdateFilter();
+ onDeleteFilter = informerConfig.getOnDeleteFilter();
+ genericFilter = informerConfig.getGenericFilter();
}
@Override
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerManager.java
index 9fc4a7db19..57bbf2a8ce 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerManager.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerManager.java
@@ -19,7 +19,8 @@
import io.javaoperatorsdk.operator.OperatorException;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
-import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
+import io.javaoperatorsdk.operator.api.config.Informable;
+import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
import io.javaoperatorsdk.operator.health.InformerHealthIndicator;
import io.javaoperatorsdk.operator.processing.LifecycleAware;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
@@ -28,7 +29,7 @@
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_ALL_NAMESPACES;
-class InformerManager>
+class InformerManager>
implements LifecycleAware, IndexerResourceCache {
private static final Logger log = LoggerFactory.getLogger(InformerManager.class);
@@ -71,8 +72,9 @@ private void initSources() {
if (!sources.isEmpty()) {
throw new IllegalStateException("Some sources already initialized.");
}
- final var targetNamespaces = configuration.getEffectiveNamespaces(controllerConfiguration);
- if (ResourceConfiguration.allNamespacesWatched(targetNamespaces)) {
+ final var targetNamespaces =
+ configuration.getInformerConfig().getEffectiveNamespaces(controllerConfiguration);
+ if (InformerConfiguration.allNamespacesWatched(targetNamespaces)) {
var source = createEventSourceForNamespace(WATCH_ALL_NAMESPACES);
log.debug("Registered {} -> {} for any namespace", this, source);
} else {
@@ -108,13 +110,14 @@ public void changeNamespaces(Set namespaces) {
private InformerWrapper createEventSourceForNamespace(String namespace) {
final InformerWrapper source;
+ final var labelSelector = configuration.getInformerConfig().getLabelSelector();
if (namespace.equals(WATCH_ALL_NAMESPACES)) {
final var filteredBySelectorClient =
- client.inAnyNamespace().withLabelSelector(configuration.getLabelSelector());
+ client.inAnyNamespace().withLabelSelector(labelSelector);
source = createEventSource(filteredBySelectorClient, eventHandler, WATCH_ALL_NAMESPACES);
} else {
source = createEventSource(
- client.inNamespace(namespace).withLabelSelector(configuration.getLabelSelector()),
+ client.inNamespace(namespace).withLabelSelector(labelSelector),
eventHandler, namespace);
}
source.addIndexers(indexers);
@@ -124,9 +127,11 @@ private InformerWrapper createEventSourceForNamespace(String namespace) {
private InformerWrapper createEventSource(
FilterWatchListDeletable, Resource> filteredBySelectorClient,
ResourceEventHandler eventHandler, String namespaceIdentifier) {
- var informer = configuration.getInformerListLimit().map(filteredBySelectorClient::withLimit)
+ final var informerConfig = configuration.getInformerConfig();
+ var informer = Optional.ofNullable(informerConfig.getInformerListLimit())
+ .map(filteredBySelectorClient::withLimit)
.orElse(filteredBySelectorClient).runnableInformer(0);
- configuration.getItemStore().ifPresent(informer::itemStore);
+ Optional.ofNullable(informerConfig.getItemStore()).ifPresent(informer::itemStore);
var source = new InformerWrapper<>(informer, controllerConfiguration.getConfigurationService(),
namespaceIdentifier);
source.addEventHandler(eventHandler);
@@ -205,11 +210,12 @@ public List byIndex(String indexName, String indexKey) {
@Override
public String toString() {
- final var selector = configuration.getLabelSelector();
+ final var informerConfig = configuration.getInformerConfig();
+ final var selector = informerConfig.getLabelSelector();
return "InformerManager ["
+ ReconcilerUtils.getResourceTypeNameWithVersion(configuration.getResourceClass())
+ "] watching: "
- + configuration.getEffectiveNamespaces(controllerConfiguration)
+ + informerConfig.getEffectiveNamespaces(controllerConfiguration)
+ (selector != null ? " selector: " + selector : "");
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java
index 54d60e2cdf..f5e899826d 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java
@@ -17,8 +17,8 @@
import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
import io.javaoperatorsdk.operator.OperatorException;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
+import io.javaoperatorsdk.operator.api.config.Informable;
import io.javaoperatorsdk.operator.api.config.NamespaceChangeable;
-import io.javaoperatorsdk.operator.api.config.ResourceConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller;
import io.javaoperatorsdk.operator.health.InformerHealthIndicator;
import io.javaoperatorsdk.operator.health.InformerWrappingEventSourceHealthIndicator;
@@ -27,7 +27,7 @@
import io.javaoperatorsdk.operator.processing.event.source.*;
@SuppressWarnings("rawtypes")
-public abstract class ManagedInformerEventSource>
+public abstract class ManagedInformerEventSource>
extends AbstractEventSource
implements ResourceEventHandler, Cache, IndexerResourceCache,
RecentOperationCacheFiller, NamespaceChangeable,
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java
index 00733b496b..46ef56e1d4 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java
@@ -30,7 +30,7 @@
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfigBuilder;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
-import static io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration.inheritsNamespacesFromController;
+import static io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration.inheritsNamespacesFromController;
import static org.junit.jupiter.api.Assertions.*;
class ControllerConfigurationOverriderTest {
@@ -67,7 +67,7 @@ void overridingNSShouldPreserveUntouchedDependents() {
.settingNamespace(namespace)
.replacingNamedDependentResourceConfig(externalDRName, stringConfig)
.build();
- assertEquals(Set.of(namespace), configuration.getNamespaces());
+ assertEquals(Set.of(namespace), configuration.getInformerConfig().getNamespaces());
// check that we still have the proper number of dependent configs
dependentResources = configuration.getWorkflowSpec().orElseThrow().getDependentResourceSpecs();
@@ -77,12 +77,11 @@ void overridingNSShouldPreserveUntouchedDependents() {
assertEquals(stringConfig, resourceConfig);
}
- @SuppressWarnings({"unchecked", "rawtypes"})
+ @SuppressWarnings({"rawtypes"})
private KubernetesDependentResourceConfig extractFirstDependentKubernetesResourceConfig(
io.javaoperatorsdk.operator.api.config.ControllerConfiguration> configuration) {
- var conf = (KubernetesDependentResourceConfig) extractDependentKubernetesResourceConfig(
+ return (KubernetesDependentResourceConfig) extractDependentKubernetesResourceConfig(
configuration, 0);
- return conf;
}
private io.javaoperatorsdk.operator.api.config.ControllerConfiguration> createConfiguration(
@@ -93,48 +92,55 @@ private io.javaoperatorsdk.operator.api.config.ControllerConfiguration> create
@Test
void overridingNamespacesShouldWork() {
var configuration = createConfiguration(new WatchCurrentReconciler());
- assertEquals(Set.of("foo"), configuration.getNamespaces());
- assertFalse(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
+ var informerConfig = configuration.getInformerConfig();
+ assertEquals(Set.of("foo"), informerConfig.getNamespaces());
+ assertFalse(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
configuration = ControllerConfigurationOverrider.override(configuration)
.addingNamespaces("foo", "bar")
.build();
- assertEquals(Set.of("foo", "bar"), configuration.getNamespaces());
- assertFalse(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
+ informerConfig = configuration.getInformerConfig();
+ assertEquals(Set.of("foo", "bar"), informerConfig.getNamespaces());
+ assertFalse(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
configuration = ControllerConfigurationOverrider.override(configuration)
.removingNamespaces("bar")
.build();
- assertEquals(Set.of("foo"), configuration.getNamespaces());
- assertFalse(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
+ informerConfig = configuration.getInformerConfig();
+ assertEquals(Set.of("foo"), informerConfig.getNamespaces());
+ assertFalse(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
configuration = ControllerConfigurationOverrider.override(configuration)
.removingNamespaces("foo")
.build();
- assertTrue(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
+ informerConfig = configuration.getInformerConfig();
+ assertTrue(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
configuration = ControllerConfigurationOverrider.override(configuration)
.settingNamespace("foo")
.build();
- assertFalse(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
- assertEquals(Set.of("foo"), configuration.getNamespaces());
+ informerConfig = configuration.getInformerConfig();
+ assertFalse(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
+ assertEquals(Set.of("foo"), informerConfig.getNamespaces());
configuration = ControllerConfigurationOverrider.override(configuration)
.watchingOnlyCurrentNamespace()
.build();
- assertFalse(configuration.watchAllNamespaces());
- assertTrue(configuration.watchCurrentNamespace());
+ informerConfig = configuration.getInformerConfig();
+ assertFalse(informerConfig.watchAllNamespaces());
+ assertTrue(informerConfig.watchCurrentNamespace());
configuration = ControllerConfigurationOverrider.override(configuration)
.watchingAllNamespaces()
.build();
- assertTrue(configuration.watchAllNamespaces());
- assertFalse(configuration.watchCurrentNamespace());
+ informerConfig = configuration.getInformerConfig();
+ assertTrue(informerConfig.watchAllNamespaces());
+ assertFalse(informerConfig.watchCurrentNamespace());
}
@Test
@@ -144,23 +150,24 @@ void itemStorePreserved() {
configuration = ControllerConfigurationOverrider.override(configuration)
.build();
- assertNotNull(configuration.getItemStore().orElse(null));
+ assertNotNull(configuration.getInformerConfig().getItemStore());
}
@Test
void configuredDependentShouldNotChangeOnParentOverrideEvenWhenInitialConfigIsSame() {
var configuration = createConfiguration(new OverriddenNSOnDepReconciler());
// retrieve the config for the first (and unique) dependent
- var config = extractFirstDependentKubernetesResourceConfig(configuration);
+ var kubeDependentConfig = extractFirstDependentKubernetesResourceConfig(configuration);
// override the parent NS to match the dependent's
configuration = ControllerConfigurationOverrider.override(configuration)
.settingNamespace(OverriddenNSDependent.DEP_NS).build();
- assertEquals(Set.of(OverriddenNSDependent.DEP_NS), configuration.getNamespaces());
+ assertEquals(Set.of(OverriddenNSDependent.DEP_NS),
+ configuration.getInformerConfig().getNamespaces());
// check that the DependentResource inherits has its own configured NS
- var informerConfig = config.informerConfig();
- assertEquals(Set.of(OverriddenNSDependent.DEP_NS), informerConfig.getNamespaces());
+ assertEquals(Set.of(OverriddenNSDependent.DEP_NS),
+ kubeDependentConfig.informerConfig().getNamespaces());
// override the parent's NS
final var newNS = "bar";
@@ -168,9 +175,9 @@ void configuredDependentShouldNotChangeOnParentOverrideEvenWhenInitialConfigIsSa
ControllerConfigurationOverrider.override(configuration).settingNamespace(newNS).build();
// check that dependent config is still using its own NS
- config = extractFirstDependentKubernetesResourceConfig(configuration);
- informerConfig = config.informerConfig();
- assertEquals(Set.of(OverriddenNSDependent.DEP_NS), informerConfig.getNamespaces());
+ kubeDependentConfig = extractFirstDependentKubernetesResourceConfig(configuration);
+ assertEquals(Set.of(OverriddenNSDependent.DEP_NS),
+ kubeDependentConfig.informerConfig().getNamespaces());
}
@SuppressWarnings("unchecked")
@@ -182,8 +189,7 @@ void dependentShouldWatchAllNamespacesIfParentDoesAsWell() {
// check that the DependentResource inherits the controller's configuration if applicable
var informerConfig = config.informerConfig();
- assertTrue(
- inheritsNamespacesFromController(informerConfig.getNamespaces()));
+ assertTrue(inheritsNamespacesFromController(informerConfig.getNamespaces()));
}
@@ -196,7 +202,7 @@ void shouldBePossibleToForceDependentToWatchAllNamespaces() {
// check that the DependentResource inherits the controller's configuration if applicable
assertTrue(
- ResourceConfiguration
+ InformerConfiguration
.allNamespacesWatched(config.informerConfig().getNamespaces()));
// override the NS
@@ -207,12 +213,11 @@ void shouldBePossibleToForceDependentToWatchAllNamespaces() {
// check that dependent config is still configured to watch all NS
config = extractFirstDependentKubernetesResourceConfig(configuration);
assertTrue(
- ResourceConfiguration
+ InformerConfiguration
.allNamespacesWatched(config.informerConfig().getNamespaces()));
}
@Test
- @SuppressWarnings("unchecked")
void overridingNamespacesShouldBePropagatedToDependentsWithDefaultConfig() {
var configuration = createConfiguration(new OneDepReconciler());
// retrieve the config for the first (and unique) dependent
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/InformerConfigurationTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/InformerConfigurationTest.java
new file mode 100644
index 0000000000..468c67e0d7
--- /dev/null
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/InformerConfigurationTest.java
@@ -0,0 +1,83 @@
+package io.javaoperatorsdk.operator.api.config;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
+import io.javaoperatorsdk.operator.api.reconciler.Constants;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class InformerConfigurationTest {
+
+ @Test
+ void allNamespacesWatched() {
+ assertThrows(IllegalArgumentException.class,
+ () -> InformerConfiguration.allNamespacesWatched(null));
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.allNamespacesWatched(
+ Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.allNamespacesWatched(
+ Collections.emptySet()));
+ assertFalse(InformerConfiguration.allNamespacesWatched(Set.of("foo", "bar")));
+ assertTrue(InformerConfiguration.allNamespacesWatched(Set.of(Constants.WATCH_ALL_NAMESPACES)));
+ assertFalse(InformerConfiguration.allNamespacesWatched(Set.of("foo")));
+ assertFalse(
+ InformerConfiguration.allNamespacesWatched(Set.of(Constants.WATCH_CURRENT_NAMESPACE)));
+ }
+
+ @Test
+ void currentNamespaceWatched() {
+ assertThrows(IllegalArgumentException.class,
+ () -> InformerConfiguration.currentNamespaceWatched(null));
+ assertThrows(IllegalArgumentException.class,
+ () -> InformerConfiguration.currentNamespaceWatched(
+ Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
+ assertThrows(IllegalArgumentException.class,
+ () -> InformerConfiguration.currentNamespaceWatched(Collections.emptySet()));
+ assertFalse(InformerConfiguration.currentNamespaceWatched(Set.of("foo", "bar")));
+ assertFalse(
+ InformerConfiguration.currentNamespaceWatched(Set.of(Constants.WATCH_ALL_NAMESPACES)));
+ assertFalse(InformerConfiguration.currentNamespaceWatched(Set.of("foo")));
+ assertTrue(
+ InformerConfiguration.currentNamespaceWatched(Set.of(Constants.WATCH_CURRENT_NAMESPACE)));
+ }
+
+ @Test
+ void nullLabelSelectorByDefault() {
+ final var informerConfig =
+ InformerConfiguration.builder(ConfigMap.class).buildForInformerEventSource();
+ assertNull(informerConfig.getLabelSelector());
+ }
+
+ @Test
+ void shouldWatchAllNamespacesByDefaultForControllers() {
+ final var informerConfig = InformerConfiguration.builder(ConfigMap.class).buildForController();
+ assertTrue(informerConfig.watchAllNamespaces());
+ }
+
+ @Test
+ void shouldFollowControllerNamespacesByDefaultForInformerEventSource() {
+ final var informerConfig =
+ InformerConfiguration.builder(ConfigMap.class).buildForInformerEventSource();
+ assertTrue(informerConfig.isFollowControllerNamespacesOnChange());
+ }
+
+ @Test
+ void failIfNotValid() {
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.failIfNotValid(null));
+ assertThrows(IllegalArgumentException.class,
+ () -> InformerConfiguration.failIfNotValid(Collections.emptySet()));
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.failIfNotValid(
+ Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.failIfNotValid(
+ Set.of(Constants.WATCH_CURRENT_NAMESPACE, "foo")));
+ assertThrows(IllegalArgumentException.class, () -> InformerConfiguration.failIfNotValid(
+ Set.of(Constants.WATCH_ALL_NAMESPACES, "foo")));
+
+ // should work
+ InformerConfiguration.failIfNotValid(Set.of("foo", "bar"));
+ }
+}
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/MockControllerConfiguration.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/MockControllerConfiguration.java
index 6ae83294bb..afd01d0f90 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/MockControllerConfiguration.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/MockControllerConfiguration.java
@@ -1,6 +1,7 @@
package io.javaoperatorsdk.operator.api.config;
import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET;
import static org.mockito.ArgumentMatchers.any;
@@ -18,9 +19,11 @@ public static ControllerConfiguration forResource(
public static ControllerConfiguration forResource(
Class resourceType, ConfigurationService configurationService) {
final ControllerConfiguration configuration = mock(ControllerConfiguration.class);
+ final InformerConfiguration informerConfiguration = mock(InformerConfiguration.class);
+ when(configuration.getInformerConfig()).thenReturn(informerConfiguration);
when(configuration.getResourceClass()).thenReturn(resourceType);
- when(configuration.getNamespaces()).thenReturn(DEFAULT_NAMESPACES_SET);
- when(configuration.getEffectiveNamespaces(any())).thenCallRealMethod();
+ when(informerConfiguration.getNamespaces()).thenReturn(DEFAULT_NAMESPACES_SET);
+ when(informerConfiguration.getEffectiveNamespaces(any())).thenCallRealMethod();
when(configuration.getName()).thenReturn(resourceType.getSimpleName());
when(configuration.getConfigurationService()).thenReturn(configurationService);
return configuration;
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ResourceConfigurationTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ResourceConfigurationTest.java
deleted file mode 100644
index 5cf8376ea2..0000000000
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ResourceConfigurationTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package io.javaoperatorsdk.operator.api.config;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
-import io.javaoperatorsdk.operator.api.reconciler.Constants;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class ResourceConfigurationTest {
-
- public static final ResourceConfiguration DEFAULT =
- () -> InformerConfiguration.builder().buildForInformerEventSource();
-
- @Test
- void allNamespacesWatched() {
- assertThrows(IllegalArgumentException.class,
- () -> ResourceConfiguration.allNamespacesWatched(null));
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.allNamespacesWatched(
- Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.allNamespacesWatched(
- Collections.emptySet()));
- assertFalse(ResourceConfiguration.allNamespacesWatched(Set.of("foo", "bar")));
- assertTrue(ResourceConfiguration.allNamespacesWatched(Set.of(Constants.WATCH_ALL_NAMESPACES)));
- assertFalse(ResourceConfiguration.allNamespacesWatched(Set.of("foo")));
- assertFalse(
- ResourceConfiguration.allNamespacesWatched(Set.of(Constants.WATCH_CURRENT_NAMESPACE)));
- }
-
- @Test
- void currentNamespaceWatched() {
- assertThrows(IllegalArgumentException.class,
- () -> ResourceConfiguration.currentNamespaceWatched(null));
- assertThrows(IllegalArgumentException.class,
- () -> ResourceConfiguration.currentNamespaceWatched(
- Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
- assertThrows(IllegalArgumentException.class,
- () -> ResourceConfiguration.currentNamespaceWatched(Collections.emptySet()));
- assertFalse(ResourceConfiguration.currentNamespaceWatched(Set.of("foo", "bar")));
- assertFalse(
- ResourceConfiguration.currentNamespaceWatched(Set.of(Constants.WATCH_ALL_NAMESPACES)));
- assertFalse(ResourceConfiguration.currentNamespaceWatched(Set.of("foo")));
- assertTrue(
- ResourceConfiguration.currentNamespaceWatched(Set.of(Constants.WATCH_CURRENT_NAMESPACE)));
- }
-
- @Test
- void nullLabelSelectorByDefault() {
- assertNull(DEFAULT.getLabelSelector());
- }
-
- // todo: fix me
- @Disabled
- @Test
- void shouldWatchAllNamespacesByDefault() {
- assertTrue(DEFAULT.watchAllNamespaces());
- }
-
- @Test
- void failIfNotValid() {
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.failIfNotValid(null));
- assertThrows(IllegalArgumentException.class,
- () -> ResourceConfiguration.failIfNotValid(Collections.emptySet()));
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.failIfNotValid(
- Set.of(Constants.WATCH_CURRENT_NAMESPACE, Constants.WATCH_ALL_NAMESPACES, "foo")));
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.failIfNotValid(
- Set.of(Constants.WATCH_CURRENT_NAMESPACE, "foo")));
- assertThrows(IllegalArgumentException.class, () -> ResourceConfiguration.failIfNotValid(
- Set.of(Constants.WATCH_ALL_NAMESPACES, "foo")));
-
- // should work
- ResourceConfiguration.failIfNotValid(Set.of("foo", "bar"));
- }
-}
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java
index e24de96dbb..a7f0dade3b 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/EventSourceManagerTest.java
@@ -168,14 +168,13 @@ void changesNamespacesOnControllerAndInformerEventSources() {
when(controllerResourceEventSourceMock.allowsNamespaceChanges()).thenCallRealMethod();
var manager = new EventSourceManager(controller, eventSources);
- InformerEventSourceConfiguration informerConfigurationMock =
+ InformerEventSourceConfiguration eventSourceConfigurationMock =
mock(InformerEventSourceConfiguration.class);
- when(informerConfigurationMock.followControllerNamespaceChanges()).thenReturn(true);
InformerEventSource informerEventSource = mock(InformerEventSource.class);
when(informerEventSource.name()).thenReturn("ies");
when(informerEventSource.resourceType()).thenReturn(TestCustomResource.class);
- when(informerEventSource.configuration()).thenReturn(informerConfigurationMock);
- when(informerEventSource.allowsNamespaceChanges()).thenCallRealMethod();
+ when(informerEventSource.configuration()).thenReturn(eventSourceConfigurationMock);
+ when(informerEventSource.allowsNamespaceChanges()).thenReturn(true);
manager.registerEventSource(informerEventSource);
manager.changeNamespaces(Set.of(newNamespaces));
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSourceTest.java
index 5282fd2138..4ba2a5184c 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSourceTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSourceTest.java
@@ -191,7 +191,6 @@ public TestConfiguration(boolean generationAware, OnAddFilter onUpdateFilter,
GenericFilter genericFilter) {
super(
- TestCustomResource.class,
"test",
generationAware,
null,
diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSourceTest.java
index 442f53bc98..ce027846f0 100644
--- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSourceTest.java
+++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSourceTest.java
@@ -16,6 +16,7 @@
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.config.InformerStoppedHandler;
+import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
import io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration;
import io.javaoperatorsdk.operator.processing.event.EventHandler;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
@@ -44,18 +45,19 @@ class InformerEventSourceTest {
private final TemporaryResourceCache temporaryResourceCacheMock =
mock(TemporaryResourceCache.class);
private final EventHandler eventHandlerMock = mock(EventHandler.class);
- private final InformerEventSourceConfiguration informerConfiguration =
+ private final InformerEventSourceConfiguration informerEventSourceConfiguration =
mock(InformerEventSourceConfiguration.class);
@BeforeEach
void setup() {
- when(informerConfiguration.getEffectiveNamespaces(any()))
- .thenReturn(DEFAULT_NAMESPACES_SET);
- when(informerConfiguration.getSecondaryToPrimaryMapper())
+ final var informerConfig = mock(InformerConfiguration.class);
+ when(informerEventSourceConfiguration.getInformerConfig()).thenReturn(informerConfig);
+ when(informerConfig.getEffectiveNamespaces(any())).thenReturn(DEFAULT_NAMESPACES_SET);
+ when(informerEventSourceConfiguration.getSecondaryToPrimaryMapper())
.thenReturn(mock(SecondaryToPrimaryMapper.class));
- when(informerConfiguration.getResourceClass()).thenReturn(Deployment.class);
+ when(informerEventSourceConfiguration.getResourceClass()).thenReturn(Deployment.class);
- informerEventSource = new InformerEventSource<>(informerConfiguration, clientMock);
+ informerEventSource = new InformerEventSource<>(informerEventSourceConfiguration, clientMock);
var mockControllerConfig = mock(ControllerConfiguration.class);
when(mockControllerConfig.getConfigurationService()).thenReturn(new BaseConfigurationService());
@@ -63,7 +65,7 @@ void setup() {
informerEventSource.setEventHandler(eventHandlerMock);
informerEventSource.setControllerConfiguration(mockControllerConfig);
SecondaryToPrimaryMapper secondaryToPrimaryMapper = mock(SecondaryToPrimaryMapper.class);
- when(informerConfiguration.getSecondaryToPrimaryMapper())
+ when(informerEventSourceConfiguration.getSecondaryToPrimaryMapper())
.thenReturn(secondaryToPrimaryMapper);
when(secondaryToPrimaryMapper.toPrimaryResourceIDs(any()))
.thenReturn(Set.of(ResourceID.fromResource(testDeployment())));
@@ -184,7 +186,7 @@ void informerStoppedHandlerShouldBeCalledWhenInformerStops() {
var mockControllerConfig = mock(ControllerConfiguration.class);
when(mockControllerConfig.getConfigurationService()).thenReturn(configuration);
- informerEventSource = new InformerEventSource<>(informerConfiguration,
+ informerEventSource = new InformerEventSource<>(informerEventSourceConfiguration,
MockKubernetesClient.client(Deployment.class, unused -> {
throw exception;
}));
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 12573b50f7..1a1214aa78 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
@@ -11,7 +11,6 @@ public class DefaultConfigurationService extends BaseConfigurationService {
@Override
protected ControllerConfiguration configFor(Reconciler reconciler) {
final var other = super.configFor(reconciler);
- return new ResolvedControllerConfiguration<>(
- RuntimeControllerMetadata.getResourceClass(reconciler), other);
+ return new ResolvedControllerConfiguration<>(other);
}
}
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java
index bde573171d..77a3b245b0 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/multiplesecondaryeventsource/MultipleSecondaryEventSourceReconciler.java
@@ -71,7 +71,10 @@ public List> prepareE
var config = InformerEventSourceConfiguration
.from(ConfigMap.class, MultipleSecondaryEventSourceCustomResource.class)
.withInformerConfiguration(c -> c
- .withNamespaces(context.getControllerConfiguration().getNamespaces())
+ // TODO: this shouldn't be needed since this should be the default behavior (tracking
+ // the controller's namespaces)
+ .withNamespaces(
+ context.getControllerConfiguration().getInformerConfig().getNamespaces())
.withLabelSelector("multisecondary"))
.withSecondaryToPrimaryMapper(s -> {
var name =
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java
index 43309446fb..c83505e597 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/BaseConfigurationServiceTest.java
@@ -112,19 +112,21 @@ void missingAnnotationCreatesDefaultConfig() {
var config = configFor(reconciler);
assertThat(config.getName()).isEqualTo(ReconcilerUtils.getNameFor(reconciler));
- assertThat(config.getLabelSelector()).isNull();
assertThat(config.getRetry()).isInstanceOf(GenericRetry.class);
assertThat(config.getRateLimiter()).isInstanceOf(LinearRateLimiter.class);
assertThat(config.maxReconciliationInterval()).hasValue(Duration.ofHours(DEFAULT_INTERVAL));
assertThat(config.fieldManager()).isEqualTo(config.getName());
- assertThat(config.getInformerListLimit()).isEmpty();
- assertThat(config.onAddFilter()).isEmpty();
- assertThat(config.onUpdateFilter()).isEmpty();
- assertThat(config.genericFilter()).isEmpty();
- assertThat(config.getNamespaces()).isEqualTo(Constants.DEFAULT_NAMESPACES_SET);
assertThat(config.getFinalizerName())
.isEqualTo(ReconcilerUtils.getDefaultFinalizerName(config.getResourceClass()));
- assertThat(config.getItemStore()).isEmpty();
+
+ final var informerConfig = config.getInformerConfig();
+ assertThat(informerConfig.getLabelSelector()).isNull();
+ assertNull(informerConfig.getInformerListLimit());
+ assertNull(informerConfig.getOnAddFilter());
+ assertNull(informerConfig.getOnUpdateFilter());
+ assertNull(informerConfig.getGenericFilter());
+ assertNull(informerConfig.getItemStore());
+ assertThat(informerConfig.getNamespaces()).isEqualTo(Constants.DEFAULT_NAMESPACES_SET);
}
@SuppressWarnings("rawtypes")
diff --git a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java
index b38f48b912..15343793fd 100644
--- a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java
+++ b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageDependentsWorkflowReconciler.java
@@ -85,7 +85,7 @@ private void initDependentResources(KubernetesClient client) {
Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR)
.forEach(dr -> dr.configureWith(new KubernetesDependentResourceConfigBuilder()
- .withKubernetesDependentInformerConfig(InformerConfiguration.builder()
+ .withKubernetesDependentInformerConfig(InformerConfiguration.builder(dr.resourceType())
.withLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR)
.buildForInformerEventSource())
.build()));
diff --git a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java
index e7930a3658..580d529a72 100644
--- a/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java
+++ b/sample-operators/webpage/src/main/java/io/javaoperatorsdk/operator/sample/WebPageStandaloneDependentsReconciler.java
@@ -96,7 +96,7 @@ private Workflow createDependentResourcesAndWorkflow() {
// configure them with our label selector
Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR)
.forEach(dr -> dr.configureWith(new KubernetesDependentResourceConfigBuilder()
- .withKubernetesDependentInformerConfig(InformerConfiguration.builder()
+ .withKubernetesDependentInformerConfig(InformerConfiguration.builder(dr.resourceType())
.withLabelSelector(SELECTOR + "=true")
.buildForInformerEventSource())
.build()));