diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index b0a4cfb5..1849176c 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -61,7 +61,6 @@ spring-cloud-kubernetes-client-reactive-discoveryclient-it spring-cloud-kubernetes-configuration-watcher-it spring-cloud-kubernetes-core-k8s-client-it - spring-cloud-kubernetes-client-secrets-event-reload spring-cloud-kubernetes-client-event-and-polling-reload spring-cloud-kubernetes-client-configmap-event-reload-multiple-apps spring-cloud-kubernetes-client-secrets-event-reload-multiple-apps diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/App.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/App.java similarity index 90% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/App.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/App.java index f8ea374d..a39ba5a6 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/App.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/App.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -25,7 +25,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties */ @SpringBootApplication @EnableConfigurationProperties({ LeftProperties.class, RightProperties.class, RightWithLabelsProperties.class, - ConfigMapProperties.class }) + ConfigMapProperties.class, SecretsProperties.class }) public class App { public static void main(String[] args) { diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/ConfigMapProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/ConfigMapProperties.java similarity index 93% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/ConfigMapProperties.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/ConfigMapProperties.java index 224773de..a99899f2 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/ConfigMapProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/ConfigMapProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/Controller.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/Controller.java similarity index 96% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/Controller.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/Controller.java index dec721af..791831d4 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/Controller.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/Controller.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/LeftProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/LeftProperties.java similarity index 92% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/LeftProperties.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/LeftProperties.java index fd7a7ef6..76407d99 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/LeftProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/LeftProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightProperties.java similarity index 93% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightProperties.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightProperties.java index 52049303..f30f2a6f 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightWithLabelsProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightWithLabelsProperties.java similarity index 93% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightWithLabelsProperties.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightWithLabelsProperties.java index a7c519b2..47a8d5f2 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/client/configmap/reload/RightWithLabelsProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/RightWithLabelsProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.configmap.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsController.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsController.java similarity index 93% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsController.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsController.java index 7d40247b..91be11c8 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsController.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.secrets.event.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsProperties.java similarity index 92% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsProperties.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsProperties.java index e48c7a83..4fb3d3e3 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/java/org/springframework/cloud/kubernetes/reload/SecretsProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.secrets.event.reload; +package org.springframework.cloud.kubernetes.reload; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/resources/application.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/resources/application-with-secret.yaml similarity index 99% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/resources/application.yaml rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/resources/application-with-secret.yaml index ed832dbe..fb844898 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/resources/application.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/main/resources/application-with-secret.yaml @@ -18,4 +18,3 @@ spring: secrets: enabled: true enable-api: true - diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/BootstrapEnabledPollingReloadConfigMapMountDelegate.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/BootstrapEnabledPollingReloadConfigMapMountDelegate.java index f82fe5b3..e6900bc5 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/BootstrapEnabledPollingReloadConfigMapMountDelegate.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/BootstrapEnabledPollingReloadConfigMapMountDelegate.java @@ -30,9 +30,6 @@ import org.springframework.http.HttpMethod; import org.springframework.web.reactive.function.client.WebClient; import static org.awaitility.Awaitility.await; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.builder; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchSix; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.retrySpec; /** * @author wind57 @@ -59,7 +56,7 @@ final class BootstrapEnabledPollingReloadConfigMapMountDelegate { Util util, String imageName) throws Exception { recreateMountConfigMap(util); - patchSix(deploymentName, "default", imageName); + K8sClientConfigMapReloadITUtil.patchSix(deploymentName, "default", imageName); // (1) Commons.waitForLogStatement("paths property sources : [/tmp/application.properties]", k3sContainer, @@ -70,9 +67,9 @@ final class BootstrapEnabledPollingReloadConfigMapMountDelegate { deploymentName); // (3) - WebClient webClient = builder().baseUrl("http://localhost/mount").build(); - String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) - .block(); + WebClient webClient = K8sClientConfigMapReloadITUtil.builder().baseUrl("http://localhost/mount").build(); + String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block(); // we first read the initial value from the configmap Assertions.assertEquals("as-mount-initial", result); @@ -84,8 +81,9 @@ final class BootstrapEnabledPollingReloadConfigMapMountDelegate { new CoreV1Api().replaceNamespacedConfigMap("poll-reload-as-mount", NAMESPACE, configMap, null, null, null, null); - await().timeout(Duration.ofSeconds(180)).until(() -> webClient.method(HttpMethod.GET).retrieve() - .bodyToMono(String.class).retryWhen(retrySpec()).block().equals("as-mount-changed")); + await().timeout(Duration.ofSeconds(180)) + .until(() -> webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block().equals("as-mount-changed")); } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/DataChangesInConfigMapReloadDelegate.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/DataChangesInConfigMapReloadDelegate.java index d4fc12ae..61971879 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/DataChangesInConfigMapReloadDelegate.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/DataChangesInConfigMapReloadDelegate.java @@ -32,10 +32,6 @@ import org.springframework.http.HttpMethod; import org.springframework.web.reactive.function.client.WebClient; import static org.awaitility.Awaitility.await; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.builder; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.logs; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchFour; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.retrySpec; /** * @author wind57 @@ -59,13 +55,14 @@ final class DataChangesInConfigMapReloadDelegate { */ static void testSimple(String dockerImage, String deploymentName, K3sContainer k3sContainer) { - patchFour(deploymentName, NAMESPACE, dockerImage); + K8sClientConfigMapReloadITUtil.patchFour(deploymentName, NAMESPACE, dockerImage); Commons.assertReloadLogStatements("added configmap informer for namespace", "added secret informer for namespace", deploymentName); - WebClient webClient = builder().baseUrl("http://localhost/" + LEFT_NAMESPACE).build(); - String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) - .block(); + WebClient webClient = K8sClientConfigMapReloadITUtil.builder().baseUrl("http://localhost/" + LEFT_NAMESPACE) + .build(); + String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block(); // we first read the initial value from the left-configmap Assertions.assertEquals("left-initial", result); @@ -79,13 +76,14 @@ final class DataChangesInConfigMapReloadDelegate { replaceConfigMap(configMap); await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { - WebClient innerWebClient = builder().baseUrl("http://localhost/" + LEFT_NAMESPACE).build(); + WebClient innerWebClient = K8sClientConfigMapReloadITUtil.builder() + .baseUrl("http://localhost/" + LEFT_NAMESPACE).build(); String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) - .retryWhen(retrySpec()).block(); + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block(); return "left-initial".equals(innerResult); }); - String logs = logs(deploymentName, k3sContainer); + String logs = K8sClientConfigMapReloadITUtil.logs(deploymentName, k3sContainer); Assertions.assertTrue(logs.contains("ConfigMap left-configmap was updated in namespace left")); Assertions.assertTrue(logs.contains("data in configmap has not changed, will not reload")); @@ -98,9 +96,10 @@ final class DataChangesInConfigMapReloadDelegate { replaceConfigMap(configMap); await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { - WebClient innerWebClient = builder().baseUrl("http://localhost/" + LEFT_NAMESPACE).build(); + WebClient innerWebClient = K8sClientConfigMapReloadITUtil.builder() + .baseUrl("http://localhost/" + LEFT_NAMESPACE).build(); String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) - .retryWhen(retrySpec()).block(); + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block(); return "left-after-change".equals(innerResult); }); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadIT.java index 903b1182..7e326c1c 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadIT.java @@ -45,11 +45,11 @@ import org.springframework.web.reactive.function.client.WebClient; import static org.awaitility.Awaitility.await; import static org.springframework.cloud.kubernetes.client.configmap.reload.BootstrapEnabledPollingReloadConfigMapMountDelegate.testBootstrapEnabledPollingReloadConfigMapMount; import static org.springframework.cloud.kubernetes.client.configmap.reload.DataChangesInConfigMapReloadDelegate.testSimple; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.builder; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchOne; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchThree; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchTwo; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.retrySpec; +import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientConfigMapReloadITUtil.builder; +import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientConfigMapReloadITUtil.patchOne; +import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientConfigMapReloadITUtil.patchThree; +import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientConfigMapReloadITUtil.patchTwo; +import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientConfigMapReloadITUtil.retrySpec; import static org.springframework.cloud.kubernetes.client.configmap.reload.PollingReloadConfigMapMountDelegate.testPollingReloadConfigMapMount; /** diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientReloadITUtil.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadITUtil.java similarity index 99% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientReloadITUtil.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadITUtil.java index 8922dd82..4f5680be 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientReloadITUtil.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/K8sClientConfigMapReloadITUtil.java @@ -34,12 +34,11 @@ import static org.springframework.cloud.kubernetes.integration.tests.commons.nat /** * @author wind57 */ -final class K8sClientReloadITUtil { +final class K8sClientConfigMapReloadITUtil { private static final Map POD_LABELS = Map.of("app", "spring-k8s-client-reload"); - private K8sClientReloadITUtil() { - + private K8sClientConfigMapReloadITUtil() { } private static final String BODY_ONE = """ diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/PollingReloadConfigMapMountDelegate.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/PollingReloadConfigMapMountDelegate.java index 8bae0696..8bc99f43 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/PollingReloadConfigMapMountDelegate.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/configmap/reload/PollingReloadConfigMapMountDelegate.java @@ -30,9 +30,6 @@ import org.springframework.http.HttpMethod; import org.springframework.web.reactive.function.client.WebClient; import static org.awaitility.Awaitility.await; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.builder; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.patchFive; -import static org.springframework.cloud.kubernetes.client.configmap.reload.K8sClientReloadITUtil.retrySpec; /** * @author wind57 @@ -61,7 +58,7 @@ final class PollingReloadConfigMapMountDelegate { static void testPollingReloadConfigMapMount(String deploymentName, K3sContainer k3sContainer, Util util, String imageName) throws Exception { - patchFive(deploymentName, "default", imageName); + K8sClientConfigMapReloadITUtil.patchFive(deploymentName, "default", imageName); // (1) Commons.waitForLogStatement("paths property sources : [/tmp/application.properties]", k3sContainer, @@ -72,9 +69,9 @@ final class PollingReloadConfigMapMountDelegate { deploymentName); // (3) - WebClient webClient = builder().baseUrl("http://localhost/mount").build(); - String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) - .block(); + WebClient webClient = K8sClientConfigMapReloadITUtil.builder().baseUrl("http://localhost/mount").build(); + String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block(); // we first read the initial value from the configmap Assertions.assertEquals("as-mount-initial", result); @@ -86,8 +83,9 @@ final class PollingReloadConfigMapMountDelegate { new CoreV1Api().replaceNamespacedConfigMap("poll-reload-as-mount", "default", configMap, null, null, null, null); - await().timeout(Duration.ofSeconds(180)).until(() -> webClient.method(HttpMethod.GET).retrieve() - .bodyToMono(String.class).retryWhen(retrySpec()).block().equals("as-mount-changed")); + await().timeout(Duration.ofSeconds(180)) + .until(() -> webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(K8sClientConfigMapReloadITUtil.retrySpec()).block().equals("as-mount-changed")); } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/DataChangesInSecretsReloadDelegate.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/DataChangesInSecretsReloadDelegate.java new file mode 100644 index 00000000..71178fae --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/DataChangesInSecretsReloadDelegate.java @@ -0,0 +1,110 @@ +/* + * 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.client.secrets.reload; + +import java.time.Duration; +import java.util.Map; + +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder; +import io.kubernetes.client.openapi.models.V1Secret; +import io.kubernetes.client.openapi.models.V1SecretBuilder; +import org.junit.jupiter.api.Assertions; +import org.testcontainers.k3s.K3sContainer; + +import org.springframework.cloud.kubernetes.integration.tests.commons.Commons; +import org.springframework.http.HttpMethod; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.awaitility.Awaitility.await; +import static org.springframework.cloud.kubernetes.client.secrets.reload.K8sClientSecretsReloadITUtil.builder; +import static org.springframework.cloud.kubernetes.client.secrets.reload.K8sClientSecretsReloadITUtil.retrySpec; + +final class DataChangesInSecretsReloadDelegate { + + private static final String NAMESPACE = "default"; + + /** + *
+	 *     - secret with no labels and data: from.properties.key = initial exists in namespace default
+	 *     - we assert that we can read it correctly first, by invoking localhost/key.
+	 *
+	 *     - then we change the secret by adding a label, this in turn does not
+	 *       change the result of localhost/key, because the data has not changed.
+	 *
+	 *     - then we change data inside the secret, and we must see the updated value.
+	 * 
+ */ + static void testDataChangesInSecretsReload(K3sContainer k3sContainer, String deploymentName) { + Commons.assertReloadLogStatements("added secret informer for namespace", + "added configmap informer for namespace", deploymentName); + + WebClient webClient = builder().baseUrl("http://localhost/key").build(); + String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) + .block(); + + // we first read the initial value from the secret + Assertions.assertEquals("initial", result); + + // then deploy a new version of left-configmap, but without changing its data, + // only add a label + V1Secret secret = new V1SecretBuilder() + .withMetadata(new V1ObjectMetaBuilder().withLabels(Map.of("new-label", "abc")).withNamespace(NAMESPACE) + .withName("event-reload").build()) + .withData(Map.of("application.properties", "from.properties.key=initial".getBytes())).build(); + + replaceSecret(secret, "event-reload"); + + await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { + WebClient innerWebClient = builder().baseUrl("http://localhost/key").build(); + String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(retrySpec()).block(); + return "initial".equals(innerResult); + }); + + Commons.waitForLogStatement("Secret event-reload was updated in namespace default", k3sContainer, + deploymentName); + Commons.waitForLogStatement("data in secret has not changed, will not reload", k3sContainer, deploymentName); + + // change data + secret = new V1SecretBuilder() + .withMetadata(new V1ObjectMetaBuilder().withLabels(Map.of("new-label", "abc")).withNamespace(NAMESPACE) + .withName("event-reload").build()) + .withData(Map.of("application.properties", "from.properties.key=change-initial".getBytes())).build(); + + replaceSecret(secret, "event-reload"); + + await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { + WebClient innerWebClient = builder().baseUrl("http://localhost/key").build(); + String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(retrySpec()).block(); + return "change-initial".equals(innerResult); + }); + + } + + private static void replaceSecret(V1Secret secret, String name) { + try { + new CoreV1Api().replaceNamespacedSecret(name, NAMESPACE, secret, null, null, null, null); + } + catch (ApiException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadIT.java similarity index 71% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadIT.java index 64fe5a56..905afb39 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * 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. @@ -14,18 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.client.secrets.event.reload; +package org.springframework.cloud.kubernetes.client.secrets.reload; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import io.kubernetes.client.openapi.apis.CoreV1Api; import io.kubernetes.client.openapi.models.V1Deployment; -import io.kubernetes.client.openapi.models.V1EnvVar; import io.kubernetes.client.openapi.models.V1Ingress; import io.kubernetes.client.openapi.models.V1Secret; import io.kubernetes.client.openapi.models.V1Service; @@ -33,30 +28,34 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.testcontainers.k3s.K3sContainer; -import reactor.netty.http.client.HttpClient; -import reactor.util.retry.Retry; -import reactor.util.retry.RetryBackoffSpec; import org.springframework.cloud.kubernetes.integration.tests.commons.Commons; import org.springframework.cloud.kubernetes.integration.tests.commons.Phase; import org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util; import org.springframework.http.HttpMethod; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; import static org.awaitility.Awaitility.await; +import static org.springframework.cloud.kubernetes.client.secrets.reload.DataChangesInSecretsReloadDelegate.testDataChangesInSecretsReload; +import static org.springframework.cloud.kubernetes.client.secrets.reload.K8sClientSecretsReloadITUtil.builder; +import static org.springframework.cloud.kubernetes.client.secrets.reload.K8sClientSecretsReloadITUtil.patchOne; +import static org.springframework.cloud.kubernetes.client.secrets.reload.K8sClientSecretsReloadITUtil.retrySpec; /** * @author wind57 */ -class SecretsEventReloadIT { +class K8sClientSecretsReloadIT { private static final String PROPERTY_URL = "http://localhost:80/key"; - private static final String IMAGE_NAME = "spring-cloud-kubernetes-client-secrets-event-reload"; + private static final String IMAGE_NAME = "spring-cloud-kubernetes-client-event-and-polling-reload"; private static final String NAMESPACE = "default"; + private static final String DEPLOYMENT_NAME = "spring-k8s-client-reload"; + + private static final String DOCKER_IMAGE = "docker.io/springcloud/" + IMAGE_NAME + ":" + Commons.pomVersion(); + private static final K3sContainer K3S = Commons.container(); private static Util util; @@ -71,30 +70,39 @@ class SecretsEventReloadIT { util = new Util(K3S); coreV1Api = new CoreV1Api(); util.setUp(NAMESPACE); + configK8sClientIt(Phase.CREATE); } @AfterAll static void afterAll() throws Exception { + configK8sClientIt(Phase.DELETE); Commons.cleanUp(IMAGE_NAME, K3S); Commons.systemPrune(); } @Test void testSecretReload() throws Exception { - configK8sClientIt(Phase.CREATE, false); Commons.assertReloadLogStatements("added secret informer for namespace", - "added configmap informer for namespace", IMAGE_NAME); + "added configmap informer for namespace", DEPLOYMENT_NAME); testSecretEventReload(); - configK8sClientIt(Phase.DELETE, false); + + testAllOther(); + } + + private void testAllOther() throws Exception { + recreateSecret(); + patchOne(DEPLOYMENT_NAME, NAMESPACE, DOCKER_IMAGE); + testSecretReloadConfigDisabled(); + + recreateSecret(); + patchOne(DEPLOYMENT_NAME, NAMESPACE, DOCKER_IMAGE); + testDataChangesInSecretsReload(K3S, DEPLOYMENT_NAME); } - @Test void testSecretReloadConfigDisabled() throws Exception { - configK8sClientIt(Phase.CREATE, true); Commons.assertReloadLogStatements("added secret informer for namespace", - "added configmap informer for namespace", IMAGE_NAME); + "added configmap informer for namespace", DEPLOYMENT_NAME); testSecretEventReload(); - configK8sClientIt(Phase.DELETE, true); } void testSecretEventReload() throws Exception { @@ -117,22 +125,18 @@ class SecretsEventReloadIT { .retryWhen(retrySpec()).block().equals("after-change")); } - private void configK8sClientIt(Phase phase, boolean configDisabled) { - V1Deployment deployment = (V1Deployment) util.yaml("deployment.yaml"); + private void recreateSecret() { + V1Secret secret = (V1Secret) util.yaml("secret.yaml"); + util.deleteAndWait(NAMESPACE, null, secret); + util.createAndWait(NAMESPACE, null, secret); + } + + private static void configK8sClientIt(Phase phase) { + V1Deployment deployment = (V1Deployment) util.yaml("deployment-with-secret.yaml"); V1Service service = (V1Service) util.yaml("service.yaml"); V1Ingress ingress = (V1Ingress) util.yaml("ingress.yaml"); V1Secret secret = (V1Secret) util.yaml("secret.yaml"); - List envVars = new ArrayList<>( - Optional.ofNullable(deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv()) - .orElse(List.of())); - - if (configDisabled) { - V1EnvVar disableConfig = new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_CONFIG_ENABLED").value("FALSE"); - envVars.add(disableConfig); - deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setEnv(envVars); - } - if (phase.equals(Phase.CREATE)) { util.createAndWait(NAMESPACE, null, deployment, service, ingress, true); util.createAndWait(NAMESPACE, null, secret); @@ -143,12 +147,4 @@ class SecretsEventReloadIT { } } - private WebClient.Builder builder() { - return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())); - } - - private RetryBackoffSpec retrySpec() { - return Retry.fixedDelay(60, Duration.ofSeconds(2)).filter(Objects::nonNull); - } - } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadITUtil.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadITUtil.java new file mode 100644 index 00000000..c58051b0 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/reload/K8sClientSecretsReloadITUtil.java @@ -0,0 +1,102 @@ +/* + * 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.client.secrets.reload; + +import java.time.Duration; +import java.util.Map; +import java.util.Objects; + +import reactor.netty.http.client.HttpClient; +import reactor.util.retry.Retry; +import reactor.util.retry.RetryBackoffSpec; + +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util.patchWithReplace; + +/** + * @author wind57 + */ +final class K8sClientSecretsReloadITUtil { + + private static final Map POD_LABELS = Map.of("app", "spring-k8s-client-reload"); + + private static final String BODY_ONE = """ + { + "spec": { + "template": { + "spec": { + "containers": [{ + "name": "spring-k8s-client-reload", + "image": "image_name_here", + "livenessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/actuator/health/liveness", + "port": 8080, + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 1 + }, + "readinessProbe": { + "failureThreshold": 3, + "httpGet": { + "path": "/actuator/health/readiness", + "port": 8080, + "scheme": "HTTP" + }, + "periodSeconds": 10, + "successThreshold": 1, + "timeoutSeconds": 1 + }, + "env": [ + { + "name": "SPRING_CLOUD_KUBERNETES_CONFIG_ENABLED", + "value": "FALSE" + }, + { + "name": "SPRING_PROFILES_ACTIVE", + "value": "with-secret" + } + ] + }] + } + } + } + } + """; + + private K8sClientSecretsReloadITUtil() { + + } + + static WebClient.Builder builder() { + return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())); + } + + static RetryBackoffSpec retrySpec() { + return Retry.fixedDelay(60, Duration.ofSeconds(2)).filter(Objects::nonNull); + } + + static void patchOne(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-client-secrets-event-reload/src/test/resources/deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/resources/deployment-with-secret.yaml similarity index 71% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/deployment.yaml rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/resources/deployment-with-secret.yaml index 116475e4..21f9a2e8 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/deployment.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/resources/deployment-with-secret.yaml @@ -1,20 +1,20 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: spring-cloud-kubernetes-client-secrets-deployment-event-reload + name: spring-k8s-client-reload spec: selector: matchLabels: - app: spring-cloud-kubernetes-client-secrets-event-reload + app: spring-k8s-client-reload template: metadata: labels: - app: spring-cloud-kubernetes-client-secrets-event-reload + app: spring-k8s-client-reload spec: serviceAccountName: spring-cloud-kubernetes-serviceaccount containers: - - name: spring-cloud-kubernetes-client-secrets-event-reload - image: docker.io/springcloud/spring-cloud-kubernetes-client-secrets-event-reload + - name: spring-k8s-client-reload + image: docker.io/springcloud/spring-cloud-kubernetes-client-event-and-polling-reload imagePullPolicy: IfNotPresent readinessProbe: httpGet: @@ -29,3 +29,5 @@ spec: env: - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CLIENT_CONFIG_RELOAD value: DEBUG + - name: SPRING_PROFILES_ACTIVE + value: "with-secret" diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/secret.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/resources/secret.yaml similarity index 100% rename from spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/secret.yaml rename to spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-event-and-polling-reload/src/test/resources/secret.yaml diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/pom.xml deleted file mode 100644 index 3057b98f..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/pom.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - org.springframework.cloud - spring-cloud-kubernetes-integration-tests - 3.1.0-SNAPSHOT - - 4.0.0 - - spring-cloud-kubernetes-client-secrets-event-reload - - - - org.springframework.cloud - spring-cloud-starter-kubernetes-client-config - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.boot - spring-boot-starter-actuator - - - - org.springframework.cloud - spring-cloud-kubernetes-test-support - - - - - - - - ../src/main/resources - true - - - src/main/resources - true - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - docker.io/springcloud/${project.artifactId}:${project.version} - - - - build-image - - ${skip.build.image} - - package - - build-image - - - - repackage - package - - repackage - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - - - - - - ${testsToRun} - - - - - - - - diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsApp.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsApp.java deleted file mode 100644 index 72056a23..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsApp.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2022 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.client.secrets.event.reload; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; - -/** - * @author wind57 - */ - -@SpringBootApplication -@EnableConfigurationProperties(SecretsProperties.class) -public class SecretsApp { - - public static void main(String[] args) { - SpringApplication.run(SecretsApp.class, args); - } - -} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/DataChangesInSecretsReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/DataChangesInSecretsReloadIT.java deleted file mode 100644 index bec495be..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/DataChangesInSecretsReloadIT.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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.client.secrets.event.reload; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -import io.kubernetes.client.openapi.ApiException; -import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.kubernetes.client.openapi.models.V1Deployment; -import io.kubernetes.client.openapi.models.V1EnvVar; -import io.kubernetes.client.openapi.models.V1Ingress; -import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder; -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.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.Container; -import org.testcontainers.k3s.K3sContainer; -import reactor.netty.http.client.HttpClient; -import reactor.util.retry.Retry; -import reactor.util.retry.RetryBackoffSpec; - -import org.springframework.cloud.kubernetes.integration.tests.commons.Commons; -import org.springframework.cloud.kubernetes.integration.tests.commons.Phase; -import org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.awaitility.Awaitility.await; - -class DataChangesInSecretsReloadIT { - - private static final String IMAGE_NAME = "spring-cloud-kubernetes-client-secrets-event-reload"; - - private static final String NAMESPACE = "default"; - - private static final K3sContainer K3S = Commons.container(); - - private static Util util; - - private static CoreV1Api api; - - @BeforeAll - static void beforeAll() throws Exception { - K3S.start(); - Commons.validateImage(IMAGE_NAME, K3S); - Commons.loadSpringCloudKubernetesImage(IMAGE_NAME, K3S); - - util = new Util(K3S); - api = new CoreV1Api(); - - util.setUpClusterWide(NAMESPACE, Set.of(NAMESPACE)); - } - - @AfterAll - static void afterAll() throws Exception { - Commons.cleanUp(IMAGE_NAME, K3S); - Commons.systemPrune(); - } - - /** - *
-	 *     - secret with no labels and data: from.properties.key = initial exists in namespace default
-	 *     - we assert that we can read it correctly first, by invoking localhost/key.
-	 *
-	 *     - then we change the secret by adding a label, this in turn does not
-	 *       change the result of localhost/key, because the data has not changed.
-	 *
-	 *     - then we change data inside the secret, and we must see the updated value.
-	 * 
- */ - @Test - void testSimple() { - manifests(Phase.CREATE); - Commons.assertReloadLogStatements("added secret informer for namespace", - "added configmap informer for namespace", IMAGE_NAME); - - WebClient webClient = builder().baseUrl("http://localhost/key").build(); - String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) - .block(); - - // we first read the initial value from the secret - Assertions.assertEquals("initial", result); - - // then deploy a new version of left-configmap, but without changing its data, - // only add a label - V1Secret secret = new V1SecretBuilder() - .withMetadata(new V1ObjectMetaBuilder().withLabels(Map.of("new-label", "abc")).withNamespace(NAMESPACE) - .withName("event-reload").build()) - .withData(Map.of("application.properties", "from.properties.key=initial".getBytes())).build(); - - replaceSecret(secret, "event-reload"); - - await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { - WebClient innerWebClient = builder().baseUrl("http://localhost/key").build(); - String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) - .retryWhen(retrySpec()).block(); - return "initial".equals(innerResult); - }); - - String logs = logs(); - Assertions.assertTrue(logs.contains("Secret event-reload was updated in namespace default")); - Assertions.assertTrue(logs.contains("data in secret has not changed, will not reload")); - - // change data - secret = new V1SecretBuilder() - .withMetadata(new V1ObjectMetaBuilder().withLabels(Map.of("new-label", "abc")).withNamespace(NAMESPACE) - .withName("event-reload").build()) - .withData(Map.of("application.properties", "from.properties.key=change-initial".getBytes())).build(); - - replaceSecret(secret, "event-reload"); - - await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(90)).until(() -> { - WebClient innerWebClient = builder().baseUrl("http://localhost/key").build(); - String innerResult = innerWebClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) - .retryWhen(retrySpec()).block(); - return "change-initial".equals(innerResult); - }); - - manifests(Phase.DELETE); - } - - private static void manifests(Phase phase) { - - try { - - V1Secret secret = (V1Secret) util.yaml("secret.yaml"); - V1Deployment deployment = (V1Deployment) util.yaml("deployment.yaml"); - V1Service service = (V1Service) util.yaml("service.yaml"); - V1Ingress ingress = (V1Ingress) util.yaml("ingress.yaml"); - - List envVars = new ArrayList<>( - Optional.ofNullable(deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv()) - .orElse(List.of())); - - V1EnvVar configDisabledEnvVar = new V1EnvVar().name("SPRING_CLOUD_KUBERNETES_CONFIG_ENABLED") - .value("FALSE"); - envVars.add(configDisabledEnvVar); - deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setEnv(envVars); - - if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, secret); - util.createAndWait(NAMESPACE, null, deployment, service, ingress, true); - } - - if (phase.equals(Phase.DELETE)) { - util.deleteAndWait(NAMESPACE, null, secret); - util.deleteAndWait(NAMESPACE, deployment, service, ingress); - } - - } - catch (Exception e) { - throw new RuntimeException(e); - } - - } - - private String logs() { - try { - String appPodName = K3S.execInContainer("sh", "-c", - "kubectl get pods -l app=" + IMAGE_NAME + " -o=name --no-headers | tr -d '\n'").getStdout(); - - Container.ExecResult execResult = K3S.execInContainer("sh", "-c", "kubectl logs " + appPodName.trim()); - return execResult.getStdout(); - } - catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - private WebClient.Builder builder() { - return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())); - } - - private RetryBackoffSpec retrySpec() { - return Retry.fixedDelay(120, Duration.ofSeconds(2)).filter(Objects::nonNull); - } - - private static void replaceSecret(V1Secret secret, String name) { - try { - api.replaceNamespacedSecret(name, NAMESPACE, secret, null, null, null, null); - } - catch (ApiException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/ingress.yaml deleted file mode 100644 index 7c74d618..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/ingress.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: spring-cloud-kubernetes-client-secrets-ingress-event-reload - namespace: default -spec: - rules: - - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: spring-cloud-kubernetes-client-secrets-event-reload - port: - number: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/logback-test.xml deleted file mode 100644 index 9e284876..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/logback-test.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n - - - - - - - - - - diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/service.yaml deleted file mode 100644 index e1fb85db..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: spring-cloud-kubernetes-client-secrets-event-reload - name: spring-cloud-kubernetes-client-secrets-event-reload -spec: - ports: - - name: http - port: 8080 - targetPort: 8080 - selector: - app: spring-cloud-kubernetes-client-secrets-event-reload - type: ClusterIP