diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java index 1786c3a568..957d78ac7d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java @@ -39,20 +39,22 @@ protected AbstractDependentResource() { @Override public ReconcileResult reconcile(P primary, Context

context) { if (bulk) { - final var targetKeys = bulkDependentResource.targetKeys(primary, context); + final var targetResources = bulkDependentResource.desiredResources(primary, context); + Map actualResources = bulkDependentResource.getSecondaryResources(primary, context); - deleteBulkResourcesIfRequired(targetKeys, actualResources, primary, context); - final List> results = new ArrayList<>(targetKeys.size()); + deleteBulkResourcesIfRequired(targetResources.keySet(), actualResources, primary, context); + final List> results = new ArrayList<>(targetResources.size()); + + targetResources.forEach((key, resource) -> { + results.add(reconcileIndexAware(primary, actualResources.get(key), resource, key, context)); + }); - for (String key : targetKeys) { - results.add(reconcileIndexAware(primary, actualResources.get(key), key, context)); - } return ReconcileResult.aggregatedResult(results); } else { var actualResource = getSecondaryResource(primary, context); - return reconcileIndexAware(primary, actualResource.orElse(null), null, context); + return reconcileIndexAware(primary, actualResource.orElse(null), null, null, context); } } @@ -66,12 +68,13 @@ protected void deleteBulkResourcesIfRequired(Set targetKeys, Map actu }); } - protected ReconcileResult reconcileIndexAware(P primary, R resource, String key, + protected ReconcileResult reconcileIndexAware(P primary, R actualResource, R desiredResource, + String key, Context

context) { if (creatable || updatable) { - if (resource == null) { + if (actualResource == null) { if (creatable) { - var desired = desiredIndexAware(primary, key, context); + var desired = bulkAwareDesired(primary, desiredResource, context); throwIfNull(desired, primary, "Desired"); logForOperation("Creating", primary, desired); var createdResource = handleCreate(desired, primary, context); @@ -81,20 +84,22 @@ protected ReconcileResult reconcileIndexAware(P primary, R resource, String k if (updatable) { final Matcher.Result match; if (bulk) { - match = bulkDependentResource.match(resource, primary, key, context); + match = + bulkDependentResource.match(actualResource, desiredResource, primary, key, context); } else { - match = updater.match(resource, primary, context); + match = updater.match(actualResource, primary, context); } if (!match.matched()) { final var desired = - match.computedDesired().orElse(desiredIndexAware(primary, key, context)); + match.computedDesired().orElse(bulkAwareDesired(primary, desiredResource, context)); throwIfNull(desired, primary, "Desired"); logForOperation("Updating", primary, desired); - var updatedResource = handleUpdate(resource, desired, primary, context); + var updatedResource = handleUpdate(actualResource, desired, primary, context); return ReconcileResult.resourceUpdated(updatedResource); } } else { - log.debug("Update skipped for dependent {} as it matched the existing one", resource); + log.debug("Update skipped for dependent {} as it matched the existing one", + actualResource); } } } else { @@ -102,11 +107,11 @@ protected ReconcileResult reconcileIndexAware(P primary, R resource, String k "Dependent {} is read-only, implement Creator and/or Updater interfaces to modify it", getClass().getSimpleName()); } - return ReconcileResult.noOperation(resource); + return ReconcileResult.noOperation(actualResource); } - private R desiredIndexAware(P primary, String key, Context

context) { - return bulk ? bulkDependentResource.desired(primary, key, context) + private R bulkAwareDesired(P primary, R alreadyComputedDesire, Context

context) { + return bulk ? alreadyComputedDesire : desired(primary, context); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java index 1c7189293b..fe8da3a091 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/BulkDependentResource.java @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.processing.dependent; import java.util.Map; -import java.util.Set; import io.fabric8.kubernetes.api.model.HasMetadata; import io.javaoperatorsdk.operator.api.reconciler.Context; @@ -20,12 +19,10 @@ public interface BulkDependentResource /** * @return number of resources to create */ - Set targetKeys(P primary, Context

context); + Map desiredResources(P primary, Context

context); Map getSecondaryResources(P primary, Context

context); - R desired(P primary, String key, Context

context); - /** * Used to delete resource if the desired count is lower than the actual count of a resource. * @@ -50,6 +47,6 @@ public interface BulkDependentResource * convenience methods ({@link Result#nonComputed(boolean)} and * {@link Result#computed(boolean, Object)}) */ - Result match(R actualResource, P primary, String key, Context

context); + Result match(R actualResource, R desired, P primary, String key, Context

context); } 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 97ad7fa226..82df9dbbb9 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 @@ -139,9 +139,8 @@ public Result match(R actualResource, P primary, Context

context) { return matcher.match(actualResource, primary, context); } - public Result match(R actualResource, P primary, String key, Context

context) { - final var desired = bulkDependentResource.desired(primary, key, context); - return GenericKubernetesResourceMatcher.match((R) desired, actualResource, false); + public Result match(R actualResource, R desired, P primary, String key, Context

context) { + return GenericKubernetesResourceMatcher.match(desired, actualResource, false); } protected void handleDelete(P primary, Context

context) { @@ -149,7 +148,6 @@ protected void handleDelete(P primary, Context

context) { resource.ifPresent(r -> client.resource(r).delete()); } - public void deleteBulkResource(P primary, R resource, String key, Context

context) { client.resource(resource).delete(); } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/ConfigMapDeleterBulkDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/ConfigMapDeleterBulkDependentResource.java index e41b38c97e..a04224790c 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/ConfigMapDeleterBulkDependentResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/ConfigMapDeleterBulkDependentResource.java @@ -32,17 +32,17 @@ public ConfigMapDeleterBulkDependentResource() { } @Override - public Set targetKeys(BulkDependentTestCustomResource primary, + public Map desiredResources(BulkDependentTestCustomResource primary, Context context) { var number = primary.getSpec().getNumberOfResources(); - Set res = new HashSet<>(); + Map res = new HashMap<>(); for (int i = 0; i < number; i++) { - res.add(Integer.toString(i)); + var key = Integer.toString(i); + res.put(key, desired(primary, key, context)); } return res; } - @Override public ConfigMap desired(BulkDependentTestCustomResource primary, String key, Context context) { ConfigMap configMap = new ConfigMap(); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/external/ExternalBulkDependentResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/external/ExternalBulkDependentResource.java index 79b861d060..3a13e29707 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/external/ExternalBulkDependentResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/bulkdependent/external/ExternalBulkDependentResource.java @@ -60,12 +60,14 @@ private ResourceID toResourceID(ExternalResource externalResource) { } @Override - public Set targetKeys(BulkDependentTestCustomResource primary, + public Map desiredResources(BulkDependentTestCustomResource primary, Context context) { var number = primary.getSpec().getNumberOfResources(); - Set res = new HashSet<>(); + Map res = new HashMap<>(); for (int i = 0; i < number; i++) { - res.add(Integer.toString(i)); + var key = Integer.toString(i); + res.put(key, new ExternalResource(toExternalResourceId(primary, key), + primary.getSpec().getAdditionalData())); } return res; } @@ -84,13 +86,6 @@ public Map getSecondaryResources( r -> r)); } - @Override - public ExternalResource desired(BulkDependentTestCustomResource primary, String key, - Context context) { - return new ExternalResource(toExternalResourceId(primary, key), - primary.getSpec().getAdditionalData()); - } - @Override public void deleteBulkResource(BulkDependentTestCustomResource primary, ExternalResource resource, String key, @@ -100,9 +95,9 @@ public void deleteBulkResource(BulkDependentTestCustomResource primary, External @Override public Matcher.Result match(ExternalResource actualResource, + ExternalResource desired, BulkDependentTestCustomResource primary, String index, Context context) { - var desired = desired(primary, index, context); return Matcher.Result.computed(desired.equals(actualResource), desired); } }