From ba0288cf6d8482fef5ec99108c31a5fa29e9182d Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 9 Apr 2026 15:38:20 +0300 Subject: [PATCH 1/5] 2208: breaking changes Signed-off-by: wind57 --- .../config/reload/ConfigReloadProperties.java | 44 ++----------------- .../config/ConfigReloadPropertiesTests.java | 4 -- 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java index 8fd85f0c11..0141c3c967 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java @@ -21,7 +21,6 @@ import java.util.Set; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.bind.ConstructorBinding; import org.springframework.boot.context.properties.bind.DefaultValue; /** @@ -37,9 +36,6 @@ * @param period Sets the polling period to use when the detection mode is POLLING. * @param namespaces namespaces where an informer will be set-up. this property is only * relevant for event based reloading. - * @param enableReloadFiltering create an informer only for sources that have - * 'spring.cloud.kubernetes.config.informer.enabled=true' label. This property is only - * relevant for event based reloading. * @param maxWaitForRestart Restart or Shutdown strategies are used, Spring Cloud * Kubernetes waits a random amount of time before restarting. This is done in order to * avoid having all instances of the same application restart at the same time. This @@ -48,53 +44,19 @@ * @author Nicola Ferraro */ @ConfigurationProperties(prefix = "spring.cloud.kubernetes.reload") -public record ConfigReloadProperties(boolean enabled, boolean monitoringConfigMaps, - Map configMapsLabels, - boolean monitoringSecrets, Map secretsLabels, - ReloadStrategy strategy, - ReloadDetectionMode mode, Duration period, - Set namespaces, boolean enableReloadFiltering, - Duration maxWaitForRestart) { - - @ConstructorBinding - public ConfigReloadProperties(boolean enabled, @DefaultValue("true") boolean monitoringConfigMaps, +public record ConfigReloadProperties(boolean enabled, @DefaultValue("true") boolean monitoringConfigMaps, @DefaultValue Map configMapsLabels, boolean monitoringSecrets, @DefaultValue Map secretsLabels, @DefaultValue("REFRESH") ReloadStrategy strategy, @DefaultValue("EVENT") ReloadDetectionMode mode, @DefaultValue("15000ms") Duration period, - @DefaultValue Set namespaces, boolean enableReloadFiltering, + @DefaultValue Set namespaces, @DefaultValue("2s") Duration maxWaitForRestart) { - this.enabled = enabled; - this.monitoringConfigMaps = monitoringConfigMaps; - this.configMapsLabels = configMapsLabels; - this.monitoringSecrets = monitoringSecrets; - this.secretsLabels = secretsLabels; - this.strategy = strategy; - this.mode = mode; - this.period = period; - this.namespaces = namespaces; - this.enableReloadFiltering = enableReloadFiltering; - this.maxWaitForRestart = maxWaitForRestart; - } - - @Deprecated(forRemoval = true) - public ConfigReloadProperties(boolean enabled, @DefaultValue("true") boolean monitoringConfigMaps, - boolean monitoringSecrets, - @DefaultValue("REFRESH") ReloadStrategy strategy, - @DefaultValue("EVENT") ReloadDetectionMode mode, @DefaultValue("15000ms") Duration period, - @DefaultValue Set namespaces, boolean enableReloadFiltering, - @DefaultValue("2s") Duration maxWaitForRestart) { - - this(enabled, monitoringConfigMaps, Map.of(), monitoringSecrets, Map.of(), - strategy, mode, period, namespaces, enableReloadFiltering, maxWaitForRestart); - } - /** * default instance. */ public static final ConfigReloadProperties DEFAULT = new ConfigReloadProperties(false, true, Map.of(), false, - Map.of(), ReloadStrategy.REFRESH, ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), false, + Map.of(), ReloadStrategy.REFRESH, ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), Duration.ofSeconds(2)); /** diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigReloadPropertiesTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigReloadPropertiesTests.java index 43d5b50863..63abc13eb7 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigReloadPropertiesTests.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigReloadPropertiesTests.java @@ -19,7 +19,6 @@ import java.time.Duration; import java.util.Map; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -54,7 +53,6 @@ void testDefaults() { assertThat(ConfigReloadProperties.ReloadDetectionMode.EVENT).isEqualTo(properties.mode()); assertThat(Duration.ofMillis(15000)).isEqualTo(properties.period()); assertThat(properties.namespaces().isEmpty()).isTrue(); - assertThat(properties.enableReloadFiltering()).isFalse(); assertThat(Duration.ofSeconds(2)).isEqualTo(properties.maxWaitForRestart()); }); } @@ -70,7 +68,6 @@ void testNonDefaults() { "spring.cloud.kubernetes.reload.strategy=SHUTDOWN", "spring.cloud.kubernetes.reload.mode=POLLING", "spring.cloud.kubernetes.reload.period=1000ms", "spring.cloud.kubernetes.reload.namespaces[0]=a", "spring.cloud.kubernetes.reload.namespaces[1]=b", - "spring.cloud.kubernetes.reload.enable-reload-filtering=true", "spring.cloud.kubernetes.reload.max-wait-for-restart=5s") .run(context -> { ConfigReloadProperties properties = context.getBean(ConfigReloadProperties.class); @@ -84,7 +81,6 @@ void testNonDefaults() { assertThat(ConfigReloadProperties.ReloadDetectionMode.POLLING).isEqualTo(properties.mode()); assertThat(Duration.ofMillis(1000)).isEqualTo(properties.period()); assertThat(properties.namespaces()).containsExactlyInAnyOrder("a", "b"); - assertThat(properties.enableReloadFiltering()).isTrue(); assertThat(Duration.ofSeconds(5)).isEqualTo(properties.maxWaitForRestart()); }); } From eac9eb7879b66a5b341e6f4a015c0d0dbe07480b Mon Sep 17 00:00:00 2001 From: wind57 Date: Wed, 15 Apr 2026 12:24:54 +0300 Subject: [PATCH 2/5] first test on removal Signed-off-by: wind57 --- .../namespace-label-filtering.adoc | 23 +- ...loud-kubernetes-configuration-watcher.adoc | 14 +- docs/modules/ROOT/partials/_configprops.adoc | 3 +- ...ientEventBasedConfigMapChangeDetector.java | 3 +- .../KubernetesClientConfigUtilsTests.java | 5 +- .../reload/ConfigMapReloadWithFilterTest.java | 212 ------------------ .../reload/ConfigMapReloadWithLabelsTest.java | 3 +- ...tEventBasedSecretsChangeDetectorTests.java | 4 +- .../reload/SecretReloadWithFilterTest.java | 212 ------------------ .../reload/SecretReloadWithLabelsTest.java | 3 +- .../reload_it/EventReloadConfigMapTest.java | 6 +- .../reload_it/EventReloadSecretTest.java | 6 +- .../reload_it/PollingReloadConfigMapTest.java | 6 +- .../reload_it/PollingReloadSecretTest.java | 6 +- .../config/reload/ConfigReloadProperties.java | 9 +- ...ric8EventBasedConfigMapChangeDetector.java | 23 +- ...abric8EventBasedSecretsChangeDetector.java | 22 +- .../config/Fabric8ConfigUtilsTests.java | 8 +- .../reload_it/EventReloadConfigMapTest.java | 6 +- .../reload_it/EventReloadSecretTest.java | 6 +- .../PollingReloadConfigMapAndSecretTest.java | 6 +- .../reload_it/PollingReloadConfigMapTest.java | 6 +- .../reload_it/PollingReloadSecretTest.java | 6 +- .../labels/ConfigMapReloadWithFilterTest.java | 200 ----------------- .../labels/ConfigMapReloadWithLabelsTest.java | 3 +- .../labels/SecretReloadWithFilterTest.java | 202 ----------------- .../labels/SecretReloadWithLabelsTest.java | 3 +- .../src/main/resources/application-three.yaml | 3 +- .../src/main/resources/application-three.yaml | 3 +- 29 files changed, 61 insertions(+), 951 deletions(-) delete mode 100644 spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithFilterTest.java delete mode 100644 spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithFilterTest.java delete mode 100644 spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithFilterTest.java delete mode 100644 spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithFilterTest.java diff --git a/docs/modules/ROOT/pages/property-source-config/namespace-label-filtering.adoc b/docs/modules/ROOT/pages/property-source-config/namespace-label-filtering.adoc index 4123fff339..90f92fa89e 100644 --- a/docs/modules/ROOT/pages/property-source-config/namespace-label-filtering.adoc +++ b/docs/modules/ROOT/pages/property-source-config/namespace-label-filtering.adoc @@ -25,27 +25,7 @@ spring: Such a configuration will make the app watch changes only in the `my-namespace` namespace. Mind that this will watch _all_ configmaps/secrets (depending on which one you enable). If you want an even more fine-grained approach, -you can enable "label-filtering". First we need to enable such support via : `enable-reload-filtering: true` - -[source,yaml] ----- -spring: - application: - name: event-reload - cloud: - kubernetes: - reload: - enabled: true - strategy: shutdown - mode: event - namespaces: - - my-namespaces - monitoring-config-maps: true - enable-reload-filtering: true ----- - -What this will do, is watch configmaps/secrets that only have the `spring.cloud.kubernetes.config.informer.enabled: true` label. -In the next major release this support will be removed and replaced with: +you can set the labels that are supposed to be watched, via: [source,yaml] ---- @@ -80,7 +60,6 @@ spring: | `spring.cloud.kubernetes.reload.mode` | `Enum` | `event` | Specifies how to listen for changes in property sources (`event` or `polling`) | `spring.cloud.kubernetes.reload.period` | `Duration`| `15s` | The period for verifying changes when using the `polling` strategy | `spring.cloud.kubernetes.reload.namespaces` | `String[]`| | namespaces where we should watch for changes -| `spring.cloud.kubernetes.reload.enable-reload-filtering` | `String` | | enabled labeled filtering for reload functionality |=== Notes: diff --git a/docs/modules/ROOT/pages/spring-cloud-kubernetes-configuration-watcher.adoc b/docs/modules/ROOT/pages/spring-cloud-kubernetes-configuration-watcher.adoc index 84021ecd5e..35302b5077 100644 --- a/docs/modules/ROOT/pages/spring-cloud-kubernetes-configuration-watcher.adoc +++ b/docs/modules/ROOT/pages/spring-cloud-kubernetes-configuration-watcher.adoc @@ -43,26 +43,18 @@ Changes from configmaps/secrets will only trigger an event being fired from conf To put it simpler, if you change a configmap (or secret), that does _not_ have the label above, configuration watcher will skip firing an event for it (if you enabled debug logging, this will be visible in logs). -By default, configuration watcher will monitor all configmaps/secrets in the configured namespace(s). If you want to filter to watch only particular sources, you can do that by setting: +By default, configuration watcher will monitor all configmaps/secrets in the configured namespace(s). If you want to watch only particular sources, you can do that by choosing only sources with some labels: [source] ---- -SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE ----- - -This will tell watcher to only monitor sources that have a label: `spring.cloud.kubernetes.config.informer.enabled=true`. -This support will be dropped in the next major release and will be replaced with: - -[source] ----- -spring.cloud.kubernetes.reload.config-maps-labels +spring.cloud.kubernetes.reload.config-maps-labels[a]=b ---- and [source] ---- -spring.cloud.kubernetes.reload.secrets-labels +spring.cloud.kubernetes.reload.secrets-labels[c]=d ---- One more important configuration, especially for configmaps and secrets that are mounted as volumes (via `spring.config.import`) is: diff --git a/docs/modules/ROOT/partials/_configprops.adoc b/docs/modules/ROOT/partials/_configprops.adoc index 3a6a94e5ba..9c144fb8d4 100644 --- a/docs/modules/ROOT/partials/_configprops.adoc +++ b/docs/modules/ROOT/partials/_configprops.adoc @@ -101,7 +101,6 @@ |spring.cloud.kubernetes.loadbalancer.enabled | `+++true+++` | Load balancer enabled,default true. |spring.cloud.kubernetes.loadbalancer.mode | `+++pod+++` | {@link KubernetesLoadBalancerMode} setting load balancer server list with ip of pod or service name. default value is POD. |spring.cloud.kubernetes.loadbalancer.port-name | `+++http+++` | service port name. -|spring.cloud.kubernetes.reload.enable-reload-filtering | `+++false+++` | create an informer only for sources that have 'spring.cloud.kubernetes.config.informer.enabled=true' label. This property is only relevant for event based reloading. |spring.cloud.kubernetes.reload.enabled | `+++false+++` | Enables the Kubernetes configuration reload on change. |spring.cloud.kubernetes.reload.max-wait-for-restart | `+++2s+++` | Restart or Shutdown strategies are used, Spring Cloud Kubernetes waits a random amount of time before restarting. This is done in order to avoid having all instances of the same application restart at the same time. This property configures the maximum of amount of wait time from the moment the signal is received that a restart is needed until the moment the restart is actually triggered |spring.cloud.kubernetes.reload.mode | `+++EVENT+++` | Sets the detection mode for Kubernetes configuration reload. @@ -121,4 +120,4 @@ |spring.cloud.kubernetes.secrets.sources | | |spring.cloud.kubernetes.secrets.use-name-as-prefix | `+++false+++` | -|=== \ No newline at end of file +|=== diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java index 421a3d9c71..8272298953 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java @@ -137,7 +137,8 @@ void inform() { .labelSelector(labelSelector(configMapsLabels)) .buildCall(null), V1ConfigMap.class, V1ConfigMapList.class); - LOG.debug(() -> "configmap informer for namespace : " + namespace + " with labels : " + configMapsLabels); + LOG.debug( + () -> "configmap informer for namespace : " + namespace + " with labels : " + configMapsLabels); informer.addEventHandler(handler); informers.add(informer); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtilsTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtilsTests.java index 96a47a883b..d19ff769ff 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtilsTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtilsTests.java @@ -17,6 +17,7 @@ package org.springframework.cloud.kubernetes.client.config; import java.time.Duration; +import java.util.Map; import java.util.Set; import org.assertj.core.api.Assertions; @@ -33,9 +34,9 @@ class KubernetesClientConfigUtilsTests { @Test void testNamespacesFromProperties() { - ConfigReloadProperties properties = new ConfigReloadProperties(false, false, false, + ConfigReloadProperties properties = new ConfigReloadProperties(false, false, Map.of(), false, Map.of(), ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(15000), Set.of("non-default"), false, Duration.ofSeconds(2)); + Duration.ofMillis(15000), Set.of("non-default"), Duration.ofSeconds(2)); Set namespaces = KubernetesClientConfigUtils .namespaces(new KubernetesNamespaceProvider(new MockEnvironment()), properties, "configmap"); Assertions.assertThat(1).isEqualTo(namespaces.size()); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithFilterTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithFilterTest.java deleted file mode 100644 index 35b6ba3e80..0000000000 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithFilterTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2012-present 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.config.reload; - -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.client.VerificationException; -import com.github.tomakehurst.wiremock.client.WireMock; -import io.kubernetes.client.openapi.ApiClient; -import io.kubernetes.client.openapi.JSON; -import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.kubernetes.client.openapi.models.V1ConfigMap; -import io.kubernetes.client.openapi.models.V1ConfigMapList; -import io.kubernetes.client.openapi.models.V1ListMeta; -import io.kubernetes.client.openapi.models.V1ObjectMeta; -import io.kubernetes.client.util.ClientBuilder; -import io.kubernetes.client.util.Watch; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedStatic; -import org.mockito.Mockito; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.kubernetes.client.KubernetesClientUtils; -import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; -import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.integration.tests.commons.Awaitilities; -import org.springframework.mock.env.MockPropertySource; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static io.kubernetes.client.informer.EventType.ADDED; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.getApplicationNamespace; - -/** - * @author wind57 - */ -@SpringBootTest(properties = { "spring.main.allow-bean-definition-overriding=true" }) -@ExtendWith(OutputCaptureExtension.class) -class ConfigMapReloadWithFilterTest { - - private static WireMockServer wireMockServer; - - private static final String PATH = "^/api/v1/namespaces/default/configmaps.*"; - - private static CoreV1Api coreV1Api; - - private static final MockedStatic MOCK_STATIC = Mockito - .mockStatic(KubernetesClientUtils.class); - - @BeforeAll - static void setup() { - wireMockServer = new WireMockServer(options().dynamicPort()); - - wireMockServer.start(); - WireMock.configureFor("localhost", wireMockServer.port()); - - ApiClient client = new ClientBuilder().setBasePath("http://localhost:" + wireMockServer.port()).build(); - MOCK_STATIC.when(KubernetesClientUtils::createApiClientForInformerClient).thenReturn(client); - MOCK_STATIC.when(() -> getApplicationNamespace(Mockito.nullable(String.class), anyString(), any())) - .thenReturn("default"); - coreV1Api = new CoreV1Api(client); - } - - @AfterAll - static void after() { - MOCK_STATIC.close(); - wireMockServer.stop(); - } - - @Test - void test() { - - V1ConfigMap myConfigMap = new V1ConfigMap() - .metadata(new V1ObjectMeta().namespace("default") - .name("my-config-map") - .labels(Map.of("spring.cloud.kubernetes.config.informer.enabled", "true"))) - .data(Map.of("shape", "round")); - - V1ConfigMapList configMapList = new V1ConfigMapList().metadata(new V1ListMeta().resourceVersion("1")) - .items(List.of(myConfigMap)); - - // 1. first call to informer - stubFor(get(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withQueryParam("resourceVersion", equalTo("0")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(JSON.serialize(configMapList)))); - - // 2. second call to informer - V1ConfigMap second = new V1ConfigMap() - .metadata(new V1ObjectMeta().namespace("default") - .name("second") - .labels(Map.of("spring.cloud.kubernetes.config.informer.enabled", "true")) - .resourceVersion("2")) - .data(Map.of("a", "b")); - Watch.Response watchResponse = new Watch.Response<>(ADDED.name(), second); - - stubFor(get(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withQueryParam("resourceVersion", equalTo("1")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(JSON.serialize(watchResponse)))); - - // 3. all future calls to informer ( any call with resourceVersion >= 2 ) - stubFor(get(urlMatching(PATH)).atPriority(10) - .withQueryParam("watch", equalTo("true")) - .withQueryParam("resourceVersion", WireMock.matching("[2-9][0-9]*")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(""))); - - // update strategy - ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", () -> { - - }); - - // mock environment - KubernetesMockEnvironment environment = new KubernetesMockEnvironment( - mock(KubernetesClientConfigMapPropertySource.class)); - - // change locator - KubernetesClientConfigMapPropertySourceLocator locator = mock( - KubernetesClientConfigMapPropertySourceLocator.class); - when(locator.locate(environment)).thenAnswer(x -> new MockPropertySource()); - - // namespace provider - KubernetesNamespaceProvider namespaceProvider = mock(KubernetesNamespaceProvider.class); - when(namespaceProvider.getNamespace()).thenReturn("default"); - - // properties - boolean enableReloadFiltering = true; - boolean monitorConfigMaps = true; - boolean monitorSecrets = false; - Map configMapsLabels = Map.of(); - Map secretsLabels = Map.of(); - ConfigReloadProperties properties = new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, - monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), - enableReloadFiltering, Duration.ofSeconds(2)); - - // change detector - KubernetesClientEventBasedConfigMapChangeDetector changeDetector = new KubernetesClientEventBasedConfigMapChangeDetector( - coreV1Api, environment, properties, strategy, locator, namespaceProvider); - - changeDetector.inform(); - - // assert that both requests from informer are label based - Awaitilities.awaitUntil(10, 1000, () -> { - try { - - WireMock.verify(WireMock.moreThanOrExactly(1), - getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withQueryParam("labelSelector", - equalTo("spring.cloud.kubernetes.config.informer.enabled=true"))); - - WireMock.verify(WireMock.moreThanOrExactly(1), - getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withQueryParam("labelSelector", - equalTo("spring.cloud.kubernetes.config.informer.enabled=true"))); - - WireMock.verify(0, getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withoutQueryParam("labelSelector")); - - WireMock.verify(0, getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withoutQueryParam("labelSelector")); - - return true; - } - catch (VerificationException e) { - return false; - } - }); - - changeDetector.shutdown(); - - assertThat(wireMockServer.findAllUnmatchedRequests()).isEmpty(); - - } - -} diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithLabelsTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithLabelsTest.java index bd05a81b72..45e3c6c319 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithLabelsTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/ConfigMapReloadWithLabelsTest.java @@ -159,7 +159,6 @@ void test() { when(namespaceProvider.getNamespace()).thenReturn("default"); // properties - boolean enableReloadFiltering = false; boolean monitorConfigMaps = true; boolean monitorSecrets = false; Map configMapsLabels = Map.of("only-shape", "round"); @@ -167,7 +166,7 @@ void test() { ConfigReloadProperties properties = new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), - enableReloadFiltering, Duration.ofSeconds(2)); + Duration.ofSeconds(2)); // change detector KubernetesClientEventBasedConfigMapChangeDetector changeDetector = new KubernetesClientEventBasedConfigMapChangeDetector( diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetectorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetectorTests.java index e8bbd8fa44..1d958ff9a8 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetectorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetectorTests.java @@ -280,9 +280,9 @@ private void changeDetectorAssert() { .thenAnswer(ignoreMe -> new MockPropertySource().withProperty("db-password", "p455w0rd2")); // properties - ConfigReloadProperties properties = new ConfigReloadProperties(false, false, true, + ConfigReloadProperties properties = new ConfigReloadProperties(false, false, Map.of(), true, Map.of(), ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(15000), Set.of(), false, Duration.ofSeconds(2)); + Duration.ofMillis(15000), Set.of(), Duration.ofSeconds(2)); // namespace provider KubernetesNamespaceProvider kubernetesNamespaceProvider = mock(KubernetesNamespaceProvider.class); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithFilterTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithFilterTest.java deleted file mode 100644 index 2bb9f64bf2..0000000000 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithFilterTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2012-present 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.config.reload; - -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.client.VerificationException; -import com.github.tomakehurst.wiremock.client.WireMock; -import io.kubernetes.client.openapi.ApiClient; -import io.kubernetes.client.openapi.JSON; -import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.kubernetes.client.openapi.models.V1ListMeta; -import io.kubernetes.client.openapi.models.V1ObjectMeta; -import io.kubernetes.client.openapi.models.V1Secret; -import io.kubernetes.client.openapi.models.V1SecretList; -import io.kubernetes.client.util.ClientBuilder; -import io.kubernetes.client.util.Watch; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedStatic; -import org.mockito.Mockito; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.kubernetes.client.KubernetesClientUtils; -import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource; -import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator; -import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.integration.tests.commons.Awaitilities; -import org.springframework.mock.env.MockPropertySource; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static io.kubernetes.client.informer.EventType.ADDED; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.getApplicationNamespace; - -/** - * @author wind57 - */ -@SpringBootTest(properties = { "spring.main.allow-bean-definition-overriding=true" }) -@ExtendWith(OutputCaptureExtension.class) -class SecretReloadWithFilterTest { - - private static WireMockServer wireMockServer; - - private static final String PATH = "^/api/v1/namespaces/default/secrets.*"; - - private static CoreV1Api coreV1Api; - - private static final MockedStatic MOCK_STATIC = Mockito - .mockStatic(KubernetesClientUtils.class); - - @BeforeAll - static void setup() { - wireMockServer = new WireMockServer(options().dynamicPort()); - - wireMockServer.start(); - WireMock.configureFor("localhost", wireMockServer.port()); - - ApiClient client = new ClientBuilder().setBasePath("http://localhost:" + wireMockServer.port()).build(); - MOCK_STATIC.when(KubernetesClientUtils::createApiClientForInformerClient).thenReturn(client); - MOCK_STATIC.when(() -> getApplicationNamespace(Mockito.nullable(String.class), anyString(), any())) - .thenReturn("default"); - coreV1Api = new CoreV1Api(client); - } - - @AfterAll - static void after() { - MOCK_STATIC.close(); - wireMockServer.stop(); - } - - @Test - void test() { - - V1Secret mySecret = new V1Secret() - .metadata(new V1ObjectMeta().namespace("default") - .name("my-secret") - .labels(Map.of("spring.cloud.kubernetes.config.informer.enabled", "true"))) - .data(Map.of("shape", "round".getBytes())); - - V1SecretList secretList = new V1SecretList().metadata(new V1ListMeta().resourceVersion("1")) - .items(List.of(mySecret)); - - // 1. first call to informer - stubFor(get(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withQueryParam("resourceVersion", equalTo("0")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(JSON.serialize(secretList)))); - - // 2. second call to informer - V1Secret second = new V1Secret() - .metadata(new V1ObjectMeta().namespace("default") - .name("second") - .labels(Map.of("spring.cloud.kubernetes.config.informer.enabled", "true")) - .resourceVersion("2")) - .data(Map.of("a", "b".getBytes())); - Watch.Response watchResponse = new Watch.Response<>(ADDED.name(), second); - - stubFor(get(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withQueryParam("resourceVersion", equalTo("1")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(JSON.serialize(watchResponse)))); - - // 3. all future calls to informer ( any call with resourceVersion >= 2 ) - stubFor(get(urlMatching(PATH)).atPriority(10) - .withQueryParam("watch", equalTo("true")) - .withQueryParam("resourceVersion", WireMock.matching("[2-9][0-9]*")) - .withQueryParam("labelSelector", equalTo("spring.cloud.kubernetes.config.informer.enabled=true")) - .willReturn(aResponse().withStatus(200).withBody(""))); - - // update strategy - ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", () -> { - - }); - - // mock environment - KubernetesMockEnvironment environment = new KubernetesMockEnvironment( - mock(KubernetesClientSecretsPropertySource.class)); - - // change locator - KubernetesClientSecretsPropertySourceLocator locator = mock(KubernetesClientSecretsPropertySourceLocator.class); - when(locator.locate(environment)).thenAnswer(x -> new MockPropertySource()); - - // namespace provider - KubernetesNamespaceProvider namespaceProvider = mock(KubernetesNamespaceProvider.class); - when(namespaceProvider.getNamespace()).thenReturn("default"); - - // properties - boolean enableReloadFiltering = true; - boolean monitorConfigMaps = false; - boolean monitorSecrets = true; - Map configMapsLabels = Map.of(); - Map secretsLabels = Map.of(); - ConfigReloadProperties properties = new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, - monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), - enableReloadFiltering, Duration.ofSeconds(2)); - - // change detector - KubernetesClientEventBasedSecretsChangeDetector changeDetector = new KubernetesClientEventBasedSecretsChangeDetector( - coreV1Api, environment, properties, strategy, locator, namespaceProvider); - - changeDetector.inform(); - - // assert that both requests from informer are label based - Awaitilities.awaitUntil(10, 1000, () -> { - try { - - WireMock.verify(WireMock.moreThanOrExactly(1), - getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withQueryParam("labelSelector", - equalTo("spring.cloud.kubernetes.config.informer.enabled=true"))); - - WireMock.verify(WireMock.moreThanOrExactly(1), - getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withQueryParam("labelSelector", - equalTo("spring.cloud.kubernetes.config.informer.enabled=true"))); - - WireMock.verify(0, getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("false")) - .withoutQueryParam("labelSelector")); - - WireMock.verify(0, getRequestedFor(urlMatching(PATH)).withQueryParam("watch", equalTo("true")) - .withoutQueryParam("labelSelector")); - - return true; - - } - catch (VerificationException e) { - return false; - } - }); - - changeDetector.shutdown(); - - assertThat(wireMockServer.findAllUnmatchedRequests()).isEmpty(); - - } - -} diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithLabelsTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithLabelsTest.java index d5149fc153..b1876c199a 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithLabelsTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/SecretReloadWithLabelsTest.java @@ -157,7 +157,6 @@ void test() { when(namespaceProvider.getNamespace()).thenReturn("default"); // properties - boolean enableReloadFiltering = false; boolean monitorConfigMaps = false; boolean monitorSecrets = true; Map configMapsLabels = Map.of(); @@ -165,7 +164,7 @@ void test() { ConfigReloadProperties properties = new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of(), - enableReloadFiltering, Duration.ofSeconds(2)); + Duration.ofSeconds(2)); // change detector KubernetesClientEventBasedSecretsChangeDetector changeDetector = new KubernetesClientEventBasedSecretsChangeDetector( diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java index eb1f25cb0a..c4c3b2e666 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java @@ -197,9 +197,9 @@ VisibleKubernetesClientEventBasedConfigMapChangeDetector kubernetesClientEventBa @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, false, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("spring-k8s"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), false, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("spring-k8s"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java index a4b838206a..137eb32fe3 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java @@ -202,9 +202,9 @@ VisibleKubernetesClientEventBasedSecretsChangeDetector kubernetesClientEventBase @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, false, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("spring-k8s"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), false, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("spring-k8s"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java index 610bb42a36..58f3311a64 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java @@ -173,9 +173,9 @@ PollingConfigMapChangeDetector pollingConfigMapChangeDetector(AbstractEnvironmen @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, false, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("non-default"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), false, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("non-default"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java index d961f02269..9b2401f61f 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java @@ -175,9 +175,9 @@ PollingSecretsChangeDetector pollingSecretsChangeDetector(AbstractEnvironment en @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, false, true, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("non-default"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, false, Map.of(), true, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("non-default"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java index 992218fe7c..c10bcb5079 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadProperties.java @@ -45,12 +45,11 @@ */ @ConfigurationProperties(prefix = "spring.cloud.kubernetes.reload") public record ConfigReloadProperties(boolean enabled, @DefaultValue("true") boolean monitoringConfigMaps, - @DefaultValue Map configMapsLabels, - boolean monitoringSecrets, @DefaultValue Map secretsLabels, - @DefaultValue("REFRESH") ReloadStrategy strategy, + @DefaultValue Map configMapsLabels, boolean monitoringSecrets, + @DefaultValue Map secretsLabels, @DefaultValue("REFRESH") ReloadStrategy strategy, @DefaultValue("EVENT") ReloadDetectionMode mode, @DefaultValue("15000ms") Duration period, - @DefaultValue Set namespaces, - @DefaultValue("2s") Duration maxWaitForRestart) { + @DefaultValue Set namespaces, @DefaultValue("2s") Duration maxWaitForRestart) { + /** * default instance. */ diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java index 7cd2da0bff..682a85b63c 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java @@ -66,8 +66,6 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang private final ConfigurableEnvironment environment; - private final boolean enableReloadFiltering; - private final boolean monitorConfigMaps; private final Map configMapsLabels; @@ -80,7 +78,6 @@ public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, this.environment = environment; this.kubernetesClient = kubernetesClient; this.fabric8ConfigMapPropertySourceLocator = fabric8ConfigMapPropertySourceLocator; - this.enableReloadFiltering = properties.enableReloadFiltering(); this.monitorConfigMaps = properties.monitoringConfigMaps(); this.configMapsLabels = properties.configMapsLabels(); namespaces = namespaces(kubernetesClient, namespaceProvider, properties, "configmap"); @@ -92,25 +89,11 @@ private void inform() { LOG.info("Kubernetes event-based configMap change detector activated"); - Map labelSelector; - - if (enableReloadFiltering) { - LOG.warn(() -> "enable reload filtering is deprecated and will be removed in the next major release"); - LOG.warn(() -> "use spring.cloud.kubernetes.reload.config-maps-labels instead"); - if (!configMapsLabels.isEmpty()) { - LOG.warn(() -> "spring.cloud.kubernetes.reload.config-maps-labels is not empty, but " - + "spring.cloud.kubernetes.reload.enable-reload-filtering is enabled and will override the former"); - } - labelSelector = Map.of(ConfigReloadProperties.RELOAD_LABEL_FILTER, "true"); - } - else { - labelSelector = configMapsLabels; - } - namespaces.forEach(namespace -> { SharedIndexInformer informer; - informer = kubernetesClient.configMaps().inNamespace(namespace).withLabels(labelSelector).inform(); - LOG.debug("added configmap informer for namespace : " + namespace + " with labels : " + labelSelector); + informer = kubernetesClient.configMaps().inNamespace(namespace).withLabels(configMapsLabels).inform(); + LOG.debug( + "added configmap informer for namespace : " + namespace + " with labels : " + configMapsLabels); informer.addEventHandler(new ConfigMapInformerAwareEventHandler(informer)); informers.add(informer); diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java index 95e893118d..dd92996240 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java @@ -66,8 +66,6 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD private final ConfigurableEnvironment environment; - private final boolean enableReloadFiltering; - private final boolean monitorSecrets; private final Map secretsLabels; @@ -80,7 +78,6 @@ public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, C this.environment = environment; this.kubernetesClient = kubernetesClient; this.fabric8SecretsPropertySourceLocator = fabric8SecretsPropertySourceLocator; - this.enableReloadFiltering = properties.enableReloadFiltering(); this.monitorSecrets = properties.monitoringSecrets(); secretsLabels = properties.secretsLabels(); namespaces = namespaces(kubernetesClient, namespaceProvider, properties, "secrets"); @@ -100,25 +97,10 @@ private void inform() { LOG.info("Kubernetes event-based secrets change detector activated"); - Map labelSelector; - - if (enableReloadFiltering) { - LOG.warn(() -> "enable reload filtering is deprecated and will be removed in the next major release"); - LOG.warn(() -> "use spring.cloud.kubernetes.secrets-labels instead"); - if (!secretsLabels.isEmpty()) { - LOG.warn(() -> "spring.cloud.kubernetes.reload.secrets-labels is not empty, but " - + "spring.cloud.kubernetes.reload.enable-reload-filtering is enabled and will override the former"); - } - labelSelector = Map.of(ConfigReloadProperties.RELOAD_LABEL_FILTER, "true"); - } - else { - labelSelector = secretsLabels; - } - namespaces.forEach(namespace -> { SharedIndexInformer informer; - informer = kubernetesClient.secrets().inNamespace(namespace).withLabels(labelSelector).inform(); - LOG.debug("added secret informer for namespace : " + namespace + " with labels : " + labelSelector); + informer = kubernetesClient.secrets().inNamespace(namespace).withLabels(secretsLabels).inform(); + LOG.debug("added secret informer for namespace : " + namespace + " with labels : " + secretsLabels); informer.addEventHandler(new SecretInformerAwareEventHandler(informer)); informers.add(informer); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigUtilsTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigUtilsTests.java index bd0c09fd39..592a68f936 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigUtilsTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigUtilsTests.java @@ -17,6 +17,7 @@ package org.springframework.cloud.kubernetes.fabric8.config; import java.time.Duration; +import java.util.Map; import java.util.Set; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; @@ -35,9 +36,10 @@ class Fabric8ConfigUtilsTests { @Test void testNamespacesFromProperties() { - ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(false, true, false, - ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(15000), Set.of("non-default"), false, Duration.ofSeconds(2)); + ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(false, true, Map.of(), false, + Map.of(), ConfigReloadProperties.ReloadStrategy.REFRESH, + ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(15000), Set.of("non-default"), + Duration.ofSeconds(2)); Set namespaces = Fabric8ConfigUtils.namespaces(null, new KubernetesNamespaceProvider(new MockEnvironment()), configReloadProperties, "configmap"); Assertions.assertThat(namespaces.size()).isEqualTo(1); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java index 0279f5e8b2..6c03398cdb 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java @@ -158,9 +158,9 @@ Fabric8EventBasedConfigMapChangeDetector fabric8EventBasedSecretsChangeDetector( @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, false, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(2000), Set.of(NAMESPACE), false, - Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), false, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, + Duration.ofMillis(2000), Set.of(NAMESPACE), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java index 35b77c24ee..8743525e33 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java @@ -163,9 +163,9 @@ Fabric8EventBasedSecretsChangeDetector fabric8EventBasedSecretsChangeDetector(Ab @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, true, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.EVENT, Duration.ofMillis(2000), Set.of(NAMESPACE), false, - Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), true, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, + Duration.ofMillis(2000), Set.of(NAMESPACE), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapAndSecretTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapAndSecretTest.java index 71b53398f7..ef6d628fbb 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapAndSecretTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapAndSecretTest.java @@ -177,9 +177,9 @@ PollingConfigMapChangeDetector pollingConfigMapChangeDetector(AbstractEnvironmen @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, true, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(200), Set.of(NAMESPACE), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), true, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(200), Set.of(NAMESPACE), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java index a381e1e810..57b9d8d672 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java @@ -139,9 +139,9 @@ PollingConfigMapChangeDetector pollingConfigMapChangeDetector(AbstractEnvironmen @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, false, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("non-default"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), false, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("non-default"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java index c69754c1df..226c026ef8 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java @@ -145,9 +145,9 @@ PollingSecretsChangeDetector pollingSecretsChangeDetector(AbstractEnvironment en @Bean @Primary ConfigReloadProperties configReloadProperties() { - return new ConfigReloadProperties(true, true, true, ConfigReloadProperties.ReloadStrategy.REFRESH, - ConfigReloadProperties.ReloadDetectionMode.POLLING, Duration.ofMillis(2000), Set.of("non-default"), - false, Duration.ofSeconds(2)); + return new ConfigReloadProperties(true, true, Map.of(), true, Map.of(), + ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.POLLING, + Duration.ofMillis(2000), Set.of("non-default"), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithFilterTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithFilterTest.java deleted file mode 100644 index 521013d757..0000000000 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithFilterTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2012-present 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.fabric8.config.reload_it.labels; - -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.ConfigMapBuilder; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties; -import org.springframework.cloud.kubernetes.commons.config.ReadType; -import org.springframework.cloud.kubernetes.commons.config.RetryProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.VisibleFabric8ConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedConfigMapChangeDetector; -import org.springframework.cloud.kubernetes.integration.tests.commons.Awaitilities; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; -import org.springframework.test.context.ContextConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author wind57 - */ -@SpringBootTest(properties = { "spring.main.allow-bean-definition-overriding=true" }, - classes = { ConfigMapReloadWithFilterTest.TestConfig.class }) -@ContextConfiguration(initializers = ConfigMapReloadWithFilterTest.Initializer.class) -@EnableKubernetesMockClient(crud = true, https = false) -class ConfigMapReloadWithFilterTest { - - private static KubernetesClient kubernetesClient; - - private static final boolean FAIL_FAST = false; - - private static final String CONFIG_MAP_NAME = "mine"; - - private static final String NAMESPACE = "spring-k8s"; - - private static final AtomicBoolean STRATEGY_CALLED = new AtomicBoolean(false); - - /** - *
-	 *     - we enable reload filtering, via 'spring.cloud.kubernetes.reload.enable-reload-filtering=true'
-	 *       ( this is done in ConfigReloadProperties )
-	 *     - as such, only configmaps that have 'spring.cloud.kubernetes.config.informer.enabled=true'
-	 *       label are being watched. This is what the informer is created with.
-	 * 
- */ - @Test - void test() throws InterruptedException { - ConfigMap configMapOne = configMap(CONFIG_MAP_NAME, Map.of("a", "b"), - Map.of("spring.cloud.kubernetes.config.informer.enabled", "true")); - - kubernetesClient.configMaps().inNamespace(NAMESPACE).resource(configMapOne).create(); - Awaitilities.awaitUntil(10, 1000, STRATEGY_CALLED::get); - kubernetesClient.configMaps().inAnyNamespace().delete(); - Awaitilities.awaitUntil(10, 1000, - () -> kubernetesClient.configMaps().inNamespace(NAMESPACE).withName(CONFIG_MAP_NAME).get() == null); - - // reset the strategy - STRATEGY_CALLED.set(false); - - // create a configMap without label, the informer does not pick it up - configMapOne = configMap(CONFIG_MAP_NAME, Map.of("c", "d"), Map.of()); - kubernetesClient.configMaps().inNamespace(NAMESPACE).resource(configMapOne).create(); - - // wait a bit so that the informer potentially picks it up - Thread.sleep(3_000); - - assertThat(STRATEGY_CALLED.get()).isFalse(); - - } - - private static ConfigMap configMap(String name, Map data, Map labels) { - return new ConfigMapBuilder().withNewMetadata() - .withResourceVersion("1") - .withLabels(labels) - .withName(name) - .endMetadata() - .withData(data) - .build(); - } - - @TestConfiguration - static class TestConfig { - - @Bean - @Primary - Fabric8EventBasedConfigMapChangeDetector fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, - ConfigReloadProperties configReloadProperties, ConfigurationUpdateStrategy configurationUpdateStrategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, - KubernetesNamespaceProvider namespaceProvider) { - return new Fabric8EventBasedConfigMapChangeDetector(environment, configReloadProperties, kubernetesClient, - configurationUpdateStrategy, fabric8ConfigMapPropertySourceLocator, namespaceProvider); - } - - @Bean - @Primary - ConfigReloadProperties configReloadProperties() { - - boolean monitorConfigMaps = true; - boolean monitorSecrets = false; - boolean enableReloadFiltering = true; - Map configMapsLabels = Map.of(); - Map secretsLabels = Map.of(); - - return new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, - ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(2000), Set.of(NAMESPACE), enableReloadFiltering, Duration.ofSeconds(2)); - } - - @Bean - @Primary - ConfigMapConfigProperties configMapConfigProperties() { - return new ConfigMapConfigProperties(true, List.of(), Map.of(), CONFIG_MAP_NAME, NAMESPACE, false, true, - FAIL_FAST, RetryProperties.DEFAULT, ReadType.SINGLE); - } - - @Bean - @Primary - KubernetesNamespaceProvider namespaceProvider(AbstractEnvironment environment) { - return new KubernetesNamespaceProvider(environment); - } - - // this is called by reloadProperties() and we simulated that - // informer correctly caught the update for the configmap. - @Bean - @Primary - ConfigurationUpdateStrategy configurationUpdateStrategy() { - return new ConfigurationUpdateStrategy("to-console", () -> STRATEGY_CALLED.set(true)); - } - - @Bean - @Primary - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator( - ConfigMapConfigProperties configMapConfigProperties, KubernetesNamespaceProvider namespaceProvider) { - return new VisibleFabric8ConfigMapPropertySourceLocator(kubernetesClient, configMapConfigProperties, - namespaceProvider); - } - - } - - /** - * we need a bean of type 'Fabric8ConfigMapPropertySourceLocator' in the context - * ('VisibleFabric8ConfigMapPropertySourceLocator'), otherwise the reload will not - * work. This one is called before the context is refreshed. - */ - static class Initializer implements ApplicationContextInitializer { - - @Override - public void initialize(ConfigurableApplicationContext context) { - ConfigurableEnvironment environment = context.getEnvironment(); - - ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), - Map.of(), CONFIG_MAP_NAME, NAMESPACE, false, true, true, RetryProperties.DEFAULT, ReadType.SINGLE); - - KubernetesNamespaceProvider namespaceProvider = new KubernetesNamespaceProvider(environment); - - PropertySource propertySource = new VisibleFabric8ConfigMapPropertySourceLocator(kubernetesClient, - configMapConfigProperties, namespaceProvider) - .locate(environment); - - environment.getPropertySources().addFirst(propertySource); - } - - } - -} diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithLabelsTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithLabelsTest.java index 02e9153536..cc4579cf6d 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithLabelsTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/ConfigMapReloadWithLabelsTest.java @@ -128,13 +128,12 @@ ConfigReloadProperties configReloadProperties() { boolean monitorConfigMaps = true; boolean monitorSecrets = false; - boolean enableReloadFiltering = false; Map configMapsLabels = Map.of("only-shape", "round"); Map secretsLabels = Map.of(); return new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(2000), Set.of(NAMESPACE), enableReloadFiltering, Duration.ofSeconds(2)); + Duration.ofMillis(2000), Set.of(NAMESPACE), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithFilterTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithFilterTest.java deleted file mode 100644 index c6adcb4d65..0000000000 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithFilterTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2012-present 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.fabric8.config.reload_it.labels; - -import java.time.Duration; -import java.util.Base64; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; - -import io.fabric8.kubernetes.api.model.Secret; -import io.fabric8.kubernetes.api.model.SecretBuilder; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.ReadType; -import org.springframework.cloud.kubernetes.commons.config.RetryProperties; -import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.VisibleFabric8SecretsPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedSecretsChangeDetector; -import org.springframework.cloud.kubernetes.integration.tests.commons.Awaitilities; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; -import org.springframework.test.context.ContextConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author wind57 - */ -@SpringBootTest(properties = { "spring.main.allow-bean-definition-overriding=true" }, - classes = { SecretReloadWithFilterTest.TestConfig.class }) -@ContextConfiguration(initializers = SecretReloadWithFilterTest.Initializer.class) -@EnableKubernetesMockClient(crud = true, https = false) -class SecretReloadWithFilterTest { - - private static KubernetesClient kubernetesClient; - - private static final boolean FAIL_FAST = false; - - private static final String SECRET_NAME = "mine"; - - private static final String NAMESPACE = "spring-k8s"; - - private static final AtomicBoolean STRATEGY_CALLED = new AtomicBoolean(false); - - /** - *
-	 *     - we enable reload filtering, via 'spring.cloud.kubernetes.reload.enable-reload-filtering=true'
-	 *       ( this is done in ConfigReloadProperties )
-	 *     - as such, only secrets that have 'spring.cloud.kubernetes.config.informer.enabled=true'
-	 *       label are being watched. This is what the informer is created with.
-	 * 
- */ - @Test - void test() throws InterruptedException { - Secret secret = secret(SECRET_NAME, Map.of("a", "b"), - Map.of("spring.cloud.kubernetes.config.informer.enabled", "true")); - - kubernetesClient.secrets().inNamespace(NAMESPACE).resource(secret).create(); - Awaitilities.awaitUntil(10, 1000, STRATEGY_CALLED::get); - kubernetesClient.secrets().inAnyNamespace().delete(); - Awaitilities.awaitUntil(10, 1000, - () -> kubernetesClient.secrets().inNamespace(NAMESPACE).withName(SECRET_NAME).get() == null); - - // reset the strategy - STRATEGY_CALLED.set(false); - - // create a secret without label, the informer does not pick it up - secret = secret(SECRET_NAME, Map.of("c", "d"), Map.of()); - kubernetesClient.secrets().inNamespace(NAMESPACE).resource(secret).create(); - - // wait a bit so that the informer potentially picks it up - Thread.sleep(3_000); - - assertThat(STRATEGY_CALLED.get()).isFalse(); - - } - - private static Secret secret(String name, Map data, Map labels) { - Map encoded = data.entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, - e -> new String(Base64.getEncoder().encode(e.getValue().getBytes())))); - return new SecretBuilder().withNewMetadata() - .withLabels(labels) - .withName(name) - .endMetadata() - .withData(encoded) - .build(); - } - - @TestConfiguration - static class TestConfig { - - @Bean - @Primary - Fabric8EventBasedSecretsChangeDetector fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, - ConfigReloadProperties configReloadProperties, ConfigurationUpdateStrategy configurationUpdateStrategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, - KubernetesNamespaceProvider namespaceProvider) { - return new Fabric8EventBasedSecretsChangeDetector(environment, configReloadProperties, kubernetesClient, - configurationUpdateStrategy, fabric8SecretsPropertySourceLocator, namespaceProvider); - } - - @Bean - @Primary - ConfigReloadProperties configReloadProperties() { - - boolean monitorConfigMaps = false; - boolean monitorSecrets = true; - boolean enableReloadFiltering = true; - Map configMapsLabels = Map.of(); - Map secretsLabels = Map.of(); - - return new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, - ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(2000), Set.of(NAMESPACE), enableReloadFiltering, Duration.ofSeconds(2)); - } - - @Bean - @Primary - SecretsConfigProperties secretsConfigProperties() { - return new SecretsConfigProperties(true, List.of(), Map.of(), SECRET_NAME, NAMESPACE, false, true, - FAIL_FAST, RetryProperties.DEFAULT, ReadType.SINGLE); - } - - @Bean - @Primary - KubernetesNamespaceProvider namespaceProvider(AbstractEnvironment environment) { - return new KubernetesNamespaceProvider(environment); - } - - @Bean - @Primary - ConfigurationUpdateStrategy configurationUpdateStrategy() { - return new ConfigurationUpdateStrategy("to-console", () -> STRATEGY_CALLED.set(true)); - } - - @Bean - @Primary - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator( - SecretsConfigProperties secretsConfigProperties, KubernetesNamespaceProvider namespaceProvider) { - return new VisibleFabric8SecretsPropertySourceLocator(kubernetesClient, secretsConfigProperties, - namespaceProvider); - } - - } - - /** - * This one is called before the context is refreshed. - */ - static class Initializer implements ApplicationContextInitializer { - - @Override - public void initialize(ConfigurableApplicationContext context) { - ConfigurableEnvironment environment = context.getEnvironment(); - - // simulate that environment already has a Fabric8SecretsPropertySource, - // otherwise we can't properly test reload functionality - SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, List.of(), Map.of(), - SECRET_NAME, NAMESPACE, false, true, true, RetryProperties.DEFAULT, ReadType.BATCH); - KubernetesNamespaceProvider namespaceProvider = new KubernetesNamespaceProvider(environment); - - PropertySource propertySource = new VisibleFabric8SecretsPropertySourceLocator(kubernetesClient, - secretsConfigProperties, namespaceProvider) - .locate(environment); - - environment.getPropertySources().addFirst(propertySource); - } - - } - -} diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithLabelsTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithLabelsTest.java index adb15ec121..21ef184b25 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithLabelsTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/labels/SecretReloadWithLabelsTest.java @@ -133,13 +133,12 @@ ConfigReloadProperties configReloadProperties() { boolean monitorConfigMaps = false; boolean monitorSecrets = true; - boolean enableReloadFiltering = false; Map configMapsLabels = Map.of(); Map secretsLabels = Map.of("only-shape", "round"); return new ConfigReloadProperties(true, monitorConfigMaps, configMapsLabels, monitorSecrets, secretsLabels, ConfigReloadProperties.ReloadStrategy.REFRESH, ConfigReloadProperties.ReloadDetectionMode.EVENT, - Duration.ofMillis(2000), Set.of(NAMESPACE), enableReloadFiltering, Duration.ofSeconds(2)); + Duration.ofMillis(2000), Set.of(NAMESPACE), Duration.ofSeconds(2)); } @Bean diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-reload/src/main/resources/application-three.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-reload/src/main/resources/application-three.yaml index 72f6a44c1e..e94a919948 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-reload/src/main/resources/application-three.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-reload/src/main/resources/application-three.yaml @@ -10,4 +10,5 @@ spring: namespaces: - right monitoring-config-maps: true - enable-reload-filtering: true + config-maps-labels: + spring.cloud.kubernetes.config.informer.enabled : "true" diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-three.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-three.yaml index 72f6a44c1e..e94a919948 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-three.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-three.yaml @@ -10,4 +10,5 @@ spring: namespaces: - right monitoring-config-maps: true - enable-reload-filtering: true + config-maps-labels: + spring.cloud.kubernetes.config.informer.enabled : "true" From 5cb5fd1aa75d0ea7cc996cba5c048e4ec4042ae2 Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 17 Apr 2026 16:58:56 +0300 Subject: [PATCH 3/5] fix test Signed-off-by: wind57 --- .../client/reload/it/K8sClientConfigMapEventTriggeredIT.java | 4 ++-- .../reload/it/K8sClientConfigMapLabelEventTriggeredIT.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapEventTriggeredIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapEventTriggeredIT.java index b44cc34cb8..4d8a1a8673 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapEventTriggeredIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapEventTriggeredIT.java @@ -99,8 +99,8 @@ static void afterAllLocal() { @Test void test(CapturedOutput output) { - assertReloadLogStatements("added configmap informer for namespace : right with labels : {}", - "added secret informer for namespace", output); + assertReloadLogStatements("configmap informer for namespace : right with labels : {}", + "secret informer for namespace", output); Assertions.assertThat(rightProperties.getValue()).isEqualTo("right-initial"); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapLabelEventTriggeredIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapLabelEventTriggeredIT.java index 1414b5c886..2bdef4662f 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapLabelEventTriggeredIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientConfigMapLabelEventTriggeredIT.java @@ -106,9 +106,9 @@ static void afterAllLocal() { void test(CapturedOutput output) { assertReloadLogStatements( - "added configmap informer for namespace : " + "configmap informer for namespace : " + "right with labels : {spring.cloud.kubernetes.config.informer.enabled=true}", - "added secret informer for namespace", output); + "secret informer for namespace", output); // read the initial value from the right-configmap Assertions.assertThat(rightProperties.getValue()).isEqualTo("right-initial"); From d229922af5f54126bf1b3caa47780f57f65943ab Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 22 May 2026 20:30:54 +0300 Subject: [PATCH 4/5] trigger Signed-off-by: wind57 From da81f9359a79d7247777001fd0f5de459e6f6fbb Mon Sep 17 00:00:00 2001 From: wind57 Date: Sat, 23 May 2026 09:47:03 +0300 Subject: [PATCH 5/5] trigger Signed-off-by: wind57