diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java index b5e3fffcf0..ab13a6d5d5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AnnotationControllerConfiguration.java @@ -17,9 +17,8 @@ import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.ReconcilerUtils; import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec; -import io.javaoperatorsdk.operator.api.reconciler.Constants; +import io.javaoperatorsdk.operator.api.reconciler.*; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; -import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent; import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent; @@ -54,9 +53,8 @@ public AnnotationControllerConfiguration(Reconciler
reconciler) {
this.reconciler = reconciler;
this.annotation = reconciler.getClass().getAnnotation(ControllerConfiguration.class);
if (annotation == null) {
- throw new OperatorException(
- "Missing mandatory @" + ControllerConfiguration.class.getSimpleName() +
- " annotation for reconciler: " + reconciler);
+ throw new OperatorException("Missing mandatory @" + CONTROLLER_CONFIG_ANNOTATION +
+ " annotation for reconciler: " + reconciler);
}
}
@@ -247,9 +245,11 @@ public List {
Optional getControllerConfiguration();
ManagedDependentResourceContext managedDependentResourceContext();
+
+ EventSourceRetriever eventSourceRetriever();
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java
index afb37a8c53..cb7f4ae63b 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java
@@ -9,6 +9,7 @@
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext;
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.ManagedDependentResourceContext;
import io.javaoperatorsdk.operator.processing.Controller;
+import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
public class DefaultContext implements Context {
@@ -47,6 +48,12 @@ public getControllerConfiguration() {
return controllerConfiguration;
@@ -57,6 +64,11 @@ public ManagedDependentResourceContext managedDependentResourceContext() {
return defaultManagedDependentResourceContext;
}
+ @Override
+ public EventSourceRetriever eventSourceRetriever() {
+ return controller.getEventSourceManager();
+ }
+
public DefaultContext setRetryInfo(RetryInfo retryInfo) {
this.retryInfo = retryInfo;
return this;
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceContext.java
index e8062e9651..2c1e82ba4c 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
@@ -3,6 +3,8 @@
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
+import io.javaoperatorsdk.operator.processing.event.EventSourceManager;
+import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
import io.javaoperatorsdk.operator.processing.event.source.IndexerResourceCache;
@@ -13,14 +15,14 @@
*/
public class EventSourceContext {
- private final IndexerResourceCache primaryCache;
+ private final EventSourceManager eventSourceManager;
private final ControllerConfiguration controllerConfiguration;
private final KubernetesClient client;
- public EventSourceContext(IndexerResourceCache primaryCache,
+ public EventSourceContext(EventSourceManager eventSourceManager,
ControllerConfiguration controllerConfiguration,
KubernetesClient client) {
- this.primaryCache = primaryCache;
+ this.eventSourceManager = eventSourceManager;
this.controllerConfiguration = controllerConfiguration;
this.client = client;
}
@@ -31,7 +33,7 @@ public EventSourceContext(IndexerResourceCache primaryCache,
* @return the primary resource cache
*/
public IndexerResourceCache getPrimaryCache() {
- return primaryCache;
+ return eventSourceManager.getControllerResourceEventSource();
}
/**
@@ -54,4 +56,8 @@ public ControllerConfiguration getControllerConfiguration() {
public KubernetesClient getClient() {
return client;
}
+
+ public EventSourceRetriever getEventSourceRetriever() {
+ return eventSourceManager;
+ }
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java
index 9b3c7a67bd..c49332b468 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/EventSourceInitializer.java
@@ -1,9 +1,13 @@
package io.javaoperatorsdk.operator.api.reconciler;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
+import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceAware;
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
/**
@@ -39,6 +43,21 @@ static Map context);
+
+}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java
new file mode 100644
index 0000000000..f28633252a
--- /dev/null
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceIDMatcherDiscriminator.java
@@ -0,0 +1,25 @@
+package io.javaoperatorsdk.operator.api.reconciler;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.javaoperatorsdk.operator.processing.event.ResourceID;
+
+public class ResourceIDMatcherDiscriminator mapper;
+
+ public ResourceIDMatcherDiscriminator(Function mapper) {
+ this.mapper = mapper;
+ }
+
+ @Override
+ public Optional context) {
+ var resourceID = mapper.apply(primary);
+ return context.getSecondaryResources(resource).stream()
+ .filter(resourceID::isSameResource)
+ .findFirst();
+ }
+}
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 90ba701a6a..2f2f1f1e0d 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
@@ -57,4 +57,13 @@
* one can be
*/
String[] dependsOn() default {};
+
+ /**
+ * Setting here a name of the event source means that dependent resource will use an event source
+ * registered with that name. So won't create one. This is helpful if more dependent resources
+ * created for the same type, and want to share a common event source.
+ *
+ * @return event source name (if any) provided by the dependent resource should be used.
+ */
+ String eventSource() default NO_VALUE_SET;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java
index 0923d19473..8d31778488 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/DependentResource.java
@@ -1,8 +1,9 @@
package io.javaoperatorsdk.operator.api.reconciler.dependent;
+import java.util.Optional;
+
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.api.reconciler.Context;
-import io.javaoperatorsdk.operator.processing.ResourceOwner;
/**
* An interface to implement and provide dependent resource support.
@@ -10,7 +11,7 @@
* @param the associated primary resource type
*/
-public interface DependentResource context);
+ /**
+ * Retrieves the resource type associated with this DependentResource
+ *
+ * @return the resource type associated with this DependentResource
+ */
+ Class context) {
+ return Optional.empty();
+ }
+
/**
* Computes a default name for the specified DependentResource class
*
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceAware.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceAware.java
new file mode 100644
index 0000000000..c4f4fbcc4f
--- /dev/null
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/EventSourceAware.java
@@ -0,0 +1,36 @@
+package io.javaoperatorsdk.operator.api.reconciler.dependent;
+
+import java.util.Optional;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
+import io.javaoperatorsdk.operator.processing.event.source.ResourceEventSource;
+
+public interface EventSourceAware context) {
+ return getUsedEventSourceName().map(
+ name -> context.getEventSourceRetriever().getResourceEventSourceFor(resourceType(), name));
+ }
+
+ Class primary resource
+ */
+@Deprecated(forRemoval = true)
public interface EventSourceProvider {
/**
* @param context - event source context where the event source is initialized
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 c83da1c8ea..468e14e8ea 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
@@ -1,14 +1,14 @@
package io.javaoperatorsdk.operator.api.reconciler.dependent;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
public class ReconcileResult context) {
}
public void initAndRegisterEventSources(EventSourceContext context) {
- managedWorkflow
- .getDependentResourcesByName().entrySet().stream()
- .filter(drEntry -> drEntry.getValue() instanceof EventSourceProvider)
- .forEach(drEntry -> {
- final var provider = (EventSourceProvider) drEntry.getValue();
- final var source = provider.initEventSource(context);
- eventSourceManager.registerEventSource(drEntry.getKey(), source);
- });
-
- // add manually defined event sources
if (reconciler instanceof EventSourceInitializer) {
final var provider = (EventSourceInitializer ) this.reconciler;
final var ownSources = provider.prepareEventSources(context);
ownSources.forEach(eventSourceManager::registerEventSource);
}
+ managedWorkflow.getDependentResourcesByName().entrySet().stream().filter(entry -> {
+ final var value = entry.getValue();
+ return value instanceof EventSourceProvider || value instanceof EventSourceAware;
+ }).forEach(entry -> {
+ final var value = entry.getValue();
+ final var key = entry.getKey();
+ if (value instanceof EventSourceProvider) {
+ final var provider = (EventSourceProvider) value;
+ final var source = provider.initEventSource(context);
+ eventSourceManager.registerEventSource(key, source);
+ } else {
+ ((EventSourceAware, P>) value).eventSource(context)
+ .ifPresent(es -> eventSourceManager.registerEventSource(key, es));
+ }
+ });
}
@Override
@@ -288,8 +294,8 @@ public synchronized void start(boolean startEventProcessor) throws OperatorExcep
try {
// check that the custom resource is known by the cluster if configured that way
validateCRDWithLocalModelIfRequired(resClass, controllerName, crdName, specVersion);
- final var context = new EventSourceContext<>(
- eventSourceManager.getControllerResourceEventSource(), configuration, kubernetesClient);
+ final var context =
+ new EventSourceContext<>(eventSourceManager, configuration, kubernetesClient);
initAndRegisterEventSources(context);
eventSourceManager.start();
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java
deleted file mode 100644
index f9c02a8a33..0000000000
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/ResourceOwner.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.javaoperatorsdk.operator.processing;
-
-import java.util.Optional;
-
-import io.fabric8.kubernetes.api.model.HasMetadata;
-
-public interface ResourceOwner context) {
- var maybeActual = getSecondaryResource(primary);
+ if (bulk) {
+ final var count = bulkDependentResource.count(primary, context);
+ deleteBulkResourcesIfRequired(count, lastKnownBulkSize(), primary, context);
+ adjustDiscriminators(count);
+ @SuppressWarnings("unchecked")
+ final ReconcileResult context) {
+ if (targetCount >= actualCount) {
+ return;
+ }
+ for (int i = targetCount; i < actualCount; i++) {
+ var resource = getSecondaryResourceIndexAware(primary, i, context);
+ var index = i;
+ resource.ifPresent(
+ r -> bulkDependentResource.deleteBulkResourceWithIndex(primary, r, index, context));
+ }
+ }
+
+ private void adjustDiscriminators(int count) {
+ if (resourceDiscriminator.size() == count) {
+ return;
+ }
+ if (resourceDiscriminator.size() < count) {
+ for (int i = resourceDiscriminator.size(); i < count; i++) {
+ resourceDiscriminator.add(bulkDependentResource.getResourceDiscriminator(i));
+ }
+ }
+ if (resourceDiscriminator.size() > count) {
+ resourceDiscriminator.subList(count, resourceDiscriminator.size()).clear();
+ }
+ }
+
+ protected ReconcileResult context) {
+ Optional context) {
} else {
final var actual = maybeActual.get();
if (updatable) {
- final var match = updater.match(actual, primary, context);
+ final Matcher.Result context) {
return ReconcileResult.noOperation(maybeActual.orElse(null));
}
+ private R desiredIndexAware(P primary, int i, Context context) {
+ return bulk ? desired(primary, i, context)
+ : desired(primary, context);
+ }
+
+ public Optional context) {
+ return resourceDiscriminator.isEmpty() ? context.getSecondaryResource(resourceType())
+ : resourceDiscriminator.get(0).distinguish(resourceType(), primary, context);
+ }
+
+ protected Optional context) {
+ return context.getSecondaryResource(resourceType(), resourceDiscriminator.get(index));
+ }
+
private void throwIfNull(R desired, P primary, String descriptor) {
if (desired == null) {
throw new DependentResourceException(
@@ -87,7 +162,7 @@ protected R handleCreate(R desired, P primary, Context context) {
}
/**
- * Allows sub-classes to perform additional processing (e.g. caching) on the created resource if
+ * Allows subclasses to perform additional processing (e.g. caching) on the created resource if
* needed.
*
* @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
@@ -97,7 +172,7 @@ protected R handleCreate(R desired, P primary, Context context) {
protected abstract void onCreated(ResourceID primaryResourceId, R created);
/**
- * Allows sub-classes to perform additional processing on the updated resource if needed.
+ * Allows subclasses to perform additional processing on the updated resource if needed.
*
* @param primaryResourceId the {@link ResourceID} of the primary resource associated with the
* newly updated resource
@@ -118,4 +193,29 @@ protected R desired(P primary, Context context) {
throw new IllegalStateException(
"desired method must be implemented if this DependentResource can be created and/or updated");
}
+
+ protected R desired(P primary, int index, Context context) {
+ throw new IllegalStateException(
+ "Must be implemented for bulk DependentResource creation");
+ }
+
+ public AbstractDependentResource {
+ extends AbstractDependentResource context) {
+ @SuppressWarnings("unchecked")
+ @Override
+ public Optional context) {
// some sub-classes (e.g. KubernetesDependentResource) can have their event source created
// before this method is called in the managed case, so only create the event source if it
// hasn't already been set.
@@ -34,17 +42,29 @@ public EventSource initEventSource(EventSourceContext context) {
// event source
// is shared between dependent resources this does not override the existing filters.
if (eventSource == null) {
- eventSource = createEventSource(context);
+ T localEventSource =
+ (T) EventSourceAware.super.eventSource(context).orElse(createEventSource(context));
+ setEventSource(localEventSource);
applyFilters();
}
+ return Optional.of(eventSource);
+ }
- isCacheFillerEventSource = eventSource instanceof RecentOperationCacheFiller;
- return eventSource;
+ /** To make this backwards compatible even for respect of overriding */
+ @SuppressWarnings("unchecked")
+ public T initEventSource(EventSourceContext context) {
+ return (T) eventSource(context).orElseThrow();
+ }
+
+ @Override
+ public Class context);
protected void setEventSource(T eventSource) {
+ isCacheFillerEventSource = eventSource instanceof RecentOperationCacheFiller;
this.eventSource = eventSource;
}
@@ -55,8 +75,8 @@ protected void applyFilters() {
this.eventSource.setGenericFilter(genericFilter);
}
- protected T eventSource() {
- return eventSource;
+ public Optional {
+
+ /**
+ * @return number of resources to create
+ */
+ int count(P primary, Context context);
+
+ R desired(P primary, int index, Context context);
+
+ /**
+ * Used to delete resource if the desired count is lower than the actual count of a resource.
+ *
+ * @param primary resource
+ * @param resource actual resource from the cache for the index
+ * @param i index of the resource
+ * @param context actual context
+ */
+ void deleteBulkResourceWithIndex(P primary, R resource, int i, Context context);
+
+ ResourceDiscriminator primary resource type
+ */
+public interface BulkUpdater context) {
+ throw new IllegalStateException();
+ }
+
+ Matcher.Result context);
+}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DesiredEqualsMatcher.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DesiredEqualsMatcher.java
index 459d7951d6..1d3b34a47b 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DesiredEqualsMatcher.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/DesiredEqualsMatcher.java
@@ -16,4 +16,10 @@ public Result context) {
var desired = abstractDependentResource.desired(primary, context);
return Result.computed(actualResource.equals(desired), desired);
}
+
+ @Override
+ public Result context) {
+ var desired = abstractDependentResource.desired(primary, index, context);
+ return Result.computed(actualResource.equals(desired), desired);
+ }
}
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 750fe89cbf..835f76ab3a 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
@@ -95,4 +95,19 @@ public Optional context);
+
+ /**
+ * Determines whether the specified secondary resource matches the desired state with target index
+ * of a bulk resource as defined from the specified primary resource, given the specified
+ * {@link Context}.
+ *
+ * @param actualResource the resource we want to determine whether it's matching the desired state
+ * @param primary the primary resource from which the desired state is inferred
+ * @param context the context in which the resource is being matched
+ * @return a {@link Result} encapsulating whether the resource matched its desired state and this
+ * associated state if it was computed as part of the matching process. Use the static
+ * convenience methods ({@link Result#nonComputed(boolean)} and
+ * {@link Result#computed(boolean, Object)})
+ */
+ Result context);
}
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 828f9ad785..06b3cb52f6 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
@@ -8,4 +8,8 @@ public interface Updater context);
Result context);
+
+ default Result context) {
+ throw new IllegalStateException("Implement this for bulk matching");
+ }
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java
deleted file mode 100644
index 242625bc5d..0000000000
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/external/AbstractCachingDependentResource.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.javaoperatorsdk.operator.processing.dependent.external;
-
-import java.util.Optional;
-
-import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.javaoperatorsdk.operator.api.reconciler.Ignore;
-import io.javaoperatorsdk.operator.processing.dependent.AbstractEventSourceHolderDependentResource;
-import io.javaoperatorsdk.operator.processing.event.source.ExternalResourceCachingEventSource;
-
-@Ignore
-public abstract class AbstractCachingDependentResource context) {
- var resourceId = ResourceID.fromResource(primary);
- Optional context) {
- deleteResource(primary, context);
- cache.remove(ResourceID.fromResource(primary));
- }
-
- protected abstract void deleteResource(P primary, Context context);
-
- @Override
- protected void onCreated(ResourceID primaryResourceId, R created) {
- cache.put(primaryResourceId, created);
- }
-
- @Override
- protected void onUpdated(ResourceID primaryResourceId, R updated, R actual) {
- cache.put(primaryResourceId, updated);
- }
-
- public Matcher.Result context) {
- return matcher.match(actualResource, primary, context);
- }
-
- protected void initMatcher() {
- matcher = new DesiredEqualsMatcher<>(this);
- }
-
-}
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 e294b1c938..bb066b5b24 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
@@ -24,17 +24,42 @@ private GenericKubernetesResourceMatcher(KubernetesDependentResource context) {
+ final var desired = dependentResource.desired(primary, context);
+ return Result.computed(
+ ResourceComparators.compareSecretData((Secret) desired, (Secret) actualResource),
+ desired);
+ }
+
+ @Override
+ public Result context) {
+ final var desired = dependentResource.desired(primary, index, context);
+ return Result.computed(
+ ResourceComparators.compareSecretData((Secret) desired, (Secret) actualResource),
+ desired);
+ }
};
} else if (ConfigMap.class.isAssignableFrom(resourceType)) {
- return (actual, primary, context) -> {
- final var desired = dependentResource.desired(primary, context);
- return Result.computed(
- ResourceComparators.compareConfigMapData((ConfigMap) desired, (ConfigMap) actual),
- desired);
+ return new Matcher<>() {
+ @Override
+ public Result context) {
+ final var desired = dependentResource.desired(primary, context);
+ return Result.computed(
+ ResourceComparators.compareConfigMapData((ConfigMap) desired,
+ (ConfigMap) actualResource),
+ desired);
+ }
+
+ @Override
+ public Result context) {
+ final var desired = dependentResource.desired(primary, index, context);
+ return Result.computed(
+ ResourceComparators.compareConfigMapData((ConfigMap) desired,
+ (ConfigMap) actualResource),
+ desired);
+ }
};
} else {
return new GenericKubernetesResourceMatcher(dependentResource);
@@ -43,32 +68,18 @@ static context) {
- return match(dependentResource, actualResource, primary, context, false);
+ var desired = dependentResource.desired(primary, context);
+ return match(desired, actualResource, false);
}
- /**
- * Determines whether the specified actual resource matches the desired state defined by the
- * specified {@link KubernetesDependentResource} based on the observed state of the associated
- * specified primary resource.
- *
- * @param dependentResource the {@link KubernetesDependentResource} implementation used to
- * computed the desired state associated with the specified primary resource
- * @param actualResource the observed dependent resource for which we want to determine whether it
- * matches the desired state or not
- * @param primary the primary resource from which we want to compute the desired state
- * @param context the {@link Context} instance within which this method is called
- * @param considerMetadata {@code true} to consider the metadata of the actual resource when
- * determining if it matches the desired state, {@code false} if matching should occur only
- * considering the spec of the resources
- * @return a {@link io.javaoperatorsdk.operator.processing.dependent.Matcher.Result} object
- * @param the type of primary resources associated with the secondary resources we want to
- * match
- */
- public static context, boolean considerMetadata) {
- final var desired = dependentResource.desired(primary, context);
+ @Override
+ public Result context) {
+ var desired = dependentResource.desired(primary, index, context);
+ return match(desired, actualResource, false);
+ }
+
+ public static the type of primary resources associated with the secondary resources we want to
+ * match
+ */
+ public static context, boolean considerMetadata) {
+ final var desired = dependentResource.desired(primary, context);
+ return match(desired, actualResource, considerMetadata);
+ }
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java
index f66ff95373..2ccd4da82a 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependent.java
@@ -6,6 +6,8 @@
import java.lang.annotation.Target;
import io.javaoperatorsdk.operator.api.reconciler.Constants;
+import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
+import io.javaoperatorsdk.operator.processing.event.source.filter.*;
import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
@@ -68,4 +70,8 @@
* itself if no value is set
*/
Class extends GenericFilter> genericFilter() default GenericFilter.class;
+
+ Class extends ResourceDiscriminator> resourceDiscriminator() default ResourceDiscriminator.class;
+
+ String eventSourceToUse() default NO_VALUE_SET;
}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java
index 930e5fd5b4..df195fad29 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResource.java
@@ -1,16 +1,13 @@
package io.javaoperatorsdk.operator.processing.dependent.kubernetes;
import java.util.HashMap;
-import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.javaoperatorsdk.operator.OperatorException;
import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration;
@@ -34,20 +31,19 @@
public abstract class KubernetesDependentResource context) {
@SuppressWarnings("unused")
public R create(R target, P primary, Context context) {
- return prepare(target, primary, "Creating").create(target);
+ return prepare(target, primary, "Creating").create();
}
public R update(R actual, R target, P primary, Context context) {
var updatedActual = processor.replaceSpecOnActual(actual, target, context);
- return prepare(target, primary, "Updating").replace(updatedActual);
+ return prepare(updatedActual, primary, "Updating").replace();
}
public Result context) {
return matcher.match(actualResource, primary, context);
}
+ public Result context) {
+ return matcher.match(actualResource, primary, index, context);
+ }
+
public void delete(P primary, Context context) {
- var resource = getSecondaryResource(primary);
- resource.ifPresent(r -> client.resource(r).delete());
+ if (bulk) {
+ deleteBulkResourcesIfRequired(0, lastKnownBulkSize(), primary, context);
+ } else {
+ var resource = getSecondaryResource(primary, context);
+ resource.ifPresent(r -> client.resource(r).delete());
+ }
}
- @SuppressWarnings("unchecked")
- protected NonNamespaceOperation
+ *
+ *
+ * @param context context of event source initialization
+ * @return an optional event source
+ */
+ default Optional