From b3fc9b3df1b1ba36b310f7af4343cea17d5fb005 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= <csviri@gmail.com>
Date: Tue, 12 Sep 2023 12:16:09 +0200
Subject: [PATCH 1/3] feat: builder for kubernetes dependent configuration
 (#2054)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Attila Mészáros <csviri@gmail.com>
---
 .../KubernetesDependentResourceConfig.java    | 21 +++--
 ...ernetesDependentResourceConfigBuilder.java | 84 +++++++++++++++++++
 .../ControllerConfigurationOverriderTest.java |  6 +-
 .../WebPageDependentsWorkflowReconciler.java  |  6 +-
 ...WebPageStandaloneDependentsReconciler.java | 10 +--
 5 files changed, 110 insertions(+), 17 deletions(-)
 create mode 100644 operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java

diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
index 4047b25a13..3f7a184f4f 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
@@ -20,13 +20,16 @@ public class KubernetesDependentResourceConfig<R> {
 
   private OnAddFilter<R> onAddFilter;
 
-  private OnUpdateFilter<R> onUpdateFilter;
-
-  private OnDeleteFilter<R> onDeleteFilter;
-
-  private GenericFilter<R> genericFilter;
-
-  public KubernetesDependentResourceConfig() {}
+  private final OnAddFilter<R> onAddFilter;
+  private final OnUpdateFilter<R> onUpdateFilter;
+  private final OnDeleteFilter<R> onDeleteFilter;
+  private final GenericFilter<R> genericFilter;
+
+  public KubernetesDependentResourceConfig() {
+    this(Constants.SAME_AS_CONTROLLER_NAMESPACES_SET, NO_VALUE_SET, true,
+        null, null, null,
+        null, null, null);
+  }
 
   public KubernetesDependentResourceConfig(Set<String> namespaces, String labelSelector,
       boolean configuredNS, ResourceDiscriminator<R, ?> resourceDiscriminator,
@@ -43,11 +46,15 @@ public KubernetesDependentResourceConfig(Set<String> namespaces, String labelSel
     this.resourceDiscriminator = resourceDiscriminator;
   }
 
+  // use builder instead
+  @Deprecated(forRemoval = true)
   public KubernetesDependentResourceConfig(Set<String> namespaces, String labelSelector) {
     this(namespaces, labelSelector, true, null, null, null,
         null, null);
   }
 
+  // use builder instead
+  @Deprecated(forRemoval = true)
   public KubernetesDependentResourceConfig<R> setLabelSelector(String labelSelector) {
     this.labelSelector = labelSelector;
     return this;
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
new file mode 100644
index 0000000000..8bdb8a47a5
--- /dev/null
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
@@ -0,0 +1,84 @@
+package io.javaoperatorsdk.operator.processing.dependent.kubernetes;
+
+import java.util.Set;
+
+import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
+import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
+import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
+import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
+import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;
+
+public final class KubernetesDependentResourceConfigBuilder<R> {
+
+  private Set<String> namespaces;
+  private String labelSelector;
+  private boolean createResourceOnlyIfNotExistingWithSSA;
+  private ResourceDiscriminator<R, ?> resourceDiscriminator;
+  private Boolean useSSA;
+  private OnAddFilter<R> onAddFilter;
+  private OnUpdateFilter<R> onUpdateFilter;
+  private OnDeleteFilter<R> onDeleteFilter;
+  private GenericFilter<R> genericFilter;
+
+  public KubernetesDependentResourceConfigBuilder() {}
+
+  public static <R> KubernetesDependentResourceConfigBuilder<R> aKubernetesDependentResourceConfig() {
+    return new KubernetesDependentResourceConfigBuilder<>();
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withNamespaces(Set<String> namespaces) {
+    this.namespaces = namespaces;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withLabelSelector(String labelSelector) {
+    this.labelSelector = labelSelector;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withCreateResourceOnlyIfNotExistingWithSSA(
+      boolean createResourceOnlyIfNotExistingWithSSA) {
+    this.createResourceOnlyIfNotExistingWithSSA = createResourceOnlyIfNotExistingWithSSA;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withResourceDiscriminator(
+      ResourceDiscriminator<R, ?> resourceDiscriminator) {
+    this.resourceDiscriminator = resourceDiscriminator;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withUseSSA(Boolean useSSA) {
+    this.useSSA = useSSA;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withOnAddFilter(OnAddFilter<R> onAddFilter) {
+    this.onAddFilter = onAddFilter;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withOnUpdateFilter(
+      OnUpdateFilter<R> onUpdateFilter) {
+    this.onUpdateFilter = onUpdateFilter;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withOnDeleteFilter(
+      OnDeleteFilter<R> onDeleteFilter) {
+    this.onDeleteFilter = onDeleteFilter;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfigBuilder<R> withGenericFilter(
+      GenericFilter<R> genericFilter) {
+    this.genericFilter = genericFilter;
+    return this;
+  }
+
+  public KubernetesDependentResourceConfig<R> build() {
+    return new KubernetesDependentResourceConfig<>(namespaces, labelSelector, false,
+        createResourceOnlyIfNotExistingWithSSA, resourceDiscriminator, useSSA, onAddFilter,
+        onUpdateFilter, onDeleteFilter, genericFilter);
+  }
+}
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 71be6a2cd4..eae4c22ac6 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
@@ -20,6 +20,7 @@
 import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
 import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource;
 import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfigBuilder;
 import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -327,7 +328,10 @@ void replaceNamedDependentResourceConfigShouldWork() {
     final var overridden = ControllerConfigurationOverrider.override(configuration)
         .replacingNamedDependentResourceConfig(
             DependentResource.defaultNameFor(ReadOnlyDependent.class),
-            new KubernetesDependentResourceConfig(Set.of(overriddenNS), labelSelector))
+            new KubernetesDependentResourceConfigBuilder<>()
+                .withNamespaces(Set.of(overriddenNS))
+                .withLabelSelector(labelSelector)
+                .build())
         .build();
     dependents = overridden.getDependentResources();
     dependentSpec = dependents.stream().filter(dr -> dr.getName().equals(dependentResourceName))
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 1aaf6d19db..d21e89a172 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
@@ -17,7 +17,7 @@
 import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
 import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
 import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource;
-import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfigBuilder;
 import io.javaoperatorsdk.operator.processing.dependent.workflow.Workflow;
 import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowBuilder;
 import io.javaoperatorsdk.operator.processing.event.source.EventSource;
@@ -91,8 +91,8 @@ private void initDependentResources(KubernetesClient client) {
 
     Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR).forEach(dr -> {
       dr.setKubernetesClient(client);
-      dr.configureWith(new KubernetesDependentResourceConfig()
-          .setLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR));
+      dr.configureWith(new KubernetesDependentResourceConfigBuilder()
+          .withLabelSelector(DEPENDENT_RESOURCE_LABEL_SELECTOR).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 3230259c1d..c1b3030c9b 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
@@ -13,7 +13,7 @@
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.javaoperatorsdk.operator.api.reconciler.*;
 import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResource;
-import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfig;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependentResourceConfigBuilder;
 import io.javaoperatorsdk.operator.processing.event.source.EventSource;
 import io.javaoperatorsdk.operator.sample.customresource.WebPage;
 import io.javaoperatorsdk.operator.sample.dependentresource.ConfigMapDependentResource;
@@ -79,21 +79,19 @@ public ErrorStatusUpdateControl<WebPage> updateErrorStatus(
     return handleError(resource, e);
   }
 
-  @SuppressWarnings("unchecked")
+  @SuppressWarnings({"unchecked", "rawtypes"})
   private void createDependentResources(KubernetesClient client) {
     this.configMapDR = new ConfigMapDependentResource();
     this.deploymentDR = new DeploymentDependentResource();
     this.serviceDR = new ServiceDependentResource();
     this.ingressDR = new IngressDependentResource();
 
-
     Arrays.asList(configMapDR, deploymentDR, serviceDR, ingressDR).forEach(dr -> {
       dr.setKubernetesClient(client);
-      dr.configureWith(new KubernetesDependentResourceConfig()
-          .setLabelSelector(SELECTOR + "=true"));
+      dr.configureWith(new KubernetesDependentResourceConfigBuilder()
+          .withLabelSelector(SELECTOR + "=true").build());
     });
   }
 
 
-
 }

From 46d53b640209ae9c8178cac8782ce6e2c3094184 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= <csviri@gmail.com>
Date: Tue, 19 Sep 2023 09:39:06 +0200
Subject: [PATCH 2/3] builder fix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Attila Mészáros <csviri@gmail.com>
---
 .../KubernetesDependentResourceConfig.java        | 10 ++++------
 .../KubernetesDependentResourceConfigBuilder.java | 15 +--------------
 2 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
index 3f7a184f4f..509dae6d0f 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfig.java
@@ -13,13 +13,11 @@
 
 public class KubernetesDependentResourceConfig<R> {
 
-  private Set<String> namespaces = Constants.SAME_AS_CONTROLLER_NAMESPACES_SET;
-  private String labelSelector = NO_VALUE_SET;
-  private boolean namespacesWereConfigured = false;
+  private Set<String> namespaces;
+  private String labelSelector;
+  private boolean namespacesWereConfigured;
   private ResourceDiscriminator<R, ?> resourceDiscriminator;
 
-  private OnAddFilter<R> onAddFilter;
-
   private final OnAddFilter<R> onAddFilter;
   private final OnUpdateFilter<R> onUpdateFilter;
   private final OnDeleteFilter<R> onDeleteFilter;
@@ -27,7 +25,7 @@ public class KubernetesDependentResourceConfig<R> {
 
   public KubernetesDependentResourceConfig() {
     this(Constants.SAME_AS_CONTROLLER_NAMESPACES_SET, NO_VALUE_SET, true,
-        null, null, null,
+        null, null,
         null, null, null);
   }
 
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
index 8bdb8a47a5..42ec842f0a 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
@@ -12,9 +12,7 @@ public final class KubernetesDependentResourceConfigBuilder<R> {
 
   private Set<String> namespaces;
   private String labelSelector;
-  private boolean createResourceOnlyIfNotExistingWithSSA;
   private ResourceDiscriminator<R, ?> resourceDiscriminator;
-  private Boolean useSSA;
   private OnAddFilter<R> onAddFilter;
   private OnUpdateFilter<R> onUpdateFilter;
   private OnDeleteFilter<R> onDeleteFilter;
@@ -36,23 +34,12 @@ public KubernetesDependentResourceConfigBuilder<R> withLabelSelector(String labe
     return this;
   }
 
-  public KubernetesDependentResourceConfigBuilder<R> withCreateResourceOnlyIfNotExistingWithSSA(
-      boolean createResourceOnlyIfNotExistingWithSSA) {
-    this.createResourceOnlyIfNotExistingWithSSA = createResourceOnlyIfNotExistingWithSSA;
-    return this;
-  }
-
   public KubernetesDependentResourceConfigBuilder<R> withResourceDiscriminator(
       ResourceDiscriminator<R, ?> resourceDiscriminator) {
     this.resourceDiscriminator = resourceDiscriminator;
     return this;
   }
 
-  public KubernetesDependentResourceConfigBuilder<R> withUseSSA(Boolean useSSA) {
-    this.useSSA = useSSA;
-    return this;
-  }
-
   public KubernetesDependentResourceConfigBuilder<R> withOnAddFilter(OnAddFilter<R> onAddFilter) {
     this.onAddFilter = onAddFilter;
     return this;
@@ -78,7 +65,7 @@ public KubernetesDependentResourceConfigBuilder<R> withGenericFilter(
 
   public KubernetesDependentResourceConfig<R> build() {
     return new KubernetesDependentResourceConfig<>(namespaces, labelSelector, false,
-        createResourceOnlyIfNotExistingWithSSA, resourceDiscriminator, useSSA, onAddFilter,
+        resourceDiscriminator, onAddFilter,
         onUpdateFilter, onDeleteFilter, genericFilter);
   }
 }

From bb39c0238e75698f3c1cb87da954423a049f943f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= <csviri@gmail.com>
Date: Tue, 19 Sep 2023 09:55:58 +0200
Subject: [PATCH 3/3] defaults fix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Attila Mészáros <csviri@gmail.com>
---
 .../kubernetes/KubernetesDependentResourceConfigBuilder.java   | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
index 42ec842f0a..a408d78915 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/KubernetesDependentResourceConfigBuilder.java
@@ -2,6 +2,7 @@
 
 import java.util.Set;
 
+import io.javaoperatorsdk.operator.api.reconciler.Constants;
 import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
 import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
 import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
@@ -10,7 +11,7 @@
 
 public final class KubernetesDependentResourceConfigBuilder<R> {
 
-  private Set<String> namespaces;
+  private Set<String> namespaces = Constants.SAME_AS_CONTROLLER_NAMESPACES_SET;
   private String labelSelector;
   private ResourceDiscriminator<R, ?> resourceDiscriminator;
   private OnAddFilter<R> onAddFilter;