envVars = new ArrayList<>(
- Optional.ofNullable(deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv())
- .orElse(new ArrayList<>()));
-
- V1EnvVar commonsDebug = new V1EnvVar()
- .name("LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD").value("DEBUG");
- V1EnvVar watcherDebug = new V1EnvVar()
- .name("LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER").value("DEBUG");
-
- envVars.add(commonsDebug);
- envVars.add(watcherDebug);
-
- if (disableReload) {
- V1EnvVar disableReloadEnvVar = new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_RELOAD_ENABLED").value("FALSE");
- envVars.add(disableReloadEnvVar);
- deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setEnv(envVars);
- }
-
+ .yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml");
V1Service service = (V1Service) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml");
@@ -192,6 +172,19 @@ class ActuatorRefreshIT {
}
+ // Create new configmap to trigger controller to signal app to refresh
+ private void createConfigMap() {
+ V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
+ .addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
+ util.createAndWait(NAMESPACE, configMap, null);
+ }
+
+ private void deleteConfigMap() {
+ V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata().withName("service-wiremock")
+ .addToLabels("spring.cloud.kubernetes.config", "true").endMetadata().addToData("foo", "bar").build();
+ util.deleteAndWait(NAMESPACE, configMap, null);
+ }
+
private String logs() {
try {
String appPodName = K3S.execInContainer("sh", "-c", "kubectl get pods -l app="
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java
similarity index 93%
rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java
rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java
index 108c3556..c8ae889a 100644
--- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java
+++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java
@@ -16,6 +16,7 @@
package org.springframework.cloud.kubernetes.configuration.watcher;
+import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Base64;
@@ -32,9 +33,7 @@ import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1SecretBuilder;
import io.kubernetes.client.openapi.models.V1Service;
import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.k3s.K3sContainer;
@@ -72,11 +71,15 @@ class ActuatorRefreshMultipleNamespacesIT {
util = new Util(K3S);
util.createNamespace(LEFT_NAMESPACE);
util.createNamespace(RIGHT_NAMESPACE);
+ util.wiremock(DEFAULT_NAMESPACE, "/", Phase.CREATE);
util.setUpClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE));
+ configWatcher(Phase.CREATE);
}
@AfterAll
static void afterAll() throws Exception {
+ configWatcher(Phase.DELETE);
+ util.wiremock(DEFAULT_NAMESPACE, "/", Phase.DELETE);
util.deleteClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE));
util.deleteNamespace(LEFT_NAMESPACE);
util.deleteNamespace(RIGHT_NAMESPACE);
@@ -84,18 +87,6 @@ class ActuatorRefreshMultipleNamespacesIT {
Commons.systemPrune();
}
- @BeforeEach
- void setup() {
- configWatcher(Phase.CREATE);
- util.wiremock(DEFAULT_NAMESPACE, "/", Phase.CREATE);
- }
-
- @AfterEach
- void after() {
- configWatcher(Phase.DELETE);
- util.wiremock(DEFAULT_NAMESPACE, "/", Phase.DELETE);
- }
-
/**
*
* - deploy config-watcher in default namespace
@@ -139,8 +130,8 @@ class ActuatorRefreshMultipleNamespacesIT {
() -> !WireMock.findAll(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh"))).isEmpty());
WireMock.verify(WireMock.exactly(2), WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh")));
- util.deleteAndWait(LEFT_NAMESPACE, leftConfigMap, null);
- util.deleteAndWait(RIGHT_NAMESPACE, rightConfigMap, null);
+ testSecretActuatorRefreshMultipleNamespaces();
+
}
/**
@@ -153,10 +144,8 @@ class ActuatorRefreshMultipleNamespacesIT {
* - same as above for the secret-right.
*
*/
- @Test
void testSecretActuatorRefreshMultipleNamespaces() {
- WireMock.configureFor(WIREMOCK_HOST, WIREMOCK_PORT, WIREMOCK_PATH);
- await().timeout(Duration.ofSeconds(60))
+ await().timeout(Duration.ofSeconds(60)).ignoreException(SocketException.class)
.until(() -> WireMock
.stubFor(WireMock.post(WireMock.urlEqualTo("/actuator/refresh"))
.willReturn(WireMock.aResponse().withBody("{}").withStatus(200)))
@@ -186,18 +175,15 @@ class ActuatorRefreshMultipleNamespacesIT {
await().atMost(Duration.ofSeconds(30)).until(
() -> !WireMock.findAll(WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh"))).isEmpty());
- WireMock.verify(WireMock.exactly(2), WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh")));
-
- util.deleteAndWait(LEFT_NAMESPACE, null, leftSecret);
- util.deleteAndWait(RIGHT_NAMESPACE, null, rightSecret);
+ WireMock.verify(WireMock.exactly(4), WireMock.postRequestedFor(WireMock.urlEqualTo("/actuator/refresh")));
}
- private void configWatcher(Phase phase) {
+ private static void configWatcher(Phase phase) {
V1ConfigMap configMap = (V1ConfigMap) util
.yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml");
V1Deployment deployment = (V1Deployment) util
- .yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml");
+ .yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml");
List envVars = List.of(
new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_RELOAD_NAMESPACES_0").value(LEFT_NAMESPACE),
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java
new file mode 100644
index 00000000..b9d77740
--- /dev/null
+++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013-2023 the original author or authors.
+ *
+ * Licensed 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
+ *
+ * https://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.springframework.cloud.kubernetes.configuration.watcher;
+
+import java.util.Map;
+
+import static org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util.patchWithReplace;
+
+/**
+ * @author wind57
+ */
+final class TestUtil {
+
+ private TestUtil() {
+
+ }
+
+ private static final Map POD_LABELS = Map.of("app",
+ "spring-cloud-kubernetes-configuration-watcher");
+
+ private static final String BODY_ONE = """
+ {
+ "spec": {
+ "template": {
+ "spec": {
+ "containers": [{
+ "name": "spring-cloud-kubernetes-configuration-watcher",
+ "image": "image_name_here",
+ "env": [
+ {
+ "name": "LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD",
+ "value": "DEBUG"
+ },
+ {
+ "name": "LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER",
+ "value": "DEBUG"
+ },
+ {
+ "name": "SPRING_CLOUD_KUBERNETES_RELOAD_ENABLED",
+ "value": "FALSE"
+ }
+ ]
+ }]
+ }
+ }
+ }
+ }
+ """;
+
+ static void patchForDisabledReload(String deploymentName, String namespace, String imageName) {
+ patchWithReplace(imageName, deploymentName, namespace, BODY_ONE, POD_LABELS);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml
similarity index 100%
rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml
rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-configmap.yaml
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml
similarity index 92%
rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml
rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml
index 403db22b..4d42d92b 100644
--- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml
+++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-deployment.yaml
@@ -1,7 +1,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: spring-cloud-kubernetes-configuration-watcher-deployment
+ name: spring-cloud-kubernetes-configuration-watcher
spec:
selector:
matchLabels:
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml
similarity index 100%
rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml
rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml
diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/logback-test.xml
similarity index 100%
rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/logback-test.xml
rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/resources/logback-test.xml
diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/Commons.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/Commons.java
index 3ae02cfd..3b44f35c 100644
--- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/Commons.java
+++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/Commons.java
@@ -240,13 +240,13 @@ public final class Commons {
/**
* the assumption is that there is only a single pod that is 'Running'.
*/
- public static void waitForLogStatement(String message, K3sContainer k3sContainer, String imageName) {
+ public static void waitForLogStatement(String message, K3sContainer k3sContainer, String appLabelValue) {
try {
await().atMost(Duration.ofMinutes(2)).pollInterval(Duration.ofSeconds(4)).until(() -> {
String appPodName = k3sContainer.execInContainer("sh", "-c",
- "kubectl get pods -l app=" + imageName
+ "kubectl get pods -l app=" + appLabelValue
+ " -o custom-columns=POD:metadata.name,STATUS:status.phase"
+ " | grep -i 'running' | awk '{print $1}' | tr -d '\n' ")
.getStdout();