This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/spark-kubernetes-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 93204b2  [SPARK-52755] Remove `ConfigMap` informer from config 
reconciler
93204b2 is described below

commit 93204b2692117cd815a9561901deeb42adfb5716
Author: Attila Mészáros <a_mesza...@apple.com>
AuthorDate: Wed Jul 16 13:42:43 2025 -0700

    [SPARK-52755] Remove `ConfigMap` informer from config reconciler
    
    ### What changes were proposed in this pull request?
    
    PR removes unnecessary informer for the configuration 
`SparkOperatorConfigMapReconciler`.
    It adds a sanity test using `KubeApiTest`.
    
    ### Why are the changes needed?
    
    Having additional informer might effect performance, memory consumption, 
also maintains an additiona websocket connection to Kubernetes API.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No, but introduces new way of testing.
    
    ### How was this patch tested?
    
    With an integration test.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No
    
    Closes #281 from csviri/remove-informer-config-reconciler.
    
    Authored-by: Attila Mészáros <a_mesza...@apple.com>
    Signed-off-by: Dongjoon Hyun <dongj...@apache.org>
---
 gradle/libs.versions.toml                          |  1 +
 spark-operator/build.gradle                        |  1 +
 .../apache/spark/k8s/operator/SparkOperator.java   |  4 +-
 .../config/SparkOperatorConfigMapReconciler.java   | 18 -----
 .../SparkOperatorConfigMapReconcilerTest.java      | 87 ++++++++++++++++++++++
 5 files changed, 90 insertions(+), 21 deletions(-)

diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index c4c7f55..6e69d73 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -42,6 +42,7 @@ shadow-jar-plugin = "8.3.6"
 kubernetes-client = { group = "io.fabric8", name = "kubernetes-client", 
version.ref = "fabric8" }
 kubernetes-httpclient-okhttp = { group = "io.fabric8", name = 
"kubernetes-httpclient-okhttp", version.ref = "fabric8" }
 kubernetes-server-mock = { group = "io.fabric8", name = 
"kubernetes-server-mock", version.ref = "fabric8" }
+kube-api-test-client-inject = {group = "io.fabric8", name = 
"kube-api-test-client-inject", version.ref = "fabric8"}
 crd-generator-apt = { group = "io.fabric8", name = "crd-generator-apt", 
version.ref = "fabric8" }
 okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = 
"okhttp" }
 mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", 
version.ref = "okhttp" }
diff --git a/spark-operator/build.gradle b/spark-operator/build.gradle
index 5d3a690..b2106e1 100644
--- a/spark-operator/build.gradle
+++ b/spark-operator/build.gradle
@@ -80,6 +80,7 @@ dependencies {
   testRuntimeOnly(libs.junit.platform.launcher)
 
   testImplementation(libs.mockito.core)
+  testImplementation(libs.kube.api.test.client.inject)
 }
 
 test {
diff --git 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/SparkOperator.java 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/SparkOperator.java
index 9edeb1d..3d492bd 100644
--- 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/SparkOperator.java
+++ 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/SparkOperator.java
@@ -128,9 +128,7 @@ public class SparkOperator {
         confSelector);
     op.register(
         new SparkOperatorConfigMapReconciler(
-            this::updateWatchingNamespaces,
-            SparkOperatorConf.OPERATOR_NAMESPACE.getValue(),
-            unused -> getWatchedNamespaces()),
+            this::updateWatchingNamespaces, unused -> getWatchedNamespaces()),
         c -> {
           c.withRateLimiter(SparkOperatorConf.getOperatorRateLimiter());
           c.settingNamespaces(operatorNamespace);
diff --git 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconciler.java
 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconciler.java
index 491057d..1a282b3 100644
--- 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconciler.java
+++ 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconciler.java
@@ -19,20 +19,15 @@
 
 package org.apache.spark.k8s.operator.config;
 
-import java.util.List;
 import java.util.Set;
 import java.util.function.Function;
 
 import io.fabric8.kubernetes.api.model.ConfigMap;
-import 
io.javaoperatorsdk.operator.api.config.informer.InformerEventSourceConfiguration;
 import io.javaoperatorsdk.operator.api.reconciler.Context;
 import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
 import io.javaoperatorsdk.operator.api.reconciler.ErrorStatusUpdateControl;
-import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
 import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
 import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
-import io.javaoperatorsdk.operator.processing.event.source.EventSource;
-import 
io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
@@ -46,7 +41,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class SparkOperatorConfigMapReconciler implements Reconciler<ConfigMap> 
{
   private final Function<Set<String>, Boolean> namespaceUpdater;
-  private final String operatorNamespace;
   private final Function<Void, Set<String>> watchedNamespacesGetter;
 
   @Override
@@ -56,18 +50,6 @@ public class SparkOperatorConfigMapReconciler implements 
Reconciler<ConfigMap> {
     return ErrorStatusUpdateControl.noStatusUpdate();
   }
 
-  @Override
-  public List<EventSource<?, ConfigMap>> prepareEventSources(
-      EventSourceContext<ConfigMap> context) {
-    var configMapEventSource =
-        new InformerEventSource<>(
-            InformerEventSourceConfiguration.from(ConfigMap.class, 
ConfigMap.class)
-                .withNamespaces(Set.of(operatorNamespace))
-                .build(),
-            context);
-    return List.of(configMapEventSource);
-  }
-
   @Override
   public UpdateControl<ConfigMap> reconcile(ConfigMap resource, 
Context<ConfigMap> context)
       throws Exception {
diff --git 
a/spark-operator/src/test/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconcilerTest.java
 
b/spark-operator/src/test/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconcilerTest.java
new file mode 100644
index 0000000..603d74b
--- /dev/null
+++ 
b/spark-operator/src/test/java/org/apache/spark/k8s/operator/config/SparkOperatorConfigMapReconcilerTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.spark.k8s.operator.config;
+
+import static 
org.apache.spark.k8s.operator.config.SparkOperatorConf.RECONCILER_INTERVAL_SECONDS;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+import static org.mockito.Mockito.mock;
+
+import java.util.Map;
+import java.util.function.Function;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.fabric8.kubeapitest.junit.EnableKubeAPIServer;
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.Operator;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+@SuppressFBWarnings(
+    value = {"UWF_UNWRITTEN_FIELD"},
+    justification = "Unwritten fields are covered by Kubernetes mock client")
+@EnableKubeAPIServer
+class SparkOperatorConfigMapReconcilerTest {
+
+  public static final Long TARGET_RECONCILER_INTERVAL = 60L;
+
+  private static KubernetesClient client;
+
+  Operator operator;
+
+  @BeforeEach
+  @SuppressWarnings("unchecked")
+  void startController() {
+    var reconciler =
+        new SparkOperatorConfigMapReconciler(mock(Function.class), 
mock(Function.class));
+    operator = new Operator(o -> o.withKubernetesClient(client));
+    operator.register(reconciler);
+    operator.start();
+  }
+
+  @AfterEach
+  void stopController() {
+    operator.stop();
+  }
+
+  @Test
+  @SuppressWarnings("PMD.UnitTestShouldIncludeAssert")
+  void sanityTest() {
+    client.resource(testConfigMap()).create();
+
+    await()
+        .untilAsserted(
+            () -> {
+              
assertThat(RECONCILER_INTERVAL_SECONDS.getValue()).isEqualTo(60L);
+            });
+  }
+
+  ConfigMap testConfigMap() {
+    ConfigMap configMap = new ConfigMap();
+    configMap.setMetadata(
+        new 
ObjectMetaBuilder().withName("spark-conf").withNamespace("default").build());
+    configMap.setData(
+        Map.of(RECONCILER_INTERVAL_SECONDS.getKey(), 
TARGET_RECONCILER_INTERVAL.toString()));
+    return configMap;
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org
For additional commands, e-mail: commits-h...@spark.apache.org

Reply via email to