From bf7b971398eb4d9d3fdb9b8f30eb37cf5644554e Mon Sep 17 00:00:00 2001 From: wind57 Date: Sat, 11 Jun 2022 22:26:32 +0300 Subject: [PATCH 01/30] first --- .../cloud/kubernetes/commons/config/Constants.java | 4 ++-- .../config/reload/condition/EventReloadDetectionMode.java | 5 +++-- .../config/reload/condition/PollingReloadDetectionMode.java | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/Constants.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/Constants.java index 84c4b513ba..e8be954fb8 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/Constants.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/Constants.java @@ -59,9 +59,9 @@ public final class Constants { public static final String APPLICATION_PROPERTIES = "application.properties"; /** - * prefix of the configMap. + * reload mode spring property. */ - public static final String PREFIX = "configmap"; + public static final String RELOAD_MODE = "spring.cloud.kubernetes.reload.mode"; private Constants() { } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java index 7dee4c89d9..ee85121995 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload.condition; +import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; @@ -33,11 +34,11 @@ public class EventReloadDetectionMode implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment environment = context.getEnvironment(); - if (!environment.containsProperty("spring.cloud.kubernetes.reload.mode")) { + if (!environment.containsProperty(Constants.RELOAD_MODE)) { return true; } return ConfigReloadProperties.ReloadDetectionMode.EVENT.name() - .equalsIgnoreCase(context.getEnvironment().getProperty("spring.cloud.kubernetes.reload.mode")); + .equalsIgnoreCase(environment.getProperty(Constants.RELOAD_MODE)); } } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java index 2e514b0111..e20d163b52 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload.condition; +import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; @@ -33,11 +34,11 @@ public class PollingReloadDetectionMode implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment environment = context.getEnvironment(); - if (!environment.containsProperty("spring.cloud.kubernetes.reload.mode")) { + if (!environment.containsProperty(Constants.RELOAD_MODE)) { return false; } return ConfigReloadProperties.ReloadDetectionMode.POLLING.name() - .equalsIgnoreCase(context.getEnvironment().getProperty("spring.cloud.kubernetes.reload.mode")); + .equalsIgnoreCase(environment.getProperty(Constants.RELOAD_MODE)); } } From cf4fca46f218ab3bfc55c7d406a40389bb4f442d Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 09:03:07 +0300 Subject: [PATCH 02/30] more changes --- .../reload/ConfigurationChangeDetector.java | 66 +++++++++---------- .../reload/PollingSecretsChangeDetector.java | 2 +- .../ConfigurationChangeDetectorTest.java | 25 ++++--- .../EventReloadDetectionModeTest.java | 12 ++-- .../PollingReloadDetectionModeTest.java | 12 ++-- 5 files changed, 57 insertions(+), 60 deletions(-) rename {spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8 => spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons}/config/reload/ConfigurationChangeDetectorTest.java (83%) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index c29dc7d086..3e1aa220ab 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -52,44 +52,26 @@ public abstract class ConfigurationChangeDetector { public ConfigurationChangeDetector(ConfigurableEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) { - this.environment = environment; - this.properties = properties; - this.strategy = strategy; + this.environment = Objects.requireNonNull(environment); + this.properties = Objects.requireNonNull(properties); + this.strategy = Objects.requireNonNull(strategy); } public void reloadProperties() { - this.log.info("Reloading using strategy: " + this.strategy.getName()); + log.info("Reloading using strategy: " + this.strategy.getName()); this.strategy.reload(); } - /** - * Determines if two property sources are different. - * @param left left map property sources - * @param right right map property sources - * @return {@code true} if source has changed - */ - public boolean changed(MapPropertySource left, MapPropertySource right) { - if (left == right) { - return false; - } - if (left == null || right == null) { - return true; - } - Map leftMap = left.getSource(); - Map rightMap = right.getSource(); - return !Objects.equals(leftMap, rightMap); - } - public boolean changed(List left, List right) { if (left.size() != right.size()) { - this.log.warn("The current number of ConfigMap PropertySources does not match " + log.warn("The current number of ConfigMap PropertySources does not match " + "the ones loaded from the Kubernetes - No reload will take place"); if (log.isDebugEnabled()) { - this.log.debug(String.format("source 1: %d", left.size())); + log.debug("left size : " + left.size()); left.forEach(item -> log.debug(item)); - this.log.debug(String.format("source 2: %d", right.size())); + log.debug("right size : " + right.size()); right.forEach(item -> log.debug(item)); } return false; @@ -116,7 +98,7 @@ protected > S findPropertySource(Class sourceClas return null; } if (sources.size() > 1) { - this.log.warn("Found more than one property source of type " + sourceClass); + log.warn("Found more than one property source of type " + sourceClass); } return sources.get(0); } @@ -130,9 +112,9 @@ public > List findPropertySources(Class source List managedSources = new LinkedList<>(); LinkedList> sources = toLinkedList(this.environment.getPropertySources()); - this.log.debug("findPropertySources"); - this.log.debug(String.format("environment: %s", this.environment)); - this.log.debug(String.format("environment sources: %s", sources)); + log.debug("findPropertySources"); + log.debug(String.format("environment: %s", this.environment)); + log.debug(String.format("environment sources: %s", sources)); while (!sources.isEmpty()) { PropertySource source = sources.pop(); @@ -184,14 +166,32 @@ else if (propertySource instanceof CompositePropertySource) { .collect(Collectors.toList())); } else { - this.log.debug("Found property source that cannot be handled: " + propertySource.getClass()); + log.debug("Found property source that cannot be handled: " + propertySource.getClass()); } - this.log.debug("locateMapPropertySources"); - this.log.debug(String.format("environment: %s", environment)); - this.log.debug(String.format("sources: %s", result)); + log.debug("locateMapPropertySources"); + log.debug(String.format("environment: %s", environment)); + log.debug(String.format("sources: %s", result)); return result; } + /** + * Determines if two property sources are different. + * @param left left map property sources + * @param right right map property sources + * @return {@code true} if source has changed + */ + boolean changed(MapPropertySource left, MapPropertySource right) { + if (left == right) { + return false; + } + if (left == null || right == null) { + return true; + } + Map leftMap = left.getSource(); + Map rightMap = right.getSource(); + return !Objects.equals(leftMap, rightMap); + } + } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java index 78ad722afe..114a097410 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java @@ -30,7 +30,7 @@ import org.springframework.scheduling.support.PeriodicTrigger; /** - * A change detector that periodically retrieves secrets and fire a reload when something + * A change detector that periodically retrieves secrets and fires a reload when something * changes. * * @author Nicola Ferraro diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigurationChangeDetectorTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java similarity index 83% rename from spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigurationChangeDetectorTest.java rename to spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java index 59715890fc..58595b1d42 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigurationChangeDetectorTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.kubernetes.fabric8.config.reload; +package org.springframework.cloud.kubernetes.commons.config.reload; import java.util.Collections; import java.util.HashMap; @@ -23,9 +23,6 @@ import org.junit.jupiter.api.Test; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; @@ -34,32 +31,32 @@ /** * @author wind57 */ -public class ConfigurationChangeDetectorTest { +class ConfigurationChangeDetectorTest { private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub(null, null, null); @Test - public void testChangedTwoNulls() { + void testChangedTwoNulls() { boolean changed = stub.changed(null, (MapPropertySource) null); assertThat(changed).isFalse(); } @Test - public void testChangedLeftNullRightNonNull() { + void testChangedLeftNullRightNonNull() { MapPropertySource right = new MapPropertySource("rightNonNull", Collections.emptyMap()); boolean changed = stub.changed(null, right); assertThat(changed).isTrue(); } @Test - public void testChangedLeftNonNullRightNull() { + void testChangedLeftNonNullRightNull() { MapPropertySource left = new MapPropertySource("leftNonNull", Collections.emptyMap()); boolean changed = stub.changed(left, null); assertThat(changed).isTrue(); } @Test - public void testChangedEqualMaps() { + void testChangedEqualMaps() { Object value = new Object(); Map leftMap = new HashMap<>(); leftMap.put("key", value); @@ -72,7 +69,7 @@ public void testChangedEqualMaps() { } @Test - public void testChangedNonEqualMaps() { + void testChangedNonEqualMaps() { Object value = new Object(); Map leftMap = new HashMap<>(); leftMap.put("key", value); @@ -86,7 +83,7 @@ public void testChangedNonEqualMaps() { } @Test - public void testChangedListsDifferentSizes() { + void testChangedListsDifferentSizes() { List left = Collections.singletonList(new MapPropertySource("one", Collections.emptyMap())); List right = Collections.emptyList(); boolean changed = stub.changed(left, right); @@ -94,7 +91,7 @@ public void testChangedListsDifferentSizes() { } @Test - public void testChangedListSameSizesButNotEqual() { + void testChangedListSameSizesButNotEqual() { Object value = new Object(); Map leftMap = new HashMap<>(); leftMap.put("key", value); @@ -107,7 +104,7 @@ public void testChangedListSameSizesButNotEqual() { } @Test - public void testChangedListSameSizesEqual() { + void testChangedListSameSizesEqual() { Object value = new Object(); Map leftMap = new HashMap<>(); leftMap.put("key", value); diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionModeTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionModeTest.java index 7b38b0998e..62c12343d5 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionModeTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionModeTest.java @@ -31,7 +31,7 @@ * @author wind57 */ @ExtendWith(MockitoExtension.class) -public class EventReloadDetectionModeTest { +class EventReloadDetectionModeTest { private static final String RELOAD_PROPERTY = "spring.cloud.kubernetes.reload.mode"; @@ -50,7 +50,7 @@ public class EventReloadDetectionModeTest { // returns a "null". // I am leaving it here just to make sure nothing breaks in branching @Test - public void testNull() { + void testNull() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn(null); @@ -60,7 +60,7 @@ public void testNull() { // lack of this property being set, means a match. @Test - public void testDoesNotContain() { + void testDoesNotContain() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(false); boolean matches = underTest.matches(context, metadata); @@ -68,7 +68,7 @@ public void testDoesNotContain() { } @Test - public void testMatchesCase() { + void testMatchesCase() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("EVENT"); @@ -77,7 +77,7 @@ public void testMatchesCase() { } @Test - public void testMatchesIgnoreCase() { + void testMatchesIgnoreCase() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("eVeNt"); @@ -86,7 +86,7 @@ public void testMatchesIgnoreCase() { } @Test - public void testNoMatch() { + void testNoMatch() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("not-eVeNt"); diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionModeTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionModeTest.java index d6317f03a5..ff65351dea 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionModeTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionModeTest.java @@ -31,7 +31,7 @@ * @author wind57 */ @ExtendWith(MockitoExtension.class) -public class PollingReloadDetectionModeTest { +class PollingReloadDetectionModeTest { private static final String RELOAD_PROPERTY = "spring.cloud.kubernetes.reload.mode"; @@ -50,7 +50,7 @@ public class PollingReloadDetectionModeTest { // returns a "null". // I am leaving it here just to make sure nothing breaks in branching @Test - public void testNull() { + void testNull() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn(null); @@ -60,7 +60,7 @@ public void testNull() { // lack of this property being set, means a NO match (unlike EventReloadDetectionMode) @Test - public void testDoesNotContain() { + void testDoesNotContain() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(false); boolean matches = underTest.matches(context, metadata); @@ -68,7 +68,7 @@ public void testDoesNotContain() { } @Test - public void testMatchesCase() { + void testMatchesCase() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("POLLING"); @@ -77,7 +77,7 @@ public void testMatchesCase() { } @Test - public void testMatchesIgnoreCase() { + void testMatchesIgnoreCase() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("PoLLiNG"); @@ -86,7 +86,7 @@ public void testMatchesIgnoreCase() { } @Test - public void testNoMatch() { + void testNoMatch() { Mockito.when(context.getEnvironment()).thenReturn(environment); Mockito.when(environment.containsProperty(RELOAD_PROPERTY)).thenReturn(true); Mockito.when(environment.getProperty(RELOAD_PROPERTY)).thenReturn("not-POLLING"); From 0ace7cd6618bc020eecab4129f416dbb576e17c1 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 12:48:38 +0300 Subject: [PATCH 03/30] fix test --- .../config/reload/ConfigurationChangeDetectorTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java index 58595b1d42..2079663b41 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java @@ -25,6 +25,7 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; +import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +34,8 @@ */ class ConfigurationChangeDetectorTest { - private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub(null, null, null); + private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub( + new MockEnvironment(), new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> {})); @Test void testChangedTwoNulls() { From 923895fb4f6de762b36bd0ae574446a9539d065f Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 12:50:41 +0300 Subject: [PATCH 04/30] fix test --- .../config/reload/ConfigurationChangeDetectorTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java index 2079663b41..3361827c4c 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java @@ -34,8 +34,10 @@ */ class ConfigurationChangeDetectorTest { - private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub( - new MockEnvironment(), new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> {})); + private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub(new MockEnvironment(), + new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> { + + })); @Test void testChangedTwoNulls() { From 6379ed962dbc2ee26ef2639777721c75ae36faba Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 12:51:52 +0300 Subject: [PATCH 05/30] make both final --- .../config/reload/condition/EventReloadDetectionMode.java | 2 +- .../config/reload/condition/PollingReloadDetectionMode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java index ee85121995..9e685ee0bd 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/EventReloadDetectionMode.java @@ -29,7 +29,7 @@ * @author Kris Iyer * */ -public class EventReloadDetectionMode implements Condition { +public final class EventReloadDetectionMode implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java index e20d163b52..46bc4ab418 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/PollingReloadDetectionMode.java @@ -29,7 +29,7 @@ * @author Kris Iyer * */ -public class PollingReloadDetectionMode implements Condition { +public final class PollingReloadDetectionMode implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { From ad85d114721f13a4293b03971380b24ebda2e8e4 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 14:38:45 +0300 Subject: [PATCH 06/30] first --- .../reload/ConfigReloadAutoConfiguration.java | 4 ++-- .../reload/ConfigurationChangeDetector.java | 4 ++-- .../reload/ConfigurationUpdateStrategy.java | 16 ++-------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index 67b066bb2c..2f756e085a 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload; +import java.util.Objects; import java.util.concurrent.ThreadLocalRandom; import org.springframework.beans.factory.annotation.Autowired; @@ -35,7 +36,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.util.Assert; /** * @author Ryan Baxter @@ -79,7 +79,7 @@ public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadPrope ContextRefresher refresher) { switch (properties.getStrategy()) { case RESTART_CONTEXT: - Assert.notNull(restarter, "Restart endpoint is not enabled"); + Objects.requireNonNull(restarter, "Restart endpoint is not enabled"); return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { wait(properties); restarter.restart(); diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index 3e1aa220ab..331e754d0e 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -58,8 +58,8 @@ public ConfigurationChangeDetector(ConfigurableEnvironment environment, ConfigRe } public void reloadProperties() { - log.info("Reloading using strategy: " + this.strategy.getName()); - this.strategy.reload(); + log.info("Reloading using strategy: " + this.strategy.name()); + this.strategy.reloadProcedure().run(); } public boolean changed(List left, List right) { diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationUpdateStrategy.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationUpdateStrategy.java index 3a5df3261b..bc7323debc 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationUpdateStrategy.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationUpdateStrategy.java @@ -24,28 +24,16 @@ * * @author Nicola Ferraro */ -public class ConfigurationUpdateStrategy { - - private final String name; - - private final Runnable reloadProcedure; +public final record ConfigurationUpdateStrategy(String name, Runnable reloadProcedure) { public ConfigurationUpdateStrategy(String name, Runnable reloadProcedure) { this.name = Objects.requireNonNull(name, "name cannot be null"); this.reloadProcedure = Objects.requireNonNull(reloadProcedure, "reloadProcedure cannot be null"); } - public String getName() { - return this.name; - } - - public void reload() { - this.reloadProcedure.run(); - } - @Override public String toString() { - return "ConfigurationUpdateStrategy{name='" + this.name + "'}"; + return this.getClass().getSimpleName() + "{name='" + this.name + "'}"; } } From c99f76029b228f2a9a87d9637d32932fc3874a9e Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 14:44:30 +0300 Subject: [PATCH 07/30] more clean-up --- .../reload/ConfigurationChangeDetector.java | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index 3e1aa220ab..822c5f34ec 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -85,24 +85,6 @@ public boolean changed(List left, List property source type - * @param sourceClass class for which property sources will be searched for - * @return matched property source - */ - protected > S findPropertySource(Class sourceClass) { - List sources = findPropertySources(sourceClass); - if (sources.size() == 0) { - return null; - } - if (sources.size() > 1) { - log.warn("Found more than one property source of type " + sourceClass); - } - return sources.get(0); - } - /** * @param property source type * @param sourceClass class for which property sources will be found @@ -112,14 +94,12 @@ public > List findPropertySources(Class source List managedSources = new LinkedList<>(); LinkedList> sources = toLinkedList(this.environment.getPropertySources()); - log.debug("findPropertySources"); - log.debug(String.format("environment: %s", this.environment)); - log.debug(String.format("environment sources: %s", sources)); + log.debug("environment: %s" + environment); + log.debug("environment sources " + sources); while (!sources.isEmpty()) { PropertySource source = sources.pop(); - if (source instanceof CompositePropertySource) { - CompositePropertySource comp = (CompositePropertySource) source; + if (source instanceof CompositePropertySource comp) { sources.addAll(comp.getPropertySources()); } else if (sourceClass.isInstance(source)) { @@ -169,9 +149,8 @@ else if (propertySource instanceof CompositePropertySource) { log.debug("Found property source that cannot be handled: " + propertySource.getClass()); } - log.debug("locateMapPropertySources"); - log.debug(String.format("environment: %s", environment)); - log.debug(String.format("sources: %s", result)); + log.debug("environment:" + environment); + log.debug("sources " + result); return result; } From 36e1baed19d8c247f29b1a7f6fa59aa53cbc3033 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 16:36:19 +0300 Subject: [PATCH 08/30] some simplifications --- .../reload/ConfigurationChangeDetector.java | 32 ++--- ... => ConfigurationChangeDetectorTests.java} | 116 +++++++++++++++--- 2 files changed, 110 insertions(+), 38 deletions(-) rename spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/{ConfigurationChangeDetectorTest.java => ConfigurationChangeDetectorTests.java} (53%) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index 822c5f34ec..729dbba6ba 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -17,7 +17,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -91,14 +90,15 @@ public boolean changed(List left, List> List findPropertySources(Class sourceClass) { - List managedSources = new LinkedList<>(); + List managedSources = new ArrayList<>(); - LinkedList> sources = toLinkedList(this.environment.getPropertySources()); - log.debug("environment: %s" + environment); - log.debug("environment sources " + sources); + List> sources = environment.getPropertySources().stream() + .collect(Collectors.toCollection(ArrayList::new)); + log.debug("environment: " + environment); + log.debug("environment sources: " + sources); while (!sources.isEmpty()) { - PropertySource source = sources.pop(); + PropertySource source = sources.remove(0); if (source instanceof CompositePropertySource comp) { sources.addAll(comp.getPropertySources()); } @@ -116,14 +116,6 @@ else if (source instanceof BootstrapPropertySource) { return managedSources; } - private LinkedList toLinkedList(Iterable it) { - LinkedList list = new LinkedList<>(); - for (E e : it) { - list.add(e); - } - return list; - } - /** * Returns a list of MapPropertySource that correspond to the current state of the * system. This only handles the PropertySource objects that are returned. @@ -140,16 +132,18 @@ protected List locateMapPropertySources(PropertySourceLocator if (propertySource instanceof MapPropertySource) { result.add((MapPropertySource) propertySource); } - else if (propertySource instanceof CompositePropertySource) { - result.addAll(((CompositePropertySource) propertySource).getPropertySources().stream() - .filter(p -> p instanceof MapPropertySource).map(p -> (MapPropertySource) p) - .collect(Collectors.toList())); + else if (propertySource instanceof CompositePropertySource source) { + + List list = source.getPropertySources().stream() + .filter(p -> p instanceof MapPropertySource).map(x -> (MapPropertySource) x) + .collect(Collectors.toList()); + result.addAll(list); } else { log.debug("Found property source that cannot be handled: " + propertySource.getClass()); } - log.debug("environment:" + environment); + log.debug("environment:" + environment); log.debug("sources " + result); return result; diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTests.java similarity index 53% rename from spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java rename to spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTests.java index 3361827c4c..6854c67cc0 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTest.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetectorTests.java @@ -16,15 +16,21 @@ package org.springframework.cloud.kubernetes.commons.config.reload; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.cloud.bootstrap.config.BootstrapPropertySource; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; @@ -32,30 +38,31 @@ /** * @author wind57 */ -class ConfigurationChangeDetectorTest { +class ConfigurationChangeDetectorTests { - private final ConfigurationChangeDetectorStub stub = new ConfigurationChangeDetectorStub(new MockEnvironment(), + private final ConfigurationChangeDetector changeDetector = new ConfigurationChangeDetector(new MockEnvironment(), new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> { - })); + })) { + }; @Test void testChangedTwoNulls() { - boolean changed = stub.changed(null, (MapPropertySource) null); + boolean changed = changeDetector.changed(null, (MapPropertySource) null); assertThat(changed).isFalse(); } @Test void testChangedLeftNullRightNonNull() { MapPropertySource right = new MapPropertySource("rightNonNull", Collections.emptyMap()); - boolean changed = stub.changed(null, right); + boolean changed = changeDetector.changed(null, right); assertThat(changed).isTrue(); } @Test void testChangedLeftNonNullRightNull() { MapPropertySource left = new MapPropertySource("leftNonNull", Collections.emptyMap()); - boolean changed = stub.changed(left, null); + boolean changed = changeDetector.changed(left, null); assertThat(changed).isTrue(); } @@ -68,7 +75,7 @@ void testChangedEqualMaps() { rightMap.put("key", value); MapPropertySource left = new MapPropertySource("left", leftMap); MapPropertySource right = new MapPropertySource("right", rightMap); - boolean changed = stub.changed(left, right); + boolean changed = changeDetector.changed(left, right); assertThat(changed).isFalse(); } @@ -82,7 +89,7 @@ void testChangedNonEqualMaps() { rightMap.put("key", value); MapPropertySource left = new MapPropertySource("left", leftMap); MapPropertySource right = new MapPropertySource("right", rightMap); - boolean changed = stub.changed(left, right); + boolean changed = changeDetector.changed(left, right); assertThat(changed).isTrue(); } @@ -90,7 +97,7 @@ void testChangedNonEqualMaps() { void testChangedListsDifferentSizes() { List left = Collections.singletonList(new MapPropertySource("one", Collections.emptyMap())); List right = Collections.emptyList(); - boolean changed = stub.changed(left, right); + boolean changed = changeDetector.changed(left, right); assertThat(changed).isFalse(); } @@ -103,7 +110,7 @@ void testChangedListSameSizesButNotEqual() { leftMap.put("anotherKey", value); List left = Collections.singletonList(new MapPropertySource("one", leftMap)); List right = Collections.singletonList(new MapPropertySource("two", rightMap)); - boolean changed = stub.changed(left, right); + boolean changed = changeDetector.changed(left, right); assertThat(changed).isTrue(); } @@ -116,18 +123,89 @@ void testChangedListSameSizesEqual() { leftMap.put("key", value); List left = Collections.singletonList(new MapPropertySource("one", leftMap)); List right = Collections.singletonList(new MapPropertySource("two", rightMap)); - boolean changed = stub.changed(left, right); + boolean changed = changeDetector.changed(left, right); assertThat(changed).isTrue(); } - /** - * only needed to test some protected methods it defines - */ - private static final class ConfigurationChangeDetectorStub extends ConfigurationChangeDetector { + @Test + void testFindPropertySources() { + MockEnvironment environment = new MockEnvironment(); + ConfigurationChangeDetector detector = new ConfigurationChangeDetector(environment, + new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> { + + })) { + }; + + MutablePropertySources propertySources = environment.getPropertySources(); + propertySources.addFirst(new OneComposite()); + propertySources.addFirst(new PlainPropertySource("plain")); + propertySources.addFirst(new OneBootstrap(new EnumerablePropertySource<>("enumerable") { + @Override + public String[] getPropertyNames() { + return new String[0]; + } + + @Override + public Object getProperty(String name) { + return null; + } + })); + + List result = detector.findPropertySources(PlainPropertySource.class); + Assertions.assertEquals(3, result.size()); + Assertions.assertEquals("plain", result.get(0).getProperty("")); + Assertions.assertEquals("from-bootstrap", result.get(1).getProperty("")); + Assertions.assertEquals("from-inner-two-composite", result.get(2).getProperty("")); + } + + private static final class OneComposite extends CompositePropertySource { + + private OneComposite() { + super("one"); + } + + @Override + public Collection> getPropertySources() { + return List.of(new TwoComposite()); + } + + } + + private static final class TwoComposite extends CompositePropertySource { + + private TwoComposite() { + super("two"); + } + + @Override + public Collection> getPropertySources() { + return List.of(new PlainPropertySource("from-inner-two-composite")); + } + + } + + private static final class PlainPropertySource extends PropertySource { + + private PlainPropertySource(String name) { + super(name); + } + + @Override + public Object getProperty(String name) { + return this.name; + } + + } + + private static final class OneBootstrap extends BootstrapPropertySource { + + private OneBootstrap(EnumerablePropertySource delegate) { + super(delegate); + } - private ConfigurationChangeDetectorStub(ConfigurableEnvironment environment, ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy) { - super(environment, properties, strategy); + @Override + public PropertySource getDelegate() { + return new PlainPropertySource("from-bootstrap"); } } From e3725f546c69bcb2aff7631b15b5b17b98bbea94 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 12 Jun 2022 16:38:12 +0300 Subject: [PATCH 09/30] same logging --- .../config/reload/ConfigurationChangeDetector.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index 729dbba6ba..c13dcfc4dd 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -67,10 +67,10 @@ public boolean changed(List left, List log.debug(item)); - log.debug("right size : " + right.size()); + log.debug("right size: " + right.size()); right.forEach(item -> log.debug(item)); } return false; @@ -143,8 +143,8 @@ else if (propertySource instanceof CompositePropertySource source) { log.debug("Found property source that cannot be handled: " + propertySource.getClass()); } - log.debug("environment:" + environment); - log.debug("sources " + result); + log.debug("environment: " + environment); + log.debug("sources: " + result); return result; } From 1eefcb99d9ed655c43370e80d6d80b96a9058706 Mon Sep 17 00:00:00 2001 From: wind57 Date: Tue, 14 Jun 2022 11:51:01 +0300 Subject: [PATCH 10/30] more clean-up, still I am in the blur a little --- .../reload/ConfigReloadAutoConfiguration.java | 5 +++-- .../config/reload/ConfigReloadProperties.java | 2 +- .../reload/ConfigurationChangeDetector.java | 2 +- .../PollingConfigMapChangeDetector.java | 22 +++++++++---------- .../reload/PollingSecretsChangeDetector.java | 18 +++++++-------- 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index 2f756e085a..55f197ab06 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -35,6 +35,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** @@ -56,13 +57,13 @@ protected static class ConfigReloadAutoConfigurationBeans { @Bean("springCloudKubernetesTaskScheduler") @ConditionalOnMissingBean - public TaskSchedulerWrapper taskScheduler() { + public TaskSchedulerWrapper taskScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-"); threadPoolTaskScheduler.setDaemon(true); - return new TaskSchedulerWrapper(threadPoolTaskScheduler); + return new TaskSchedulerWrapper<>(threadPoolTaskScheduler); } /** 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 1d5c80764e..c93e9ea8a9 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 @@ -44,7 +44,7 @@ public class ConfigReloadProperties { private boolean monitoringSecrets = false; /** - * Sets the reload strategy for Kubernetes configuration reload on change. + * Sets reload strategy for Kubernetes configuration reload on change. */ private ReloadStrategy strategy = ReloadStrategy.REFRESH; diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java index bb62749035..996829d0a5 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigurationChangeDetector.java @@ -58,7 +58,7 @@ public ConfigurationChangeDetector(ConfigurableEnvironment environment, ConfigRe public void reloadProperties() { log.info("Reloading using strategy: " + this.strategy.name()); - this.strategy.reloadProcedure().run(); + strategy.reloadProcedure().run(); } public boolean changed(List left, List right) { diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java index be75cb39bf..e626c84d98 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java @@ -41,16 +41,16 @@ public class PollingConfigMapChangeDetector extends ConfigurationChangeDetector protected Log log = LogFactory.getLog(getClass()); - private PropertySourceLocator propertySourceLocator; + private final PropertySourceLocator propertySourceLocator; - private Class propertySourceClass; + private final Class propertySourceClass; - private TaskScheduler taskExecutor; + private final TaskScheduler taskExecutor; - private Duration period = Duration.ofMillis(1500); + private final Duration period; public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, Class propertySourceClass, + ConfigurationUpdateStrategy strategy, Class propertySourceClass, PropertySourceLocator propertySourceLocator, TaskScheduler taskExecutor) { super(environment, properties, strategy); this.propertySourceLocator = propertySourceLocator; @@ -61,19 +61,17 @@ public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigRel @PostConstruct public void init() { - this.log.info("Kubernetes polling configMap change detector activated"); + log.info("Kubernetes polling configMap change detector activated"); PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); trigger.setInitialDelay(period.toMillis()); taskExecutor.schedule(this::executeCycle, trigger); } - public void executeCycle() { + private void executeCycle() { boolean changedConfigMap = false; - if (this.properties.isMonitoringConfigMaps()) { - if (log.isDebugEnabled()) { - log.debug("Polling for changes in config maps"); - } + if (properties.isMonitoringConfigMaps()) { + log.debug("Polling for changes in config maps"); List currentConfigMapSources = findPropertySources(propertySourceClass); if (!currentConfigMapSources.isEmpty()) { @@ -83,7 +81,7 @@ public void executeCycle() { } if (changedConfigMap) { - this.log.info("Detected change in config maps"); + log.info("Detected change in config maps"); reloadProperties(); } } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java index 114a097410..adc780a55a 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java @@ -43,14 +43,14 @@ public class PollingSecretsChangeDetector extends ConfigurationChangeDetector { private final PropertySourceLocator propertySourceLocator; - private Class propertySourceClass; + private final Class propertySourceClass; - private TaskScheduler taskExecutor; + private final TaskScheduler taskExecutor; - private Duration period = Duration.ofMillis(1500); + private final Duration period; public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, Class propertySourceClass, + ConfigurationUpdateStrategy strategy, Class propertySourceClass, PropertySourceLocator propertySourceLocator, TaskScheduler taskExecutor) { super(environment, properties, strategy); this.propertySourceLocator = propertySourceLocator; @@ -61,7 +61,7 @@ public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloa @PostConstruct public void init() { - this.log.info("Kubernetes polling secrets change detector activated"); + log.info("Kubernetes polling secrets change detector activated"); PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); trigger.setInitialDelay(period.toMillis()); taskExecutor.schedule(this::executeCycle, trigger); @@ -71,19 +71,17 @@ public void executeCycle() { boolean changedSecrets = false; if (this.properties.isMonitoringSecrets()) { - if (log.isDebugEnabled()) { - log.debug("Polling for changes in secrets"); - } + log.debug("Polling for changes in secrets"); List currentSecretSources = locateMapPropertySources(this.propertySourceLocator, this.environment); if (currentSecretSources != null && !currentSecretSources.isEmpty()) { - List propertySources = findPropertySources(this.propertySourceClass); + List propertySources = findPropertySources(this.propertySourceClass); changedSecrets = changed(currentSecretSources, propertySources); } } if (changedSecrets) { - this.log.info("Detected change in secrets"); + log.info("Detected change in secrets"); reloadProperties(); } } From f60830a0d4bc11f3d27445917158ec0c060c12e9 Mon Sep 17 00:00:00 2001 From: wind57 Date: Tue, 14 Jun 2022 22:33:40 +0300 Subject: [PATCH 11/30] clean-up --- ...ventBasedConfigMapChangeDetectorTests.java | 8 +- ...tEventBasedSecretsChangeDetectorTests.java | 8 +- .../reload/ConfigReloadAutoConfiguration.java | 87 ++++---- .../ConfigMapWatcherChangeDetector.java | 4 +- .../watcher/SecretsWatcherChangeDetector.java | 4 +- .../reload/ConfigReloadAutoConfiguration.java | 200 ------------------ .../ConfigReloadDefaultAutoConfiguration.java | 182 ---------------- .../Fabric8ConfigReloadAutoConfiguration.java | 145 +++++++++++++ ...ic8EventBasedConfigMapChangeDetector.java} | 4 +- ...bric8EventBasedSecretsChangeDetector.java} | 4 +- .../main/resources/META-INF/spring.factories | 2 +- ...BasedConfigurationChangeDetectorTests.java | 6 +- .../config/KubernetesConfigTestBase.java | 7 +- 13 files changed, 205 insertions(+), 456 deletions(-) delete mode 100644 spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java delete mode 100644 spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java create mode 100644 spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java rename spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/{EventBasedConfigMapChangeDetector.java => Fabric8EventBasedConfigMapChangeDetector.java} (95%) rename spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/{EventBasedSecretsChangeDetector.java => Fabric8EventBasedSecretsChangeDetector.java} (95%) diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java index 88b0a44b31..94761c371a 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java @@ -148,7 +148,7 @@ void watch() { apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.getName()).thenReturn("strategy"); + when(strategy.name()).thenReturn("strategy"); KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientConfigMapPropertySource.class)).withProperty("debug", "true"); KubernetesClientConfigMapPropertySourceLocator locator = mock( @@ -164,13 +164,13 @@ void watch() { controllerThread.start(); await().timeout(Duration.ofSeconds(5)) .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)).reload(); + verify(strategy, atLeast(3)); } // This is needed when using JDK17 because GSON uses reflection to construct an // OffsetDateTime but that constructor // is protected. - public class GsonOffsetDateTimeAdapter extends TypeAdapter { + public static class GsonOffsetDateTimeAdapter extends TypeAdapter { @Override public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IOException { @@ -178,7 +178,7 @@ public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IO } @Override - public OffsetDateTime read(JsonReader jsonReader) throws IOException { + public OffsetDateTime read(JsonReader jsonReader) { return OffsetDateTime.now(); } 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 4c438e89a7..e63978a74a 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 @@ -143,7 +143,7 @@ void watch() { apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.getName()).thenReturn("strategy"); + when(strategy.name()).thenReturn("strategy"); KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientSecretsPropertySource.class)).withProperty("db-password", "p455w0rd"); KubernetesClientSecretsPropertySourceLocator locator = mock(KubernetesClientSecretsPropertySourceLocator.class); @@ -162,13 +162,13 @@ void watch() { await().timeout(Duration.ofSeconds(300)) .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)).reload(); + verify(strategy, atLeast(3)); } // This is needed when using JDK17 because GSON uses reflection to construct an // OffsetDateTime but that constructor // is protected. - public class GsonOffsetDateTimeAdapter extends TypeAdapter { + public static class GsonOffsetDateTimeAdapter extends TypeAdapter { @Override public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IOException { @@ -176,7 +176,7 @@ public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IO } @Override - public OffsetDateTime read(JsonReader jsonReader) throws IOException { + public OffsetDateTime read(JsonReader jsonReader) { return OffsetDateTime.now(); } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index 55f197ab06..c64c621f1f 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -45,66 +45,51 @@ @ConditionalOnKubernetesAndConfigEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class }) + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) +@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") public class ConfigReloadAutoConfiguration { - /** - * Configuration reload must be enabled explicitly. - */ - @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") - @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) - protected static class ConfigReloadAutoConfigurationBeans { + @Bean("springCloudKubernetesTaskScheduler") + @ConditionalOnMissingBean + public TaskSchedulerWrapper taskScheduler() { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); - @Bean("springCloudKubernetesTaskScheduler") - @ConditionalOnMissingBean - public TaskSchedulerWrapper taskScheduler() { - ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-"); + threadPoolTaskScheduler.setDaemon(true); - threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-"); - threadPoolTaskScheduler.setDaemon(true); + return new TaskSchedulerWrapper<>(threadPoolTaskScheduler); + } - return new TaskSchedulerWrapper<>(threadPoolTaskScheduler); + @Bean + @ConditionalOnMissingBean + public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, + ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter, + ContextRefresher refresher) { + switch (properties.getStrategy()) { + case RESTART_CONTEXT: + Objects.requireNonNull(restarter, "Restart endpoint is not enabled"); + return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { + wait(properties); + restarter.restart(); + }); + case REFRESH: + return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh); + case SHUTDOWN: + return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { + wait(properties); + ctx.close(); + }); } + throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy()); + } - /** - * @param properties config reload properties - * @param ctx application context - * @param restarter restart endpoint - * @param refresher context refresher - * @return provides the action to execute when the configuration changes. - */ - @Bean - @ConditionalOnMissingBean - public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, - ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter, - ContextRefresher refresher) { - switch (properties.getStrategy()) { - case RESTART_CONTEXT: - Objects.requireNonNull(restarter, "Restart endpoint is not enabled"); - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { - wait(properties); - restarter.restart(); - }); - case REFRESH: - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh); - case SHUTDOWN: - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { - wait(properties); - ctx.close(); - }); - } - throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy()); + private static void wait(ConfigReloadProperties properties) { + final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis()); + try { + Thread.sleep(waitMillis); } - - private static void wait(ConfigReloadProperties properties) { - final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis()); - try { - Thread.sleep(waitMillis); - } - catch (InterruptedException ignored) { - } + catch (InterruptedException ignored) { } - } } diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java index 02d6ffb080..84a216205b 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java @@ -29,7 +29,7 @@ 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.reload.EventBasedConfigMapChangeDetector; +import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedConfigMapChangeDetector; import org.springframework.core.env.AbstractEnvironment; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -37,7 +37,7 @@ * @author Ryan Baxter * @author Kris Iyer */ -public abstract class ConfigMapWatcherChangeDetector extends EventBasedConfigMapChangeDetector { +public abstract class ConfigMapWatcherChangeDetector extends Fabric8EventBasedConfigMapChangeDetector { protected Log log = LogFactory.getLog(getClass()); diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java index e81adba52e..ffe7bf36cf 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java @@ -29,7 +29,7 @@ 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.reload.EventBasedSecretsChangeDetector; +import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedSecretsChangeDetector; import org.springframework.core.env.AbstractEnvironment; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -37,7 +37,7 @@ * @author Ryan Baxter * @author Kris Iyer */ -public abstract class SecretsWatcherChangeDetector extends EventBasedSecretsChangeDetector { +public abstract class SecretsWatcherChangeDetector extends Fabric8EventBasedSecretsChangeDetector { protected Log log = LogFactory.getLog(getClass()); diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java deleted file mode 100644 index 0b9335659b..0000000000 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2013-2019 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; - -import java.util.concurrent.ThreadLocalRandom; - -import io.fabric8.kubernetes.client.KubernetesClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; -import org.springframework.cloud.commons.util.TaskSchedulerWrapper; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.cloud.context.restart.RestartEndpoint; -import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesAndConfigEnabled; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; -import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.util.Assert; - -/** - * Definition of beans needed for the automatic reload of configuration. - * - * @author Nicolla Ferraro - * @author Kris Iyer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnKubernetesAndConfigEnabled -@ConditionalOnClass(EndpointAutoConfiguration.class) -@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class }) -@EnableConfigurationProperties(ConfigReloadProperties.class) -public class ConfigReloadAutoConfiguration { - - /** - * Configuration reload must be enabled explicitly. - */ - @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") - @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) - protected static class ConfigReloadAutoConfigurationBeans { - - @Autowired - private AbstractEnvironment environment; - - @Autowired - private KubernetesClient kubernetesClient; - - /** - * Polling configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8ConfigMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, - TaskSchedulerWrapper taskSchedulerWrapper) { - - return new PollingConfigMapChangeDetector(this.environment, properties, strategy, - Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator, - taskSchedulerWrapper.getTaskScheduler()); - } - - /** - * Polling secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8SecretsPropertySourceLocator secrets property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, - TaskSchedulerWrapper taskScheduler) { - - return new PollingSecretsChangeDetector(this.environment, properties, strategy, - Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator, - taskScheduler.getTaskScheduler()); - } - - /** - * Event Based configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8ConfigMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configMap change events and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { - - return new EventBasedConfigMapChangeDetector(this.environment, properties, this.kubernetesClient, strategy, - fabric8ConfigMapPropertySourceLocator); - } - - /** - * Event Based secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8SecretsPropertySourceLocator secrets property source locator - * @return a bean that listen to secrets change events and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { - - return new EventBasedSecretsChangeDetector(this.environment, properties, this.kubernetesClient, strategy, - fabric8SecretsPropertySourceLocator); - } - - /** - * @param properties config reload properties - * @param ctx application context - * @param restarter restart endpoint - * @param refresher context refresher - * @return provides the action to execute when the configuration changes. - */ - @Bean - @ConditionalOnMissingBean - public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, - ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter, - ContextRefresher refresher) { - switch (properties.getStrategy()) { - case RESTART_CONTEXT: - Assert.notNull(restarter, "Restart endpoint is not enabled"); - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { - wait(properties); - restarter.restart(); - }); - case REFRESH: - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh); - case SHUTDOWN: - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { - wait(properties); - ctx.close(); - }); - } - throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy()); - } - - private static void wait(ConfigReloadProperties properties) { - final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis()); - try { - Thread.sleep(waitMillis); - } - catch (InterruptedException ignored) { - } - } - - } - -} diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java deleted file mode 100644 index cd3246b10b..0000000000 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013-2020 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; - -import java.util.concurrent.ThreadLocalRandom; - -import io.fabric8.kubernetes.client.KubernetesClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.cloud.CloudPlatform; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.commons.util.TaskSchedulerWrapper; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; -import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; -import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; -import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource; -import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.AbstractEnvironment; - -/** - * @author Ryan Baxter - * @author Kris Iyer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) -@ConditionalOnMissingBean(ConfigReloadAutoConfiguration.class) -@EnableConfigurationProperties(ConfigReloadProperties.class) -public class ConfigReloadDefaultAutoConfiguration { - - /** - * Configuration reload must be enabled explicitly. - */ - @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") - protected static class ConfigReloadAutoConfigurationBeans { - - @Autowired - private AbstractEnvironment environment; - - @Autowired - private KubernetesClient kubernetesClient; - - @Autowired - private Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator; - - @Autowired - private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; - - private static void wait(ConfigReloadProperties properties) { - final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis()); - try { - Thread.sleep(waitMillis); - } - catch (InterruptedException ignored) { - } - } - - /** - * Polling configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8ConfigMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, - TaskSchedulerWrapper taskSchedulerWrapper) { - - return new PollingConfigMapChangeDetector(this.environment, properties, strategy, - Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator, - taskSchedulerWrapper.getTaskScheduler()); - } - - /** - * Polling secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8SecretsPropertySourceLocator secrets property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, - TaskSchedulerWrapper taskScheduler) { - - return new PollingSecretsChangeDetector(this.environment, properties, strategy, - Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator, - taskScheduler.getTaskScheduler()); - } - - /** - * Event Based configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8ConfigMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configMap change events and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { - - return new EventBasedConfigMapChangeDetector(this.environment, properties, this.kubernetesClient, strategy, - fabric8ConfigMapPropertySourceLocator); - } - - /** - * Event Based secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param fabric8SecretsPropertySourceLocator secrets property source locator - * @return a bean that listen to secrets change events and fire a reload. - */ - @Bean - @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { - - return new EventBasedSecretsChangeDetector(this.environment, properties, this.kubernetesClient, strategy, - fabric8SecretsPropertySourceLocator); - } - - /** - * @param properties config reload properties - * @param ctx application context - * @return provides the action to execute when the configuration changes. - */ - @Bean - @ConditionalOnMissingBean - public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, - ConfigurableApplicationContext ctx) { - switch (properties.getStrategy()) { - case SHUTDOWN: - return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> { - wait(properties); - ctx.close(); - }); - } - throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy()); - } - - } - -} diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java new file mode 100644 index 0000000000..d2fffcb7b9 --- /dev/null +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -0,0 +1,145 @@ +/* + * Copyright 2013-2019 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; + +import io.fabric8.kubernetes.client.KubernetesClient; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; +import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; +import org.springframework.cloud.commons.util.TaskSchedulerWrapper; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.cloud.context.restart.RestartEndpoint; +import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesAndConfigEnabled; +import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration; +import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; +import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; +import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; +import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; +import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; +import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; +import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource; +import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource; +import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.TaskScheduler; + +/** + * Definition of beans needed for the automatic reload of configuration. + * + * @author Nicolla Ferraro + * @author Kris Iyer + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnKubernetesAndConfigEnabled +@ConditionalOnClass(EndpointAutoConfiguration.class) +@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, + ConfigReloadAutoConfiguration.class }) +@EnableConfigurationProperties(ConfigReloadProperties.class) +@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") +public class Fabric8ConfigReloadAutoConfiguration { + + /** + * Polling configMap ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param fabric8ConfigMapPropertySourceLocator configMap property source locator + * @return a bean that listen to configuration changes and fire a reload. + */ + @Bean + @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) + @Conditional(PollingReloadDetectionMode.class) + public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, + TaskSchedulerWrapper taskSchedulerWrapper, AbstractEnvironment environment) { + + return new PollingConfigMapChangeDetector(environment, properties, strategy, + Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator, + taskSchedulerWrapper.getTaskScheduler()); + } + + /** + * Polling secrets ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param fabric8SecretsPropertySourceLocator secrets property source locator + * @return a bean that listen to configuration changes and fire a reload. + */ + @Bean + @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) + @Conditional(PollingReloadDetectionMode.class) + public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, + TaskSchedulerWrapper taskScheduler, AbstractEnvironment environment) { + + return new PollingSecretsChangeDetector(environment, properties, strategy, Fabric8SecretsPropertySource.class, + fabric8SecretsPropertySourceLocator, taskScheduler.getTaskScheduler()); + } + + /** + * Event Based configMap ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param fabric8ConfigMapPropertySourceLocator configMap property source locator + * @return a bean that listen to configMap change events and fire a reload. + */ + @Bean + @ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class) + @Conditional(EventReloadDetectionMode.class) + public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, + AbstractEnvironment environment, KubernetesClient kubernetesClient) { + + return new Fabric8EventBasedConfigMapChangeDetector(environment, properties, kubernetesClient, strategy, + fabric8ConfigMapPropertySourceLocator); + } + + /** + * Event Based secrets ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param fabric8SecretsPropertySourceLocator secrets property source locator + * @return a bean that listen to secrets change events and fire a reload. + */ + @Bean + @ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class) + @Conditional(EventReloadDetectionMode.class) + public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, AbstractEnvironment environment, + KubernetesClient kubernetesClient) { + + return new Fabric8EventBasedSecretsChangeDetector(environment, properties, kubernetesClient, strategy, + fabric8SecretsPropertySourceLocator); + } + +} diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedConfigMapChangeDetector.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java similarity index 95% rename from spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedConfigMapChangeDetector.java rename to spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java index 56e3f04be1..8b0edae9e1 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedConfigMapChangeDetector.java @@ -46,7 +46,7 @@ * @author Haytham Mohamed * @author Kris Iyer */ -public class EventBasedConfigMapChangeDetector extends ConfigurationChangeDetector { +public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChangeDetector { private final Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator; @@ -54,7 +54,7 @@ public class EventBasedConfigMapChangeDetector extends ConfigurationChangeDetect private KubernetesClient kubernetesClient; - public EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, + public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { super(environment, properties, strategy); diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java similarity index 95% rename from spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedSecretsChangeDetector.java rename to spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java index 7149cf81ec..b3a4c5e21d 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/EventBasedSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8EventBasedSecretsChangeDetector.java @@ -46,7 +46,7 @@ * @author Haytham Mohamed * @author Kris Iyer */ -public class EventBasedSecretsChangeDetector extends ConfigurationChangeDetector { +public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeDetector { private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; @@ -54,7 +54,7 @@ public class EventBasedSecretsChangeDetector extends ConfigurationChangeDetector private KubernetesClient kubernetesClient; - public EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, + public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { super(environment, properties, strategy); diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories index 04934d5bdb..95082d6258 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories @@ -1,5 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfiguration +org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8ConfigReloadAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ org.springframework.cloud.kubernetes.fabric8.config.Fabric8BootstrapConfiguration,\ org.springframework.cloud.kubernetes.fabric8.config.Fabric8RetryBootstrapConfiguration diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java index 7db69d96c7..852649f4a8 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java @@ -35,7 +35,7 @@ import org.springframework.cloud.kubernetes.commons.config.NormalizedSource; 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.reload.EventBasedConfigMapChangeDetector; +import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedConfigMapChangeDetector; import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; @@ -76,8 +76,8 @@ void verifyConfigChangesAccountsForBootstrapPropertySources() { ConfigurationUpdateStrategy configurationUpdateStrategy = mock(ConfigurationUpdateStrategy.class); Fabric8ConfigMapPropertySourceLocator configMapLocator = mock(Fabric8ConfigMapPropertySourceLocator.class); - EventBasedConfigMapChangeDetector detector = new EventBasedConfigMapChangeDetector(env, configReloadProperties, - k8sClient, configurationUpdateStrategy, configMapLocator); + Fabric8EventBasedConfigMapChangeDetector detector = new Fabric8EventBasedConfigMapChangeDetector(env, + configReloadProperties, k8sClient, configurationUpdateStrategy, configMapLocator); List sources = detector .findPropertySources(Fabric8ConfigMapPropertySource.class); assertThat(sources.size()).isEqualTo(1); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java index fdfea0693d..aa664a30f6 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java @@ -25,7 +25,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.bootstrap.BootstrapConfiguration; -import org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfiguration; +import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8ConfigReloadAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; /** @@ -45,8 +45,9 @@ protected void setup(Class mockClientConfiguration, String... env) { String[] properties = Stream.concat(Arrays.stream(commonProperties), Arrays.stream(env)) .toArray(size -> new String[size]); context = new SpringApplicationBuilder(PropertyPlaceholderAutoConfiguration.class, mockClientConfiguration, - BootstrapConfiguration.class, ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class) - .web(org.springframework.boot.WebApplicationType.NONE).properties(properties).run(); + BootstrapConfiguration.class, Fabric8ConfigReloadAutoConfiguration.class, + RefreshAutoConfiguration.class).web(org.springframework.boot.WebApplicationType.NONE) + .properties(properties).run(); } @AfterEach From 9f953ab68d3a4022c895d77973067933bf8bf0ce Mon Sep 17 00:00:00 2001 From: wind57 Date: Wed, 15 Jun 2022 10:09:59 +0300 Subject: [PATCH 12/30] clean-up part 4 --- ...esClientConfigReloadAutoConfiguration.java | 152 +++++++++--------- ...ientEventBasedConfigMapChangeDetector.java | 24 ++- ...ClientEventBasedSecretsChangeDetector.java | 24 ++- .../reload/ConfigReloadAutoConfiguration.java | 5 +- .../PollingConfigMapChangeDetector.java | 14 +- .../reload/PollingSecretsChangeDetector.java | 14 +- .../ConditionalOnKubernetesReloadEnabled.java | 40 +++++ .../Fabric8ConfigReloadAutoConfiguration.java | 3 +- ...ric8EventBasedConfigMapChangeDetector.java | 44 +++-- ...abric8EventBasedSecretsChangeDetector.java | 51 +++--- 10 files changed, 199 insertions(+), 172 deletions(-) create mode 100644 spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index eb1f9e3398..e80a0084d8 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; @@ -42,111 +41,106 @@ import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; +import org.springframework.cloud.kubernetes.commons.config.reload.condition.ConditionalOnKubernetesReloadEnabled; import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.TaskScheduler; /** * @author Ryan Baxter */ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled +@ConditionalOnKubernetesReloadEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, ConfigReloadAutoConfiguration.class }) + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, ConfigReloadAutoConfiguration.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) public class KubernetesClientConfigReloadAutoConfiguration { /** - * Configuration reload must be enabled explicitly. + * Polling configMap ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param configMapPropertySourceLocator configMap property source locator + * @return a bean that listen to configuration changes and fire a reload. */ - @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") - @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) - protected static class ConfigReloadAutoConfigurationBeans { + @Bean + @ConditionalOnBean(KubernetesClientConfigMapPropertySourceLocator.class) + @Conditional(PollingReloadDetectionMode.class) + public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator, + AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { - /** - * Polling configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param configMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(KubernetesClientConfigMapPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator, - AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { - - return new PollingConfigMapChangeDetector(environment, properties, strategy, - KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator, - taskScheduler.getTaskScheduler()); - } + return new PollingConfigMapChangeDetector(environment, properties, strategy, + KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator, + taskScheduler.getTaskScheduler()); + } - /** - * Polling secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param secretsPropertySourceLocator secrets property source locator - * @return a bean that listen to configuration changes and fire a reload. - */ - @Bean - @ConditionalOnBean(KubernetesClientSecretsPropertySourceLocator.class) - @Conditional(PollingReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, - AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { + /** + * Polling secrets ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param secretsPropertySourceLocator secrets property source locator + * @return a bean that listen to configuration changes and fire a reload. + */ + @Bean + @ConditionalOnBean(KubernetesClientSecretsPropertySourceLocator.class) + @Conditional(PollingReloadDetectionMode.class) + public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, + AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { - return new PollingSecretsChangeDetector(environment, properties, strategy, - KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator, - taskScheduler.getTaskScheduler()); - } + return new PollingSecretsChangeDetector(environment, properties, strategy, + KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator, + taskScheduler.getTaskScheduler()); + } - /** - * Event Based configMap ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param configMapPropertySourceLocator configMap property source locator - * @return a bean that listen to configMap change events and fire a reload. - */ - @Bean - @ConditionalOnBean(KubernetesClientConfigMapPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator, - AbstractEnvironment environment, CoreV1Api coreV1Api, - KubernetesNamespaceProvider kubernetesNamespaceProvider) { + /** + * Event Based configMap ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param configMapPropertySourceLocator configMap property source locator + * @return a bean that listen to configMap change events and fire a reload. + */ + @Bean + @ConditionalOnBean(KubernetesClientConfigMapPropertySourceLocator.class) + @Conditional(EventReloadDetectionMode.class) + public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator, + AbstractEnvironment environment, CoreV1Api coreV1Api, + KubernetesNamespaceProvider kubernetesNamespaceProvider) { - return new KubernetesClientEventBasedConfigMapChangeDetector(coreV1Api, environment, properties, strategy, - configMapPropertySourceLocator, kubernetesNamespaceProvider); - } + return new KubernetesClientEventBasedConfigMapChangeDetector(coreV1Api, environment, properties, strategy, + configMapPropertySourceLocator, kubernetesNamespaceProvider); + } - /** - * Event Based secrets ConfigurationChangeDetector. - * @param properties config reload properties - * @param strategy configuration update strategy - * @param secretsPropertySourceLocator secrets property source locator - * @return a bean that listen to secrets change events and fire a reload. - */ - @Bean - @ConditionalOnBean(KubernetesClientSecretsPropertySourceLocator.class) - @Conditional(EventReloadDetectionMode.class) - public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, - ConfigurationUpdateStrategy strategy, - KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, - AbstractEnvironment environment, CoreV1Api coreV1Api, - KubernetesNamespaceProvider kubernetesNamespaceProvider) { - return new KubernetesClientEventBasedSecretsChangeDetector(coreV1Api, environment, properties, strategy, - secretsPropertySourceLocator, kubernetesNamespaceProvider); - } + /** + * Event Based secrets ConfigurationChangeDetector. + * @param properties config reload properties + * @param strategy configuration update strategy + * @param secretsPropertySourceLocator secrets property source locator + * @return a bean that listen to secrets change events and fire a reload. + */ + @Bean + @ConditionalOnBean(KubernetesClientSecretsPropertySourceLocator.class) + @Conditional(EventReloadDetectionMode.class) + public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, + KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, + AbstractEnvironment environment, CoreV1Api coreV1Api, + KubernetesNamespaceProvider kubernetesNamespaceProvider) { + return new KubernetesClientEventBasedSecretsChangeDetector(coreV1Api, environment, properties, strategy, + secretsPropertySourceLocator, kubernetesNamespaceProvider); } } 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 82a8e811af..33ce5b9784 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 @@ -46,15 +46,15 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura private static final Log LOG = LogFactory.getLog(KubernetesClientEventBasedConfigMapChangeDetector.class); - private CoreV1Api coreV1Api = null; + private final CoreV1Api coreV1Api; private final KubernetesClientConfigMapPropertySourceLocator propertySourceLocator; private final SharedInformerFactory factory; - private KubernetesClientProperties kubernetesClientProperties; + private final String namespace; - private KubernetesNamespaceProvider kubernetesNamespaceProvider; + private final boolean monitorConfigMaps; public KubernetesClientEventBasedConfigMapChangeDetector(CoreV1Api coreV1Api, ConfigurableEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, @@ -71,26 +71,22 @@ public KubernetesClientEventBasedConfigMapChangeDetector(CoreV1Api coreV1Api, Co // certificate authorities for the cluster. This results in SSL errors. // See https://github.com/spring-cloud/spring-cloud-kubernetes/issues/885 this.factory = new SharedInformerFactory(createApiClientForInformerClient()); - this.kubernetesNamespaceProvider = kubernetesNamespaceProvider; - } - - private String getNamespace() { - return kubernetesNamespaceProvider != null ? kubernetesNamespaceProvider.getNamespace() - : kubernetesClientProperties.getNamespace(); + this.namespace = kubernetesNamespaceProvider.getNamespace(); + this.monitorConfigMaps = properties.isMonitoringConfigMaps(); } @PostConstruct public void watch() { - if (coreV1Api != null && this.properties.isMonitoringConfigMaps()) { + if (coreV1Api != null && monitorConfigMaps) { SharedIndexInformer configMapInformer = factory.sharedIndexInformerFor( - (CallGeneratorParams params) -> coreV1Api.listNamespacedConfigMapCall(getNamespace(), null, null, + (CallGeneratorParams params) -> coreV1Api.listNamespacedConfigMapCall(namespace, null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null), V1ConfigMap.class, V1ConfigMapList.class); - configMapInformer.addEventHandler(new ResourceEventHandler() { + configMapInformer.addEventHandler(new ResourceEventHandler<>() { @Override public void onAdd(V1ConfigMap obj) { - LOG.info("CongifMap " + obj.getMetadata().getName() + " was added."); + LOG.info("ConfigMap " + obj.getMetadata().getName() + " was added."); onEvent(obj); } @@ -116,7 +112,7 @@ public void unwatch() { } private void onEvent(V1ConfigMap configMap) { - this.log.debug(String.format("onEvent configMap: %s", configMap.toString())); + LOG.debug("onEvent configMap: " + configMap.toString()); boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment), findPropertySources(KubernetesClientConfigMapPropertySource.class)); if (changed) { diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java index 45b2490ed3..cc155763a2 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java @@ -45,15 +45,15 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati private static final Log LOG = LogFactory.getLog(KubernetesClientEventBasedSecretsChangeDetector.class); - private CoreV1Api coreV1Api; + private final CoreV1Api coreV1Api; private final KubernetesClientSecretsPropertySourceLocator propertySourceLocator; private final SharedInformerFactory factory; - private KubernetesClientProperties kubernetesClientProperties; + private final String namespace; - private KubernetesNamespaceProvider kubernetesNamespaceProvider; + private final boolean monitorSecrets; public KubernetesClientEventBasedSecretsChangeDetector(CoreV1Api coreV1Api, ConfigurableEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, @@ -70,22 +70,18 @@ public KubernetesClientEventBasedSecretsChangeDetector(CoreV1Api coreV1Api, Conf // See https://github.com/spring-cloud/spring-cloud-kubernetes/issues/885 this.factory = new SharedInformerFactory(createApiClientForInformerClient()); this.coreV1Api = coreV1Api; - this.kubernetesNamespaceProvider = kubernetesNamespaceProvider; - } - - private String getNamespace() { - return kubernetesNamespaceProvider != null ? kubernetesNamespaceProvider.getNamespace() - : kubernetesClientProperties.getNamespace(); + this.namespace = kubernetesNamespaceProvider.getNamespace(); + this.monitorSecrets = properties.isMonitoringSecrets(); } @PostConstruct public void watch() { - if (coreV1Api != null && this.properties.isMonitoringSecrets()) { + if (coreV1Api != null && monitorSecrets) { SharedIndexInformer configMapInformer = factory.sharedIndexInformerFor( - (CallGeneratorParams params) -> coreV1Api.listNamespacedSecretCall(getNamespace(), null, null, null, + (CallGeneratorParams params) -> coreV1Api.listNamespacedSecretCall(namespace, null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null), V1Secret.class, V1SecretList.class); - configMapInformer.addEventHandler(new ResourceEventHandler() { + configMapInformer.addEventHandler(new ResourceEventHandler<>() { @Override public void onAdd(V1Secret obj) { LOG.info("Secret " + obj.getMetadata().getName() + " was added."); @@ -109,11 +105,11 @@ public void onDelete(V1Secret obj, boolean deletedFinalStateUnknown) { } private void onEvent(V1Secret secret) { - this.log.debug(String.format("onEvent configMap: %s", secret.toString())); + LOG.debug("onEvent configMap: " + secret.toString()); boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment), findPropertySources(KubernetesClientSecretsPropertySource.class)); if (changed) { - this.log.info("Detected change in secrets"); + LOG.info("Detected change in secrets"); reloadProperties(); } } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index c64c621f1f..c1425263ce 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * 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. @@ -32,6 +32,7 @@ import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.context.restart.RestartEndpoint; import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesAndConfigEnabled; +import org.springframework.cloud.kubernetes.commons.config.reload.condition.ConditionalOnKubernetesReloadEnabled; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,10 +44,10 @@ */ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled +@ConditionalOnKubernetesReloadEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) -@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") public class ConfigReloadAutoConfiguration { @Bean("springCloudKubernetesTaskScheduler") diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java index e626c84d98..f1a1ba16f8 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java @@ -16,7 +16,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload; -import java.time.Duration; import java.util.List; import jakarta.annotation.PostConstruct; @@ -47,7 +46,9 @@ public class PollingConfigMapChangeDetector extends ConfigurationChangeDetector private final TaskScheduler taskExecutor; - private final Duration period; + private final long period; + + private final boolean monitorConfigMaps; public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, Class propertySourceClass, @@ -56,21 +57,22 @@ public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigRel this.propertySourceLocator = propertySourceLocator; this.propertySourceClass = propertySourceClass; this.taskExecutor = taskExecutor; - this.period = properties.getPeriod(); + this.period = properties.getPeriod().toMillis(); + this.monitorConfigMaps = properties.isMonitoringConfigMaps(); } @PostConstruct public void init() { log.info("Kubernetes polling configMap change detector activated"); - PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); - trigger.setInitialDelay(period.toMillis()); + PeriodicTrigger trigger = new PeriodicTrigger(period); + trigger.setInitialDelay(period); taskExecutor.schedule(this::executeCycle, trigger); } private void executeCycle() { boolean changedConfigMap = false; - if (properties.isMonitoringConfigMaps()) { + if (monitorConfigMaps) { log.debug("Polling for changes in config maps"); List currentConfigMapSources = findPropertySources(propertySourceClass); diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java index adc780a55a..023a6f640c 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java @@ -16,7 +16,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload; -import java.time.Duration; import java.util.List; import jakarta.annotation.PostConstruct; @@ -47,7 +46,9 @@ public class PollingSecretsChangeDetector extends ConfigurationChangeDetector { private final TaskScheduler taskExecutor; - private final Duration period; + private final long period; + + private final boolean monitorSecrets; public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, Class propertySourceClass, @@ -56,21 +57,22 @@ public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloa this.propertySourceLocator = propertySourceLocator; this.propertySourceClass = propertySourceClass; this.taskExecutor = taskExecutor; - this.period = properties.getPeriod(); + this.period = properties.getPeriod().toMillis(); + this.monitorSecrets = properties.isMonitoringSecrets(); } @PostConstruct public void init() { log.info("Kubernetes polling secrets change detector activated"); - PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); - trigger.setInitialDelay(period.toMillis()); + PeriodicTrigger trigger = new PeriodicTrigger(period); + trigger.setInitialDelay(period); taskExecutor.schedule(this::executeCycle, trigger); } public void executeCycle() { boolean changedSecrets = false; - if (this.properties.isMonitoringSecrets()) { + if (monitorSecrets) { log.debug("Polling for changes in secrets"); List currentSecretSources = locateMapPropertySources(this.propertySourceLocator, this.environment); diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java new file mode 100644 index 0000000000..21f886b94d --- /dev/null +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java @@ -0,0 +1,40 @@ +/* + * 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.commons.config.reload.condition; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Provides a more succinct conditional for: + * spring.cloud.kubernetes.reload.enabled. + * + * @author wind57 + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ConditionalOnProperty(prefix = "spring.cloud.kubernetes.reload.enabled", havingValue = "true") +public @interface ConditionalOnKubernetesReloadEnabled { +} diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java index d2fffcb7b9..b3dafa1580 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -37,6 +37,7 @@ import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; +import org.springframework.cloud.kubernetes.commons.config.reload.condition.ConditionalOnKubernetesReloadEnabled; import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource; @@ -57,12 +58,12 @@ */ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled +@ConditionalOnKubernetesReloadEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, ConfigReloadAutoConfiguration.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) -@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") public class Fabric8ConfigReloadAutoConfiguration { /** 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 8b0edae9e1..0d1e6a3d90 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 @@ -52,7 +52,9 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang private final Map watches; - private KubernetesClient kubernetesClient; + private final KubernetesClient kubernetesClient; + + private final boolean monitoringConfigMaps; public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, @@ -61,6 +63,7 @@ public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, this.kubernetesClient = kubernetesClient; this.fabric8ConfigMapPropertySourceLocator = fabric8ConfigMapPropertySourceLocator; this.watches = new HashMap<>(); + monitoringConfigMaps = properties.isMonitoringConfigMaps(); } @PreDestroy @@ -74,15 +77,13 @@ public void shutdown() { public void watch() { boolean activated = false; - if (this.properties.isMonitoringConfigMaps()) { + if (monitoringConfigMaps) { try { String name = "config-maps-watch-event"; - this.watches.put(name, this.kubernetesClient.configMaps().watch(new Watcher() { + watches.put(name, this.kubernetesClient.configMaps().watch(new Watcher<>() { @Override public void eventReceived(Watcher.Action action, ConfigMap configMap) { - if (log.isDebugEnabled()) { - log.debug(name + " received event for ConfigMap " + configMap.getMetadata().getName()); - } + log.debug(name + " received event for ConfigMap " + configMap.getMetadata().getName()); onEvent(configMap); } @@ -97,43 +98,40 @@ public void onClose(WatcherException exception) { } })); activated = true; - this.log.info("Added new Kubernetes watch: " + name); + log.info("Added new Kubernetes watch: " + name); } catch (Exception e) { - this.log.error( - "Error while establishing a connection to watch config maps: configuration may remain stale", - e); + log.error( + "Error while establishing a connection to watch config maps: configuration may remain stale", + e); } } if (activated) { - this.log.info("Kubernetes event-based configMap change detector activated"); + log.info("Kubernetes event-based configMap change detector activated"); } } @PreDestroy public void unwatch() { - if (this.watches != null) { - for (Map.Entry entry : this.watches.entrySet()) { - try { - this.log.debug("Closing the watch " + entry.getKey()); - entry.getValue().close(); - - } - catch (Exception e) { - this.log.error("Error while closing the watch connection", e); - } + for (Map.Entry entry : this.watches.entrySet()) { + try { + log.debug("Closing the watch " + entry.getKey()); + entry.getValue().close(); + } + catch (Exception e) { + log.error("Error while closing the watch connection", e); } } } protected void onEvent(ConfigMap configMap) { - this.log.debug(String.format("onEvent configMap: %s", configMap.toString())); + log.debug("onEvent configMap: " + configMap.toString()); boolean changed = changed( locateMapPropertySources(this.fabric8ConfigMapPropertySourceLocator, this.environment), findPropertySources(Fabric8ConfigMapPropertySource.class)); if (changed) { - this.log.info("Detected change in config maps"); + log.info("Detected change in config maps"); reloadProperties(); } } 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 b3a4c5e21d..d62db7e9fe 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 @@ -48,11 +48,13 @@ */ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeDetector { - private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; + private final Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; - private Map watches; + private final Map watches; - private KubernetesClient kubernetesClient; + private final KubernetesClient kubernetesClient; + + private final boolean monitorSecrets; public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, @@ -61,35 +63,33 @@ public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, C this.kubernetesClient = kubernetesClient; this.fabric8SecretsPropertySourceLocator = fabric8SecretsPropertySourceLocator; this.watches = new HashMap<>(); + this.monitorSecrets = properties.isMonitoringSecrets(); } @PreDestroy public void shutdown() { // Ensure the kubernetes client is cleaned up from spare threads when shutting // down - this.kubernetesClient.close(); + kubernetesClient.close(); } @PostConstruct public void watch() { boolean activated = false; - if (this.properties.isMonitoringSecrets()) { + if (monitorSecrets) { try { - activated = false; String name = "secrets-watch-event"; - this.watches.put(name, this.kubernetesClient.secrets().watch(new Watcher() { + watches.put(name, this.kubernetesClient.secrets().watch(new Watcher<>() { @Override public void eventReceived(Action action, Secret secret) { - if (log.isDebugEnabled()) { - log.debug(name + " received event for Secret " + secret.getMetadata().getName()); - } + log.debug(name + " received event for Secret " + secret.getMetadata().getName()); onEvent(secret); } @Override public void onClose(WatcherException exception) { - log.warn("Secrects watch closed", exception); + log.warn("Secrets watch closed", exception); Optional.ofNullable(exception).map(e -> { log.debug("Exception received during watch", e); return exception.asClientException(); @@ -98,41 +98,38 @@ public void onClose(WatcherException exception) { } })); activated = true; - this.log.info("Added new Kubernetes watch: " + name); + log.info("Added new Kubernetes watch: " + name); } catch (Exception e) { - this.log.error("Error while establishing a connection to watch secrets: configuration may remain stale", + log.error("Error while establishing a connection to watch secrets: configuration may remain stale", e); } } if (activated) { - this.log.info("Kubernetes event-based secrets change detector activated"); + log.info("Kubernetes event-based secrets change detector activated"); } } @PreDestroy public void unwatch() { - if (this.watches != null) { - for (Map.Entry entry : this.watches.entrySet()) { - try { - this.log.debug("Closing the watch " + entry.getKey()); - entry.getValue().close(); - - } - catch (Exception e) { - this.log.error("Error while closing the watch connection", e); - } + for (Map.Entry entry : watches.entrySet()) { + try { + log.debug("Closing the watch " + entry.getKey()); + entry.getValue().close(); + } + catch (Exception e) { + log.error("Error while closing the watch connection", e); } } } protected void onEvent(Secret secret) { - this.log.debug(String.format("onEvent configMap: %s", secret.toString())); - boolean changed = changed(locateMapPropertySources(this.fabric8SecretsPropertySourceLocator, this.environment), + log.debug("onEvent secrets: " + secret.toString()); + boolean changed = changed(locateMapPropertySources(fabric8SecretsPropertySourceLocator, environment), findPropertySources(Fabric8SecretsPropertySource.class)); if (changed) { - this.log.info("Detected change in secrets"); + log.info("Detected change in secrets"); reloadProperties(); } } From d148d2fb9a611a035bd4d56da4cdca500d52e7c5 Mon Sep 17 00:00:00 2001 From: wind57 Date: Wed, 15 Jun 2022 18:45:22 +0300 Subject: [PATCH 13/30] configmap polling test added --- .../pom.xml | 1 + .../pom.xml | 107 ++++++++++ .../polling/reload/ConfigMapApp.java | 35 ++++ .../polling/reload/ConfigMapController.java | 39 ++++ .../polling/reload/ConfigMapProperties.java | 37 ++++ .../src/main/resources/application.yaml | 18 ++ .../reload/ConfigMapPollingReloadIT.java | 196 ++++++++++++++++++ .../src/test/resources/configmap.yaml | 8 + .../src/test/resources/deployment.yaml | 28 +++ .../src/test/resources/ingress.yaml | 16 ++ .../src/test/resources/logback-test.xml | 14 ++ .../src/test/resources/service.yaml | 14 ++ 12 files changed, 513 insertions(+) create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/pom.xml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapApp.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapController.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/resources/application.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/ingress.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/logback-test.xml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/service.yaml diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index f2cc8862b0..dc48c7a34a 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -114,5 +114,6 @@ spring-cloud-kubernetes-client-reactive-discoveryclient-it spring-cloud-kubernetes-configuration-watcher-it spring-cloud-kubernetes-core-k8s-client-it + spring-cloud-kubernetes-fabric8-client-configmap-polling-reload diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/pom.xml new file mode 100644 index 0000000000..c0a6e6c82f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/pom.xml @@ -0,0 +1,107 @@ + + + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 3.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + + + + + org.springframework.cloud + spring-cloud-kubernetes-fabric8-config + + + org.springframework.cloud + spring-cloud-kubernetes-test-support + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + + + com.github.docker-java + docker-java-core + test + + + com.github.docker-java + docker-java-transport-httpclient5 + test + + + + + + + + ../src/main/resources + true + + + src/main/resources + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + docker.io/springcloud/${project.artifactId}:${project.version} + paketobuildpacks/builder + + + + package + + build-image + + + + + + + + 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-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapApp.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapApp.java new file mode 100644 index 0000000000..8594a99cc6 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapApp.java @@ -0,0 +1,35 @@ +/* + * 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.fabric8.configmap.polling.reload; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +/** + * @author wind57 + */ + +@SpringBootApplication +@EnableConfigurationProperties(ConfigMapProperties.class) +public class ConfigMapApp { + + public static void main(String[] args) { + SpringApplication.run(ConfigMapApp.class, args); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapController.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapController.java new file mode 100644 index 0000000000..c59aa7fc93 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapController.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2021 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.configmap.polling.reload; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wind57 + */ +@RestController +public class ConfigMapController { + + private final ConfigMapProperties properties; + + public ConfigMapController(ConfigMapProperties properties) { + this.properties = properties; + } + + @GetMapping("/key") + public String key() { + return properties.getKey(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java new file mode 100644 index 0000000000..167cc57f8f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2021 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.configmap.polling.reload; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author wind57 + */ +@ConfigurationProperties("from.yaml") +public class ConfigMapProperties { + + private String key; + + public String getKey() { + return key; + } + + public void setKey(String key1) { + this.key = key1; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/resources/application.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/resources/application.yaml new file mode 100644 index 0000000000..baf0f12d35 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/resources/application.yaml @@ -0,0 +1,18 @@ +logging: + level: + root: DEBUG + +spring: + application: + name: poll-reload + config: + import: "kubernetes:" + cloud: + kubernetes: + reload: + enabled: true + monitoring-config-maps: true + strategy: shutdown + mode: polling + period: 5000 + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java new file mode 100644 index 0000000000..71c5e9a72f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java @@ -0,0 +1,196 @@ +/* + * 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.fabric8.configmap.polling.reload; + +import java.io.InputStream; +import java.time.Duration; +import java.util.Map; +import java.util.Objects; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.networking.v1.Ingress; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.DefaultKubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; +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.mockito.Mockito; +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.Fabric8Utils; +import org.springframework.cloud.kubernetes.integration.tests.commons.K8SUtils; +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; + +/** + * @author wind57 + */ +class ConfigMapPollingReloadIT { + + private static final String IMAGE_NAME = "spring-cloud-kubernetes-fabric8-client-configmap-polling-reload"; + + private static final String NAMESPACE = "default"; + + private static KubernetesClient client; + + private static String deploymentName; + + private static String serviceName; + + private static String ingressName; + + private static String configMapName; + + private static final K3sContainer K3S = Commons.container(); + + @BeforeAll + static void beforeAll() throws Exception { + K3S.start(); + Commons.validateImage(IMAGE_NAME, K3S); + Commons.loadSpringCloudKubernetesImage(IMAGE_NAME, K3S); + Config config = Config.fromKubeconfig(K3S.getKubeConfigYaml()); + client = new DefaultKubernetesClient(config); + Fabric8Utils.setUp(client, NAMESPACE); + deployManifests(); + } + + @AfterAll + static void after() throws Exception { + deleteManifests(); + Commons.cleanUp(IMAGE_NAME, K3S); + } + + @SuppressWarnings({ "raw", "unchecked" }) + @Test + void test() { + WebClient webClient = builder().baseUrl("localhost/key").build(); + String result = webClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) + .block(); + + // we first read the initial value from the configmap + Assertions.assertEquals("initial", result); + + // then deploy a new version of configmap + // since we poll and have reload in place, the new property must be visible + ConfigMap map = new ConfigMapBuilder() + .withMetadata(new ObjectMetaBuilder().withNamespace("default").withName("poll-reload").build()) + .withData(Map.of("application.properties", "from.yaml.key=after-change")).build(); + + // the weird cast comes from : + // https://github.com/fabric8io/kubernetes-client/issues/2445 + ((HasMetadataOperation) client.configMaps().inNamespace("default").withName("poll-reload")) + .createOrReplace(map); + + await().timeout(Duration.ofSeconds(30)) + .until(() -> webClient.method(HttpMethod.GET).retrieve() + .bodyToMono(String.class) + .retryWhen(retrySpec()) + .block() + .equals("after-change")); + + } + + private static void deleteManifests() { + + try { + + client.configMaps().inNamespace(NAMESPACE).withName(configMapName).delete(); + client.apps().deployments().inNamespace(NAMESPACE).withName(deploymentName).delete(); + client.services().inNamespace(NAMESPACE).withName(serviceName).delete(); + client.network().v1().ingresses().inNamespace(NAMESPACE).withName(ingressName).delete(); + + } + catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private static void deployManifests() { + + try { + + ConfigMap configMap = client.configMaps().load(getConfigMap()).get(); + configMapName = configMap.getMetadata().getName(); + client.configMaps().create(configMap); + + Deployment deployment = client.apps().deployments().load(getDeployment()).get(); + + String version = K8SUtils.getPomVersion(); + String currentImage = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); + deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(currentImage + ":" + version); + + client.apps().deployments().inNamespace(NAMESPACE).create(deployment); + deploymentName = deployment.getMetadata().getName(); + + Service service = client.services().load(getService()).get(); + serviceName = service.getMetadata().getName(); + client.services().inNamespace(NAMESPACE).create(service); + + Ingress ingress = client.network().v1().ingresses().load(getIngress()).get(); + ingressName = ingress.getMetadata().getName(); + client.network().v1().ingresses().inNamespace(NAMESPACE).create(ingress); + + Fabric8Utils.waitForDeployment(client, + "spring-cloud-kubernetes-fabric8-client-configmap-deployment-polling-reload", NAMESPACE, 2, 600); + + } + catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private static InputStream getService() { + return Fabric8Utils.inputStream("service.yaml"); + } + + private static InputStream getDeployment() { + return Fabric8Utils.inputStream("deployment.yaml"); + } + + private static InputStream getIngress() { + return Fabric8Utils.inputStream("ingress.yaml"); + } + + private static InputStream getConfigMap() { + return Fabric8Utils.inputStream("configmap.yaml"); + } + + private WebClient.Builder builder() { + return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())); + } + + private RetryBackoffSpec retrySpec() { + return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml new file mode 100644 index 0000000000..7619a473ee --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: poll-reload + namespace: default +data: + application.properties: | + from.yaml.key=initial diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/deployment.yaml new file mode 100644 index 0000000000..39f4572c07 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-fabric8-client-configmap-deployment-polling-reload +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + template: + metadata: + labels: + app: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + spec: + serviceAccountName: spring-cloud-kubernetes-serviceaccount + containers: + - name: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + image: docker.io/springcloud/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8080 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8080 + path: /actuator/health/liveness + ports: + - containerPort: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/ingress.yaml new file mode 100644 index 0000000000..fd53e216c1 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-cloud-kubernetes-fabric8-client-configmap-ingress-polling-reload + namespace: default +spec: + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + port: + number: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..9e2848765f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/service.yaml new file mode 100644 index 0000000000..2995e2b6b0 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + name: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: spring-cloud-kubernetes-fabric8-client-configmap-polling-reload + type: ClusterIP From 2a5da4c3a018b27e35ec9c95efdb7a23535ff7c8 Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 10:26:33 +0300 Subject: [PATCH 14/30] informers + tests --- ...esClientConfigReloadAutoConfiguration.java | 4 +- .../reload/ConfigReloadAutoConfiguration.java | 1 - .../ConditionalOnKubernetesReloadEnabled.java | 7 +- .../watcher/SecretsWatcherChangeDetector.java | 2 +- .../Fabric8ConfigReloadAutoConfiguration.java | 8 +- ...ric8EventBasedConfigMapChangeDetector.java | 99 +++------ ...abric8EventBasedSecretsChangeDetector.java | 89 +++----- ...BasedConfigurationChangeDetectorTests.java | 4 +- .../config/KubernetesConfigTestBase.java | 3 +- .../pom.xml | 3 +- .../polling/reload/ConfigMapProperties.java | 2 +- .../reload/ConfigMapPollingReloadIT.java | 11 +- .../src/test/resources/configmap.yaml | 2 +- .../pom.xml | 107 ++++++++++ .../secrets/event/reload/SecretsApp.java | 35 ++++ .../event/reload/SecretsController.java | 39 ++++ .../event/reload/SecretsProperties.java | 37 ++++ .../src/main/resources/application.yaml | 21 ++ .../event/reload/SecretsEventsReloadIT.java | 194 ++++++++++++++++++ .../src/test/resources/deployment.yaml | 28 +++ .../src/test/resources/ingress.yaml | 16 ++ .../src/test/resources/logback-test.xml | 14 ++ .../src/test/resources/secret.yaml | 9 + .../src/test/resources/service.yaml | 14 ++ 24 files changed, 597 insertions(+), 152 deletions(-) create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/pom.xml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsApp.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsController.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsProperties.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/resources/application.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/ingress.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/logback-test.xml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/secret.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/service.yaml diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index e80a0084d8..e9d5a8e0c0 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -47,6 +47,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.core.env.AbstractEnvironment; import org.springframework.scheduling.TaskScheduler; @@ -58,8 +59,9 @@ @ConditionalOnKubernetesReloadEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, ConfigReloadAutoConfiguration.class }) + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) +@Import(ConfigReloadAutoConfiguration.class) public class KubernetesClientConfigReloadAutoConfiguration { /** diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index c1425263ce..943593ea7b 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -25,7 +25,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; import org.springframework.cloud.commons.util.TaskSchedulerWrapper; diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java index 21f886b94d..821ff45444 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/condition/ConditionalOnKubernetesReloadEnabled.java @@ -16,8 +16,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload.condition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -25,6 +23,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + /** * Provides a more succinct conditional for: * spring.cloud.kubernetes.reload.enabled. @@ -35,6 +35,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@ConditionalOnProperty(prefix = "spring.cloud.kubernetes.reload.enabled", havingValue = "true") +@ConditionalOnProperty(name = "spring.cloud.kubernetes.reload.enabled", havingValue = "true") public @interface ConditionalOnKubernetesReloadEnabled { + } diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java index ffe7bf36cf..b4fd9f9817 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/SecretsWatcherChangeDetector.java @@ -41,7 +41,7 @@ public abstract class SecretsWatcherChangeDetector extends Fabric8EventBasedSecr protected Log log = LogFactory.getLog(getClass()); - private ScheduledExecutorService executorService; + private final ScheduledExecutorService executorService; protected ConfigurationWatcherConfigurationProperties k8SConfigurationProperties; diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java index b3dafa1580..31182ee5f0 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * 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. @@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; @@ -47,6 +46,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.core.env.AbstractEnvironment; import org.springframework.scheduling.TaskScheduler; @@ -61,9 +61,9 @@ @ConditionalOnKubernetesReloadEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, - ConfigReloadAutoConfiguration.class }) + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) +@Import(ConfigReloadAutoConfiguration.class) public class Fabric8ConfigReloadAutoConfiguration { /** 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 0d1e6a3d90..455e23317b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * 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. @@ -16,18 +16,10 @@ package org.springframework.cloud.kubernetes.fabric8.config.reload; -import java.net.HttpURLConnection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.Status; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; -import io.fabric8.kubernetes.client.WatcherException; +import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.fabric8.kubernetes.client.informers.SharedIndexInformer; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; @@ -50,85 +42,58 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang private final Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator; - private final Map watches; - private final KubernetesClient kubernetesClient; private final boolean monitoringConfigMaps; + private SharedIndexInformer informer; + public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { super(environment, properties, strategy); this.kubernetesClient = kubernetesClient; this.fabric8ConfigMapPropertySourceLocator = fabric8ConfigMapPropertySourceLocator; - this.watches = new HashMap<>(); monitoringConfigMaps = properties.isMonitoringConfigMaps(); } - @PreDestroy - public void shutdown() { - // Ensure the kubernetes client is cleaned up from spare threads when shutting - // down - this.kubernetesClient.close(); - } - @PostConstruct - public void watch() { - boolean activated = false; - + private void inform() { if (monitoringConfigMaps) { - try { - String name = "config-maps-watch-event"; - watches.put(name, this.kubernetesClient.configMaps().watch(new Watcher<>() { - @Override - public void eventReceived(Watcher.Action action, ConfigMap configMap) { - log.debug(name + " received event for ConfigMap " + configMap.getMetadata().getName()); - onEvent(configMap); - } - - @Override - public void onClose(WatcherException exception) { - log.warn("ConfigMaps watch closed", exception); - Optional.ofNullable(exception).map(e -> { - log.debug("Exception received during watch", e); - return exception.asClientException(); - }).map(KubernetesClientException::getStatus).map(Status::getCode) - .filter(c -> c.equals(HttpURLConnection.HTTP_GONE)).ifPresent(c -> watch()); - } - })); - activated = true; - log.info("Added new Kubernetes watch: " + name); - } - catch (Exception e) { - log.error( - "Error while establishing a connection to watch config maps: configuration may remain stale", - e); - } - } - - if (activated) { - log.info("Kubernetes event-based configMap change detector activated"); + informer = kubernetesClient.configMaps().inform(); + informer.addEventHandler(new ResourceEventHandler<>() { + @Override + public void onAdd(ConfigMap configMap) { + onEvent(configMap); + } + + @Override + public void onUpdate(ConfigMap oldConfigMap, ConfigMap newConfigMap) { + onEvent(newConfigMap); + } + + @Override + public void onDelete(ConfigMap configMap, boolean deletedFinalStateUnknown) { + onEvent(configMap); + } + }); } } @PreDestroy - public void unwatch() { - for (Map.Entry entry : this.watches.entrySet()) { - try { - log.debug("Closing the watch " + entry.getKey()); - entry.getValue().close(); - } - catch (Exception e) { - log.error("Error while closing the watch connection", e); - } + private void shutdown() { + if (informer != null) { + log.debug("closing configmap informer"); + informer.close(); } + // Ensure the kubernetes client is cleaned up from spare threads when shutting + // down + kubernetesClient.close(); } protected void onEvent(ConfigMap configMap) { - log.debug("onEvent configMap: " + configMap.toString()); - boolean changed = changed( - locateMapPropertySources(this.fabric8ConfigMapPropertySourceLocator, this.environment), + log.debug("onEvent configMap: " + configMap.toString()); + boolean changed = changed(locateMapPropertySources(fabric8ConfigMapPropertySourceLocator, environment), findPropertySources(Fabric8ConfigMapPropertySource.class)); if (changed) { log.info("Detected change in config maps"); 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 d62db7e9fe..3c563689d0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * 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. @@ -16,18 +16,10 @@ package org.springframework.cloud.kubernetes.fabric8.config.reload; -import java.net.HttpURLConnection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - import io.fabric8.kubernetes.api.model.Secret; -import io.fabric8.kubernetes.api.model.Status; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; -import io.fabric8.kubernetes.client.WatcherException; +import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.fabric8.kubernetes.client.informers.SharedIndexInformer; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; @@ -50,77 +42,52 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD private final Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; - private final Map watches; - private final KubernetesClient kubernetesClient; private final boolean monitorSecrets; + private SharedIndexInformer informer; + public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { super(environment, properties, strategy); this.kubernetesClient = kubernetesClient; this.fabric8SecretsPropertySourceLocator = fabric8SecretsPropertySourceLocator; - this.watches = new HashMap<>(); this.monitorSecrets = properties.isMonitoringSecrets(); } @PreDestroy - public void shutdown() { + private void shutdown() { + if (informer != null) { + log.debug("closing secrets informer"); + informer.close(); + } // Ensure the kubernetes client is cleaned up from spare threads when shutting // down kubernetesClient.close(); } @PostConstruct - public void watch() { - boolean activated = false; - + private void inform() { if (monitorSecrets) { - try { - String name = "secrets-watch-event"; - watches.put(name, this.kubernetesClient.secrets().watch(new Watcher<>() { - @Override - public void eventReceived(Action action, Secret secret) { - log.debug(name + " received event for Secret " + secret.getMetadata().getName()); - onEvent(secret); - } - - @Override - public void onClose(WatcherException exception) { - log.warn("Secrets watch closed", exception); - Optional.ofNullable(exception).map(e -> { - log.debug("Exception received during watch", e); - return exception.asClientException(); - }).map(KubernetesClientException::getStatus).map(Status::getCode) - .filter(c -> c.equals(HttpURLConnection.HTTP_GONE)).ifPresent(c -> watch()); - } - })); - activated = true; - log.info("Added new Kubernetes watch: " + name); - } - catch (Exception e) { - log.error("Error while establishing a connection to watch secrets: configuration may remain stale", - e); - } - } - - if (activated) { - log.info("Kubernetes event-based secrets change detector activated"); - } - } - - @PreDestroy - public void unwatch() { - for (Map.Entry entry : watches.entrySet()) { - try { - log.debug("Closing the watch " + entry.getKey()); - entry.getValue().close(); - } - catch (Exception e) { - log.error("Error while closing the watch connection", e); - } + informer = kubernetesClient.secrets().inform(); + informer.addEventHandler(new ResourceEventHandler<>() { + @Override + public void onAdd(Secret secret) { + onEvent(secret); + } + + @Override + public void onUpdate(Secret oldSecret, Secret newSecret) { + onEvent(newSecret); + } + + @Override + public void onDelete(Secret secret, boolean deletedFinalStateUnknown) { + onEvent(secret); + } + }); } } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java index 852649f4a8..8ce2dc713d 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java @@ -74,7 +74,9 @@ void verifyConfigChangesAccountsForBootstrapPropertySources() { Fabric8ConfigMapPropertySource fabric8ConfigMapPropertySource = new Fabric8ConfigMapPropertySource(context); env.getPropertySources().addFirst(new BootstrapPropertySource<>(fabric8ConfigMapPropertySource)); - ConfigurationUpdateStrategy configurationUpdateStrategy = mock(ConfigurationUpdateStrategy.class); + ConfigurationUpdateStrategy configurationUpdateStrategy = new ConfigurationUpdateStrategy("some", () -> { + + }); Fabric8ConfigMapPropertySourceLocator configMapLocator = mock(Fabric8ConfigMapPropertySourceLocator.class); Fabric8EventBasedConfigMapChangeDetector detector = new Fabric8EventBasedConfigMapChangeDetector(env, configReloadProperties, k8sClient, configurationUpdateStrategy, configMapLocator); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java index aa664a30f6..462d8b446b 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/KubernetesConfigTestBase.java @@ -42,8 +42,7 @@ protected ConfigurableApplicationContext getContext() { } protected void setup(Class mockClientConfiguration, String... env) { - String[] properties = Stream.concat(Arrays.stream(commonProperties), Arrays.stream(env)) - .toArray(size -> new String[size]); + String[] properties = Stream.concat(Arrays.stream(commonProperties), Arrays.stream(env)).toArray(String[]::new); context = new SpringApplicationBuilder(PropertyPlaceholderAutoConfiguration.class, mockClientConfiguration, BootstrapConfiguration.class, Fabric8ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class).web(org.springframework.boot.WebApplicationType.NONE) diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index dc48c7a34a..d63c74daae 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -115,5 +115,6 @@ spring-cloud-kubernetes-configuration-watcher-it spring-cloud-kubernetes-core-k8s-client-it spring-cloud-kubernetes-fabric8-client-configmap-polling-reload - + spring-cloud-kubernetes-fabric8-client-secrets-event-reload + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java index 167cc57f8f..0b6f7e61d7 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapProperties.java @@ -21,7 +21,7 @@ /** * @author wind57 */ -@ConfigurationProperties("from.yaml") +@ConfigurationProperties("from.properties") public class ConfigMapProperties { private String key; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java index 71c5e9a72f..0879ad9c91 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/configmap/polling/reload/ConfigMapPollingReloadIT.java @@ -35,7 +35,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.testcontainers.k3s.K3sContainer; import reactor.netty.http.client.HttpClient; import reactor.util.retry.Retry; @@ -102,19 +101,15 @@ void test() { // since we poll and have reload in place, the new property must be visible ConfigMap map = new ConfigMapBuilder() .withMetadata(new ObjectMetaBuilder().withNamespace("default").withName("poll-reload").build()) - .withData(Map.of("application.properties", "from.yaml.key=after-change")).build(); + .withData(Map.of("application.properties", "from.properties.key=after-change")).build(); // the weird cast comes from : // https://github.com/fabric8io/kubernetes-client/issues/2445 ((HasMetadataOperation) client.configMaps().inNamespace("default").withName("poll-reload")) .createOrReplace(map); - await().timeout(Duration.ofSeconds(30)) - .until(() -> webClient.method(HttpMethod.GET).retrieve() - .bodyToMono(String.class) - .retryWhen(retrySpec()) - .block() - .equals("after-change")); + await().timeout(Duration.ofSeconds(30)).until(() -> webClient.method(HttpMethod.GET).retrieve() + .bodyToMono(String.class).retryWhen(retrySpec()).block().equals("after-change")); } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml index 7619a473ee..194603083c 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-configmap-polling-reload/src/test/resources/configmap.yaml @@ -5,4 +5,4 @@ metadata: namespace: default data: application.properties: | - from.yaml.key=initial + from.properties.key=initial diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/pom.xml new file mode 100644 index 0000000000..8b775e7c05 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/pom.xml @@ -0,0 +1,107 @@ + + + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 3.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-fabric8-client-secrets-event-reload + + + + + org.springframework.cloud + spring-cloud-kubernetes-fabric8-config + + + org.springframework.cloud + spring-cloud-kubernetes-test-support + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + + + com.github.docker-java + docker-java-core + test + + + com.github.docker-java + docker-java-transport-httpclient5 + test + + + + + + + + ../src/main/resources + true + + + src/main/resources + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + docker.io/springcloud/${project.artifactId}:${project.version} + paketobuildpacks/builder + + + + package + + build-image + + + + + + + + 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-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsApp.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsApp.java new file mode 100644 index 0000000000..cc49b3e4bc --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsApp.java @@ -0,0 +1,35 @@ +/* + * 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.fabric8.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-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsController.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsController.java new file mode 100644 index 0000000000..5c3d3ddac7 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsController.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2021 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.secrets.event.reload; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wind57 + */ +@RestController +public class SecretsController { + + private final SecretsProperties properties; + + public SecretsController(SecretsProperties properties) { + this.properties = properties; + } + + @GetMapping("/key") + public String key() { + return properties.getKey(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsProperties.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsProperties.java new file mode 100644 index 0000000000..c24bcb0dbf --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsProperties.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2021 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.secrets.event.reload; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author wind57 + */ +@ConfigurationProperties("from.properties") +public class SecretsProperties { + + private String key; + + public String getKey() { + return key; + } + + public void setKey(String key1) { + this.key = key1; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/resources/application.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/resources/application.yaml new file mode 100644 index 0000000000..d4b67d9cf2 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/main/resources/application.yaml @@ -0,0 +1,21 @@ +logging: + level: + root: DEBUG + +spring: + application: + name: event-reload + config: + import: "kubernetes:" + cloud: + kubernetes: + reload: + enabled: true + monitoring-secrets: true + strategy: shutdown + mode: event + secrets: + enabled: true + enable-api: true + + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java new file mode 100644 index 0000000000..1ae0a9a410 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java @@ -0,0 +1,194 @@ +/* + * 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.fabric8.secrets.event.reload; + +import java.io.InputStream; +import java.time.Duration; +import java.util.Base64; +import java.util.Map; +import java.util.Objects; + +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.SecretBuilder; +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.networking.v1.Ingress; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.DefaultKubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; +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.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.Fabric8Utils; +import org.springframework.cloud.kubernetes.integration.tests.commons.K8SUtils; +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; + +/** + * @author wind57 + */ +class SecretsEventsReloadIT { + + private static final String IMAGE_NAME = "spring-cloud-kubernetes-fabric8-client-secrets-event-reload"; + + private static final String NAMESPACE = "default"; + + private static KubernetesClient client; + + private static String deploymentName; + + private static String serviceName; + + private static String ingressName; + + private static String secretName; + + private static final K3sContainer K3S = Commons.container(); + + @BeforeAll + static void beforeAll() throws Exception { + K3S.start(); + Commons.validateImage(IMAGE_NAME, K3S); + Commons.loadSpringCloudKubernetesImage(IMAGE_NAME, K3S); + Config config = Config.fromKubeconfig(K3S.getKubeConfigYaml()); + client = new DefaultKubernetesClient(config); + Fabric8Utils.setUp(client, NAMESPACE); + deployManifests(); + } + + @AfterAll + static void after() throws Exception { + deleteManifests(); + Commons.cleanUp(IMAGE_NAME, K3S); + } + + @SuppressWarnings({ "raw", "unchecked" }) + @Test + void test() { + WebClient webClient = builder().baseUrl("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 the secret + // since we poll and have reload in place, the new property must be visible + Secret secret = new SecretBuilder() + .withMetadata(new ObjectMetaBuilder().withNamespace("default").withName("event-reload").build()) + .withData(Map.of("application.properties", + Base64.getEncoder().encodeToString("from.properties.key=after-change".getBytes()))) + .build(); + + // the weird cast comes from : + // https://github.com/fabric8io/kubernetes-client/issues/2445 + ((HasMetadataOperation) client.secrets().inNamespace("default").withName("event-reload")) + .createOrReplace(secret); + + await().timeout(Duration.ofSeconds(30)).until(() -> webClient.method(HttpMethod.GET).retrieve() + .bodyToMono(String.class).retryWhen(retrySpec()).block().equals("after-change")); + + } + + private static void deleteManifests() { + + try { + + client.secrets().inNamespace(NAMESPACE).withName(secretName).delete(); + client.apps().deployments().inNamespace(NAMESPACE).withName(deploymentName).delete(); + client.services().inNamespace(NAMESPACE).withName(serviceName).delete(); + client.network().v1().ingresses().inNamespace(NAMESPACE).withName(ingressName).delete(); + + } + catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private static void deployManifests() { + + try { + + Secret configMap = client.secrets().load(getSecret()).get(); + secretName = configMap.getMetadata().getName(); + client.secrets().create(configMap); + + Deployment deployment = client.apps().deployments().load(getDeployment()).get(); + + String version = K8SUtils.getPomVersion(); + String currentImage = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); + deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(currentImage + ":" + version); + + client.apps().deployments().inNamespace(NAMESPACE).create(deployment); + deploymentName = deployment.getMetadata().getName(); + + Service service = client.services().load(getService()).get(); + serviceName = service.getMetadata().getName(); + client.services().inNamespace(NAMESPACE).create(service); + + Ingress ingress = client.network().v1().ingresses().load(getIngress()).get(); + ingressName = ingress.getMetadata().getName(); + client.network().v1().ingresses().inNamespace(NAMESPACE).create(ingress); + + Fabric8Utils.waitForDeployment(client, + "spring-cloud-kubernetes-fabric8-client-secrets-deployment-event-reload", NAMESPACE, 2, 600); + + } + catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private static InputStream getService() { + return Fabric8Utils.inputStream("service.yaml"); + } + + private static InputStream getDeployment() { + return Fabric8Utils.inputStream("deployment.yaml"); + } + + private static InputStream getIngress() { + return Fabric8Utils.inputStream("ingress.yaml"); + } + + private static InputStream getSecret() { + return Fabric8Utils.inputStream("secret.yaml"); + } + + private WebClient.Builder builder() { + return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create())); + } + + private RetryBackoffSpec retrySpec() { + return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/deployment.yaml new file mode 100644 index 0000000000..9145122921 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-fabric8-client-secrets-deployment-event-reload +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + template: + metadata: + labels: + app: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + spec: + serviceAccountName: spring-cloud-kubernetes-serviceaccount + containers: + - name: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + image: docker.io/springcloud/spring-cloud-kubernetes-fabric8-client-secrets-event-reload + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8080 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8080 + path: /actuator/health/liveness + ports: + - containerPort: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/ingress.yaml new file mode 100644 index 0000000000..19e5d0df5c --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: spring-cloud-kubernetes-fabric8-client-secrets-ingress-event-reload + namespace: default +spec: + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + port: + number: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..9e2848765f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/secret.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/secret.yaml new file mode 100644 index 0000000000..bf3e730da4 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: event-reload + namespace: default +data: + # from.properties.key=initial + application.properties: | + ZnJvbS5wcm9wZXJ0aWVzLmtleT1pbml0aWFsCg== diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/service.yaml new file mode 100644 index 0000000000..239bc00bbb --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/resources/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + name: spring-cloud-kubernetes-fabric8-client-secrets-event-reload +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: spring-cloud-kubernetes-fabric8-client-secrets-event-reload + type: ClusterIP From 940efcc6f5a6ecb8899167d1888c3aa46d90cf72 Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 15:41:08 +0300 Subject: [PATCH 15/30] k8s native changes + tests --- ...esClientConfigReloadAutoConfiguration.java | 22 ++- ...ientEventBasedConfigMapChangeDetector.java | 6 +- ...ClientEventBasedSecretsChangeDetector.java | 1 - ...ventBasedConfigMapChangeDetectorTests.java | 17 +- ...tEventBasedSecretsChangeDetectorTests.java | 17 +- .../pom.xml | 1 + .../pom.xml | 130 ++++++++++++++ .../secrets/event/reload/SecretsApp.java | 35 ++++ .../event/reload/SecretsController.java | 39 ++++ .../event/reload/SecretsProperties.java | 37 ++++ .../src/main/resources/application.yaml | 20 +++ .../event/reload/SecretsEventReloadIT.java | 169 ++++++++++++++++++ .../src/test/resources/deployment.yaml | 28 +++ .../src/test/resources/ingress.yaml | 16 ++ .../src/test/resources/logback-test.xml | 14 ++ .../src/test/resources/secret.yaml | 9 + .../src/test/resources/service.yaml | 14 ++ .../watcher/ActuatorRefreshIT.java | 3 +- 18 files changed, 543 insertions(+), 35 deletions(-) create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/pom.xml create mode 100644 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 create mode 100644 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 create mode 100644 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 create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/resources/application.yaml create mode 100644 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 create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/ingress.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/logback-test.xml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/secret.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/service.yaml diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index e9d5a8e0c0..36d3e1babf 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -80,8 +80,8 @@ public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigR AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { return new PollingConfigMapChangeDetector(environment, properties, strategy, - KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator, - taskScheduler.getTaskScheduler()); + KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /** @@ -96,12 +96,12 @@ public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigR @Conditional(PollingReloadDetectionMode.class) public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, - AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { + KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, AbstractEnvironment environment, + TaskSchedulerWrapper taskScheduler) { return new PollingSecretsChangeDetector(environment, properties, strategy, - KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator, - taskScheduler.getTaskScheduler()); + KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /** @@ -121,10 +121,9 @@ public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigRel KubernetesNamespaceProvider kubernetesNamespaceProvider) { return new KubernetesClientEventBasedConfigMapChangeDetector(coreV1Api, environment, properties, strategy, - configMapPropertySourceLocator, kubernetesNamespaceProvider); + configMapPropertySourceLocator, kubernetesNamespaceProvider); } - /** * Event Based secrets ConfigurationChangeDetector. * @param properties config reload properties @@ -137,12 +136,11 @@ public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigRel @Conditional(EventReloadDetectionMode.class) public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, - AbstractEnvironment environment, CoreV1Api coreV1Api, - KubernetesNamespaceProvider kubernetesNamespaceProvider) { + KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, AbstractEnvironment environment, + CoreV1Api coreV1Api, KubernetesNamespaceProvider kubernetesNamespaceProvider) { return new KubernetesClientEventBasedSecretsChangeDetector(coreV1Api, environment, properties, strategy, - secretsPropertySourceLocator, kubernetesNamespaceProvider); + secretsPropertySourceLocator, kubernetesNamespaceProvider); } } 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 33ce5b9784..8e603b7fc9 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 @@ -30,7 +30,6 @@ import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator; -import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; @@ -79,9 +78,8 @@ public KubernetesClientEventBasedConfigMapChangeDetector(CoreV1Api coreV1Api, Co public void watch() { if (coreV1Api != null && monitorConfigMaps) { SharedIndexInformer configMapInformer = factory.sharedIndexInformerFor( - (CallGeneratorParams params) -> coreV1Api.listNamespacedConfigMapCall(namespace, null, null, - null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, - null), + (CallGeneratorParams params) -> coreV1Api.listNamespacedConfigMapCall(namespace, null, null, null, + null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null), V1ConfigMap.class, V1ConfigMapList.class); configMapInformer.addEventHandler(new ResourceEventHandler<>() { @Override diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java index cc155763a2..a343d7b5ac 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java @@ -29,7 +29,6 @@ import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator; -import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java index 94761c371a..4237e1178a 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java @@ -47,7 +47,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator; @@ -64,9 +63,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -147,8 +144,13 @@ void watch() { OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build(); apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); - ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.name()).thenReturn("strategy"); + + int[] howMany = new int[1]; + Runnable run = () -> { + ++howMany[0]; + }; + ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", run); + KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientConfigMapPropertySource.class)).withProperty("debug", "true"); KubernetesClientConfigMapPropertySourceLocator locator = mock( @@ -162,9 +164,8 @@ void watch() { Thread controllerThread = new Thread(changeDetector::watch); controllerThread.setDaemon(true); controllerThread.start(); - await().timeout(Duration.ofSeconds(5)) - .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)); + + await().timeout(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(2)).until(() -> howMany[0] >= 4); } // This is needed when using JDK17 because GSON uses reflection to construct an 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 e63978a74a..94bb0772d7 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 @@ -46,7 +46,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator; @@ -63,9 +62,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -142,8 +139,13 @@ void watch() { OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build(); apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); - ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.name()).thenReturn("strategy"); + + int[] howMany = new int[1]; + Runnable run = () -> { + ++howMany[0]; + }; + ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", run); + KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientSecretsPropertySource.class)).withProperty("db-password", "p455w0rd"); KubernetesClientSecretsPropertySourceLocator locator = mock(KubernetesClientSecretsPropertySourceLocator.class); @@ -160,9 +162,8 @@ void watch() { controllerThread.setDaemon(true); controllerThread.start(); - await().timeout(Duration.ofSeconds(300)) - .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)); + await().timeout(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(2)).until(() -> howMany[0] >= 4); + } // This is needed when using JDK17 because GSON uses reflection to construct an diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index d63c74daae..2dd228f113 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -116,5 +116,6 @@ spring-cloud-kubernetes-core-k8s-client-it spring-cloud-kubernetes-fabric8-client-configmap-polling-reload spring-cloud-kubernetes-fabric8-client-secrets-event-reload + spring-cloud-kubernetes-client-secrets-event-reload 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 new file mode 100644 index 0000000000..b4215801ed --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/pom.xml @@ -0,0 +1,130 @@ + + + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 3.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-client-secrets-event-reload + + + + org.springframework.cloud + spring-cloud-starter-kubernetes-client-config + + + org.springframework.cloud + spring-cloud-kubernetes-test-support + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + + + io.kubernetes + client-java + + + io.kubernetes + client-java-extended + + + com.github.docker-java + docker-java-core + test + + + com.github.docker-java + docker-java-transport-httpclient5 + test + + + + org.testcontainers + testcontainers + test + + + org.testcontainers + junit-jupiter + test + + + org.testcontainers + k3s + test + + + + + + + + ../src/main/resources + true + + + src/main/resources + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + docker.io/springcloud/${project.artifactId}:${project.version} + paketobuildpacks/builder + + + + package + + build-image + + + + + + + + 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 new file mode 100644 index 0000000000..72056a2300 --- /dev/null +++ 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 @@ -0,0 +1,35 @@ +/* + * 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/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsController.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/SecretsController.java new file mode 100644 index 0000000000..7d40247bb6 --- /dev/null +++ b/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 @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2021 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.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wind57 + */ +@RestController +public class SecretsController { + + private final SecretsProperties properties; + + public SecretsController(SecretsProperties properties) { + this.properties = properties; + } + + @GetMapping("/key") + public String key() { + return properties.getKey(); + } + +} 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-secrets-event-reload/src/main/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsProperties.java new file mode 100644 index 0000000000..712eef589a --- /dev/null +++ b/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 @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2021 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.context.properties.ConfigurationProperties; + +/** + * @author wind57 + */ +@ConfigurationProperties("from.properties") +public class SecretsProperties { + + private String key; + + public String getKey() { + return key; + } + + public void setKey(String key1) { + this.key = key1; + } + +} 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-secrets-event-reload/src/main/resources/application.yaml new file mode 100644 index 0000000000..4356bd6ac6 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/main/resources/application.yaml @@ -0,0 +1,20 @@ +logging: + level: + root: DEBUG + +spring: + application: + name: event-reload + config: + import: "kubernetes:" + cloud: + kubernetes: + reload: + enabled: true + strategy: shutdown + mode: event + monitoring-secrets: true + secrets: + enabled: true + enable-api: true + 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-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java new file mode 100644 index 0000000000..09186b3579 --- /dev/null +++ b/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 @@ -0,0 +1,169 @@ +/* + * Copyright 2013-2020 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.Map; +import java.util.Objects; + +import io.kubernetes.client.openapi.apis.AppsV1Api; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.apis.NetworkingV1Api; +import io.kubernetes.client.openapi.models.V1Deployment; +import io.kubernetes.client.openapi.models.V1Ingress; +import io.kubernetes.client.openapi.models.V1Secret; +import io.kubernetes.client.openapi.models.V1Service; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.k3s.K3sContainer; +import org.testcontainers.shaded.org.awaitility.Awaitility; +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.K8SUtils; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.cloud.kubernetes.integration.tests.commons.K8SUtils.createApiClient; +import static org.springframework.cloud.kubernetes.integration.tests.commons.K8SUtils.getPomVersion; + +/** + * @author wind57 + */ +class SecretsEventReloadIT { + + private static final String PROPERTY_URL = "localhost:80/key"; + + private static final String SPRING_CLOUD_CLIENT_CONFIG_IT_DEPLOYMENT_NAME = "spring-cloud-kubernetes-client-secrets-deployment-event-reload"; + + private static final String K8S_CONFIG_CLIENT_IT_SERVICE_NAME = "spring-cloud-kubernetes-client-secrets-event-reload"; + + private static final String NAMESPACE = "default"; + + private static CoreV1Api api; + + private static AppsV1Api appsApi; + + private static NetworkingV1Api networkingApi; + + private static K8SUtils k8SUtils; + + private static final K3sContainer K3S = Commons.container(); + + @BeforeAll + static void setup() throws Exception { + K3S.start(); + Commons.validateImage(K8S_CONFIG_CLIENT_IT_SERVICE_NAME, K3S); + Commons.loadSpringCloudKubernetesImage(K8S_CONFIG_CLIENT_IT_SERVICE_NAME, K3S); + createApiClient(K3S.getKubeConfigYaml()); + api = new CoreV1Api(); + appsApi = new AppsV1Api(); + networkingApi = new NetworkingV1Api(); + k8SUtils = new K8SUtils(api, appsApi); + k8SUtils.setUp(NAMESPACE); + } + + @AfterAll + static void afterAll() throws Exception { + Commons.cleanUp(K8S_CONFIG_CLIENT_IT_SERVICE_NAME, K3S); + } + + @AfterEach + void after() throws Exception { + appsApi.deleteCollectionNamespacedDeployment(NAMESPACE, null, null, null, + "metadata.name=" + SPRING_CLOUD_CLIENT_CONFIG_IT_DEPLOYMENT_NAME, null, null, null, null, null, null, + null, null, null); + api.deleteNamespacedService(K8S_CONFIG_CLIENT_IT_SERVICE_NAME, NAMESPACE, null, null, null, null, null, null); + networkingApi.deleteNamespacedIngress("spring-cloud-kubernetes-client-secrets-ingress-event-reload", NAMESPACE, + null, null, null, null, null, null); + api.deleteNamespacedSecret("event-reload", NAMESPACE, null, null, null, null, null, null); + } + + @Test + void testSecretReload() throws Exception { + deployConfigK8sClientIt(); + + // Check to make sure the controller deployment is ready + k8SUtils.waitForDeployment(SPRING_CLOUD_CLIENT_CONFIG_IT_DEPLOYMENT_NAME, NAMESPACE); + testSecretEventReload(); + } + + void testSecretEventReload() throws Exception { + + WebClient.Builder builder = builder(); + WebClient secretClient = builder.baseUrl(PROPERTY_URL).build(); + String secret = secretClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()) + .block(); + assertThat(secret).isEqualTo("initial"); + + V1Secret v1Secret = getConfigK8sClientItCSecret(); + Map secretData = v1Secret.getData(); + secretData.replace("application.properties", "from.properties.key: after-change".getBytes()); + v1Secret.setData(secretData); + api.replaceNamespacedSecret("event-reload", NAMESPACE, v1Secret, null, null, null); + + Awaitility.await().timeout(Duration.ofSeconds(60)).pollInterval(Duration.ofSeconds(2)) + .until(() -> secretClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) + .retryWhen(retrySpec()).block().equals("after-change")); + } + + private static void deployConfigK8sClientIt() throws Exception { + k8SUtils.waitForDeploymentToBeDeleted(SPRING_CLOUD_CLIENT_CONFIG_IT_DEPLOYMENT_NAME, NAMESPACE); + api.createNamespacedSecret(NAMESPACE, getConfigK8sClientItCSecret(), null, null, null); + appsApi.createNamespacedDeployment(NAMESPACE, getConfigK8sClientItDeployment(), null, null, null); + api.createNamespacedService(NAMESPACE, getConfigK8sClientItService(), null, null, null); + + V1Ingress ingress = getConfigK8sClientItIngress(); + networkingApi.createNamespacedIngress(NAMESPACE, ingress, null, null, null); + k8SUtils.waitForIngress(ingress.getMetadata().getName(), NAMESPACE); + } + + private static V1Deployment getConfigK8sClientItDeployment() throws Exception { + V1Deployment deployment = (V1Deployment) K8SUtils.readYamlFromClasspath("deployment.yaml"); + String image = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage() + ":" + + getPomVersion(); + deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(image); + return deployment; + } + + private static V1Service getConfigK8sClientItService() throws Exception { + return (V1Service) K8SUtils.readYamlFromClasspath("service.yaml"); + } + + private static V1Ingress getConfigK8sClientItIngress() throws Exception { + return (V1Ingress) K8SUtils.readYamlFromClasspath("ingress.yaml"); + } + + private static V1Secret getConfigK8sClientItCSecret() throws Exception { + return (V1Secret) K8SUtils.readYamlFromClasspath("secret.yaml"); + } + + 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-secrets-event-reload/src/test/resources/deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/deployment.yaml new file mode 100644 index 0000000000..74cdd1633f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-client-secrets-deployment-event-reload +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-client-secrets-event-reload + template: + metadata: + labels: + app: spring-cloud-kubernetes-client-secrets-event-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 + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8080 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8080 + path: /actuator/health/liveness + ports: + - containerPort: 8080 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 new file mode 100644 index 0000000000..7c74d61817 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/ingress.yaml @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000000..9e2848765f --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %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/secret.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/secret.yaml new file mode 100644 index 0000000000..bf3e730da4 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: event-reload + namespace: default +data: + # from.properties.key=initial + application.properties: | + ZnJvbS5wcm9wZXJ0aWVzLmtleT1pbml0aWFsCg== 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 new file mode 100644 index 0000000000..e1fb85db7b --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-client-secrets-event-reload/src/test/resources/service.yaml @@ -0,0 +1,14 @@ +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 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java index 63cddbc920..5e9af02178 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java @@ -152,8 +152,7 @@ private void deployConfigWatcher() throws Exception { private V1Deployment getConfigWatcherDeployment() throws Exception { V1Deployment deployment = (V1Deployment) K8SUtils.readYamlFromClasspath( "config-watcher/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml"); - String image = K8SUtils.getImageFromDeployment(deployment) + ":" - + getPomVersion(); + String image = K8SUtils.getImageFromDeployment(deployment) + ":" + getPomVersion(); deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(image); return deployment; } From eba2c9fbec2f2a070749831acdd6d2d5b752b17b Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 15:45:35 +0300 Subject: [PATCH 16/30] fix tests --- ...ientEventBasedConfigMapChangeDetectorTests.java | 14 +++++++++----- ...ClientEventBasedSecretsChangeDetectorTests.java | 13 ++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java index 88b0a44b31..46b0aa936b 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java @@ -147,8 +147,13 @@ void watch() { OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build(); apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); - ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.getName()).thenReturn("strategy"); + + int[] howMany = new int[1]; + Runnable run = () -> { + ++howMany[0]; + }; + ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", run); + KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientConfigMapPropertySource.class)).withProperty("debug", "true"); KubernetesClientConfigMapPropertySourceLocator locator = mock( @@ -162,9 +167,8 @@ void watch() { Thread controllerThread = new Thread(changeDetector::watch); controllerThread.setDaemon(true); controllerThread.start(); - await().timeout(Duration.ofSeconds(5)) - .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)).reload(); + + await().timeout(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(2)).until(() -> howMany[0] >= 4); } // This is needed when using JDK17 because GSON uses reflection to construct an 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 4c438e89a7..270466c01f 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 @@ -142,8 +142,13 @@ void watch() { OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build(); apiClient.setHttpClient(httpClient); CoreV1Api coreV1Api = new CoreV1Api(apiClient); - ConfigurationUpdateStrategy strategy = mock(ConfigurationUpdateStrategy.class); - when(strategy.getName()).thenReturn("strategy"); + + int[] howMany = new int[1]; + Runnable run = () -> { + ++howMany[0]; + }; + ConfigurationUpdateStrategy strategy = new ConfigurationUpdateStrategy("strategy", run); + KubernetesMockEnvironment environment = new KubernetesMockEnvironment( mock(KubernetesClientSecretsPropertySource.class)).withProperty("db-password", "p455w0rd"); KubernetesClientSecretsPropertySourceLocator locator = mock(KubernetesClientSecretsPropertySourceLocator.class); @@ -160,9 +165,7 @@ void watch() { controllerThread.setDaemon(true); controllerThread.start(); - await().timeout(Duration.ofSeconds(300)) - .until(() -> Mockito.mockingDetails(strategy).getInvocations().size() > 4); - verify(strategy, atLeast(3)).reload(); + await().timeout(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(2)).until(() -> howMany[0] >= 4); } // This is needed when using JDK17 because GSON uses reflection to construct an From af8dc0035ba62bf265bbaad0bab5cf35e42bbace Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 15:56:00 +0300 Subject: [PATCH 17/30] fix tests take 2 --- ...etesClientEventBasedConfigMapChangeDetectorTests.java | 9 +++------ ...rnetesClientEventBasedSecretsChangeDetectorTests.java | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java index 46b0aa936b..798e0909f3 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetectorTests.java @@ -20,8 +20,8 @@ import java.lang.reflect.Modifier; import java.time.Duration; import java.time.OffsetDateTime; -import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -47,7 +47,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator; @@ -64,9 +63,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -110,7 +107,7 @@ void watch() { V1ConfigMap applicationConfig = new V1ConfigMap().kind("ConfigMap") .metadata(new V1ObjectMeta().namespace("default").name("bar1")).data(data); V1ConfigMapList configMapList = new V1ConfigMapList().metadata(new V1ListMeta().resourceVersion("0")) - .items(Arrays.asList(applicationConfig)); + .items(List.of(applicationConfig)); stubFor(get(urlMatching("^/api/v1/namespaces/default/configmaps.*")).inScenario("watch") .whenScenarioStateIs(STARTED).withQueryParam("watch", equalTo("false")) .willReturn(aResponse().withStatus(200).withBody(gson.toJson(configMapList))).willSetStateTo("update")); @@ -174,7 +171,7 @@ void watch() { // This is needed when using JDK17 because GSON uses reflection to construct an // OffsetDateTime but that constructor // is protected. - public class GsonOffsetDateTimeAdapter extends TypeAdapter { + public final static class GsonOffsetDateTimeAdapter extends TypeAdapter { @Override public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IOException { 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 270466c01f..d72264aab3 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 @@ -20,8 +20,8 @@ import java.lang.reflect.Modifier; import java.time.Duration; import java.time.OffsetDateTime; -import java.util.Arrays; import java.util.Base64; +import java.util.List; import java.util.concurrent.TimeUnit; import com.github.tomakehurst.wiremock.WireMockServer; @@ -46,7 +46,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator; @@ -63,9 +62,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static org.awaitility.Awaitility.await; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -107,7 +104,7 @@ void watch() { .putStringDataItem("password", Base64.getEncoder().encodeToString("p455w0rd2".getBytes())) .putStringDataItem("username", Base64.getEncoder().encodeToString("user".getBytes())); V1SecretList secretList = new V1SecretList().kind("SecretList").metadata(new V1ListMeta().resourceVersion("0")) - .items(Arrays.asList(dbPassword)); + .items(List.of(dbPassword)); stubFor(get(urlMatching("^/api/v1/namespaces/default/secrets.*")).inScenario("watch") .whenScenarioStateIs(STARTED).withQueryParam("watch", equalTo("false")) @@ -171,7 +168,7 @@ void watch() { // This is needed when using JDK17 because GSON uses reflection to construct an // OffsetDateTime but that constructor // is protected. - public class GsonOffsetDateTimeAdapter extends TypeAdapter { + public final static class GsonOffsetDateTimeAdapter extends TypeAdapter { @Override public void write(JsonWriter jsonWriter, OffsetDateTime localDateTime) throws IOException { From d7164dc626beaa5040715e19e630d099e84487d6 Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 16:34:05 +0300 Subject: [PATCH 18/30] fix tests take 3 --- .../config/EventBasedConfigurationChangeDetectorTests.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java index 7db69d96c7..d7c152716e 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EventBasedConfigurationChangeDetectorTests.java @@ -74,7 +74,9 @@ void verifyConfigChangesAccountsForBootstrapPropertySources() { Fabric8ConfigMapPropertySource fabric8ConfigMapPropertySource = new Fabric8ConfigMapPropertySource(context); env.getPropertySources().addFirst(new BootstrapPropertySource<>(fabric8ConfigMapPropertySource)); - ConfigurationUpdateStrategy configurationUpdateStrategy = mock(ConfigurationUpdateStrategy.class); + ConfigurationUpdateStrategy configurationUpdateStrategy = new ConfigurationUpdateStrategy("strategy", () -> { + + }); Fabric8ConfigMapPropertySourceLocator configMapLocator = mock(Fabric8ConfigMapPropertySourceLocator.class); EventBasedConfigMapChangeDetector detector = new EventBasedConfigMapChangeDetector(env, configReloadProperties, k8sClient, configurationUpdateStrategy, configMapLocator); From 66b1e6a6d7e64cc4bc79df66713e8bf9f50390c0 Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 18:14:19 +0300 Subject: [PATCH 19/30] fix tests take 4 --- .../ConfigMapWatcherChangeDetector.java | 2 +- ...edConfigMapWatcherChangeDetectorTests.java | 28 ++++++++-------- ...asedSecretsWatcherChangeDetectorTests.java | 32 +++++++++---------- ...onWatcherConfigurationPropertiesTests.java | 6 ++-- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java index 02d6ffb080..c5a575feb4 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigMapWatcherChangeDetector.java @@ -41,7 +41,7 @@ public abstract class ConfigMapWatcherChangeDetector extends EventBasedConfigMap protected Log log = LogFactory.getLog(getClass()); - private ScheduledExecutorService executorService; + private final ScheduledExecutorService executorService; protected ConfigurationWatcherConfigurationProperties k8SConfigurationProperties; diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigMapWatcherChangeDetectorTests.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigMapWatcherChangeDetectorTests.java index e630f42abc..52d82a6b10 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigMapWatcherChangeDetectorTests.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigMapWatcherChangeDetectorTests.java @@ -19,12 +19,12 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.KubernetesClient; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.bus.BusProperties; import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent; @@ -42,14 +42,16 @@ * @author Ryan Baxter * @author Kris Iyer */ -@RunWith(MockitoJUnitRunner.class) -public class BusEventBasedConfigMapWatcherChangeDetectorTests { +@ExtendWith(MockitoExtension.class) +class BusEventBasedConfigMapWatcherChangeDetectorTests { - @Mock - private KubernetesClient client; + private static final ConfigurationUpdateStrategy UPDATE_STRATEGY = new ConfigurationUpdateStrategy("strategy", + () -> { + + }); @Mock - private ConfigurationUpdateStrategy updateStrategy; + private KubernetesClient client; @Mock private Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator; @@ -64,20 +66,20 @@ public class BusEventBasedConfigMapWatcherChangeDetectorTests { private BusProperties busProperties; - @Before - public void setup() { + @BeforeEach + void setup() { MockEnvironment mockEnvironment = new MockEnvironment(); ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(); ConfigurationWatcherConfigurationProperties configurationWatcherConfigurationProperties = new ConfigurationWatcherConfigurationProperties(); busProperties = new BusProperties(); changeDetector = new BusEventBasedConfigMapWatcherChangeDetector(mockEnvironment, configReloadProperties, - client, updateStrategy, fabric8ConfigMapPropertySourceLocator, busProperties, + client, UPDATE_STRATEGY, fabric8ConfigMapPropertySourceLocator, busProperties, configurationWatcherConfigurationProperties, threadPoolTaskExecutor); changeDetector.setApplicationEventPublisher(applicationEventPublisher); } @Test - public void triggerRefreshWithConfigMap() { + void triggerRefreshWithConfigMap() { ObjectMeta objectMeta = new ObjectMeta(); objectMeta.setName("foo"); ConfigMap configMap = new ConfigMap(); diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedSecretsWatcherChangeDetectorTests.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedSecretsWatcherChangeDetectorTests.java index 109ecb3094..c7a6adb0bc 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedSecretsWatcherChangeDetectorTests.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedSecretsWatcherChangeDetectorTests.java @@ -19,12 +19,12 @@ import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.client.KubernetesClient; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.bus.BusProperties; import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent; @@ -42,14 +42,16 @@ * @author Ryan Baxter * @author Kris Iyer */ -@RunWith(MockitoJUnitRunner.class) -public class BusEventBasedSecretsWatcherChangeDetectorTests { +@ExtendWith(MockitoExtension.class) +class BusEventBasedSecretsWatcherChangeDetectorTests { - @Mock - private KubernetesClient client; + private static final ConfigurationUpdateStrategy UPDATE_STRATEGY = new ConfigurationUpdateStrategy("strategy", + () -> { + + }); @Mock - private ConfigurationUpdateStrategy updateStrategy; + private KubernetesClient client; @Mock private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator; @@ -62,24 +64,22 @@ public class BusEventBasedSecretsWatcherChangeDetectorTests { private BusEventBasedSecretsWatcherChangeDetector changeDetector; - private ConfigurationWatcherConfigurationProperties configurationWatcherConfigurationProperties; - private BusProperties busProperties; - @Before - public void setup() { + @BeforeEach + void setup() { MockEnvironment mockEnvironment = new MockEnvironment(); ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(); - configurationWatcherConfigurationProperties = new ConfigurationWatcherConfigurationProperties(); + ConfigurationWatcherConfigurationProperties configurationWatcherConfigurationProperties = new ConfigurationWatcherConfigurationProperties(); busProperties = new BusProperties(); changeDetector = new BusEventBasedSecretsWatcherChangeDetector(mockEnvironment, configReloadProperties, client, - updateStrategy, fabric8SecretsPropertySourceLocator, busProperties, + UPDATE_STRATEGY, fabric8SecretsPropertySourceLocator, busProperties, configurationWatcherConfigurationProperties, threadPoolTaskExecutor); changeDetector.setApplicationEventPublisher(applicationEventPublisher); } @Test - public void triggerRefreshWithSecret() { + void triggerRefreshWithSecret() { ObjectMeta objectMeta = new ObjectMeta(); objectMeta.setName("foo"); Secret secret = new Secret(); diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java index 9c08860cb6..04ae6c32fe 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java @@ -16,17 +16,17 @@ package org.springframework.cloud.kubernetes.configuration.watcher; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; /** * @author Ryan Baxter */ -public class ConfigurationWatcherConfigurationPropertiesTests { +class ConfigurationWatcherConfigurationPropertiesTests { @Test - public void setActuatorPath() { + void setActuatorPath() { ConfigurationWatcherConfigurationProperties properties = new ConfigurationWatcherConfigurationProperties(); properties.setActuatorPath("foo"); assertThat(properties.getActuatorPath()).isEqualTo("/foo"); From db6043c1cacddbeecf9f82a74f9de59956710aa9 Mon Sep 17 00:00:00 2001 From: wind57 Date: Thu, 16 Jun 2022 22:48:11 +0300 Subject: [PATCH 20/30] fix test --- .../KubernetesClientConfigReloadAutoConfiguration.java | 4 +++- .../config/reload/Fabric8ConfigReloadAutoConfiguration.java | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index eb1f9e3398..368010ad45 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -47,6 +47,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.core.env.AbstractEnvironment; /** @@ -56,7 +57,8 @@ @ConditionalOnKubernetesAndConfigEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, ConfigReloadAutoConfiguration.class }) + RefreshAutoConfiguration.class }) +@Import(ConfigReloadAutoConfiguration.class) @EnableConfigurationProperties(ConfigReloadProperties.class) public class KubernetesClientConfigReloadAutoConfiguration { diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java index d2fffcb7b9..37f1b4889c 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -46,6 +46,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.core.env.AbstractEnvironment; import org.springframework.scheduling.TaskScheduler; @@ -59,10 +60,10 @@ @ConditionalOnKubernetesAndConfigEnabled @ConditionalOnClass(EndpointAutoConfiguration.class) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class, - ConfigReloadAutoConfiguration.class }) + RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") +@Import(ConfigReloadAutoConfiguration.class) public class Fabric8ConfigReloadAutoConfiguration { /** From 63d34d927f85efa2c2e2bb3410a122220792e02d Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 11:38:54 +0300 Subject: [PATCH 21/30] started merging --- .../config/reload/ConfigReloadAutoConfiguration.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index 13b5623ecc..c9dea5e321 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; import org.springframework.beans.factory.annotation.Autowired; @@ -44,9 +45,9 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled @ConditionalOnKubernetesReloadEnabled -@ConditionalOnClass(EndpointAutoConfiguration.class) +@ConditionalOnClass({ EndpointAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) + RefreshAutoConfiguration.class }) public class ConfigReloadAutoConfiguration { @Bean("springCloudKubernetesTaskScheduler") @@ -63,15 +64,15 @@ public TaskSchedulerWrapper taskScheduler() { @Bean @ConditionalOnMissingBean public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, - ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter, + ConfigurableApplicationContext ctx, Optional restarter, ContextRefresher refresher) { String strategyName = properties.getStrategy().name(); switch (properties.getStrategy()) { case RESTART_CONTEXT: - Objects.requireNonNull(restarter, "Restart endpoint is not enabled"); + restarter.orElseThrow(() -> new AssertionError("Restart endpoint is not enabled")); return new ConfigurationUpdateStrategy(strategyName, () -> { wait(properties); - restarter.restart(); + restarter.get().restart(); }); case REFRESH: return new ConfigurationUpdateStrategy(strategyName, refresher::refresh); From 69af4b12c9b506f9ee971505a2253f0ab5cb5daf Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 11:46:14 +0300 Subject: [PATCH 22/30] fabric8 polish --- .../Fabric8ConfigReloadAutoConfiguration.java | 18 ++---------------- ...bric8EventBasedConfigMapChangeDetector.java | 4 ++-- ...Fabric8EventBasedSecretsChangeDetector.java | 4 ++-- 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java index 535260e3b0..cc4fe011ff 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -27,10 +27,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -<<<<<<< HEAD -======= -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; ->>>>>>> main import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; @@ -44,10 +40,7 @@ import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector; import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector; -<<<<<<< HEAD import org.springframework.cloud.kubernetes.commons.config.reload.condition.ConditionalOnKubernetesReloadEnabled; -======= ->>>>>>> main import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode; import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode; import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource; @@ -69,18 +62,11 @@ */ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled -<<<<<<< HEAD @ConditionalOnKubernetesReloadEnabled -======= ->>>>>>> main -@ConditionalOnClass(EndpointAutoConfiguration.class) +@ConditionalOnClass({ EndpointAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) + RefreshAutoConfiguration.class }) @EnableConfigurationProperties(ConfigReloadProperties.class) -<<<<<<< HEAD -======= -@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") ->>>>>>> main @Import(ConfigReloadAutoConfiguration.class) public class Fabric8ConfigReloadAutoConfiguration { 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 5b594c6d76..a69eb9c20b 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 @@ -49,8 +49,8 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang private SharedIndexInformer informer; public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, - KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { + KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, + Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { super(environment, properties, strategy); this.kubernetesClient = kubernetesClient; this.fabric8ConfigMapPropertySourceLocator = fabric8ConfigMapPropertySourceLocator; 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 e601a5818a..b3b4d6041e 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 @@ -49,8 +49,8 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD private SharedIndexInformer informer; public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, - KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { + KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, + Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { super(environment, properties, strategy); this.kubernetesClient = kubernetesClient; this.fabric8SecretsPropertySourceLocator = fabric8SecretsPropertySourceLocator; From 83a60bebf745ca38d0d78754a9aa3ae346ecd83e Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 11:47:09 +0300 Subject: [PATCH 23/30] license --- .../config/reload/Fabric8ConfigReloadAutoConfiguration.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java index cc4fe011ff..7297f22e8c 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/Fabric8ConfigReloadAutoConfiguration.java @@ -1,9 +1,5 @@ /* -<<<<<<< HEAD * Copyright 2013-2022 the original author or authors. -======= - * Copyright 2013-2019 the original author or authors. ->>>>>>> main * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 8410306806dc64ae9a929e1275e4dfa3f0678f76 Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 12:01:31 +0300 Subject: [PATCH 24/30] log added --- .../config/reload/Fabric8EventBasedConfigMapChangeDetector.java | 1 + .../config/reload/Fabric8EventBasedSecretsChangeDetector.java | 1 + 2 files changed, 2 insertions(+) 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 a69eb9c20b..7f0e8001fa 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 @@ -60,6 +60,7 @@ public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, @PostConstruct private void inform() { if (monitoringConfigMaps) { + log.info("Kubernetes event-based configMap change detector activated"); informer = kubernetesClient.configMaps().inform(); informer.addEventHandler(new ResourceEventHandler<>() { @Override 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 b3b4d6041e..14f84ca864 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 @@ -71,6 +71,7 @@ private void shutdown() { @PostConstruct private void inform() { if (monitorSecrets) { + log.info("Kubernetes event-based secrets change detector activated"); informer = kubernetesClient.secrets().inform(); informer.addEventHandler(new ResourceEventHandler<>() { @Override From 8f919c978819ff8f1b7b0d714b346a6fd78d0bf4 Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 12:44:02 +0300 Subject: [PATCH 25/30] inform --- .../reload/Fabric8EventBasedConfigMapChangeDetector.java | 9 +++++++++ .../reload/Fabric8EventBasedSecretsChangeDetector.java | 9 +++++++++ 2 files changed, 18 insertions(+) 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 7f0e8001fa..b08ec1e5af 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 @@ -77,6 +77,15 @@ public void onUpdate(ConfigMap oldConfigMap, ConfigMap newConfigMap) { public void onDelete(ConfigMap configMap, boolean deletedFinalStateUnknown) { onEvent(configMap); } + + @Override + public void onNothing() { + boolean isStoreEmpty = informer.getStore().list().isEmpty(); + if(!isStoreEmpty) { + // HTTP_GONE, thus re-inform + inform(); + } + } }); } } 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 14f84ca864..ff8cf2e521 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 @@ -88,6 +88,15 @@ public void onUpdate(Secret oldSecret, Secret newSecret) { public void onDelete(Secret secret, boolean deletedFinalStateUnknown) { onEvent(secret); } + + @Override + public void onNothing() { + boolean isStoreEmpty = informer.getStore().list().isEmpty(); + if(!isStoreEmpty) { + // HTTP_GONE, thus re-inform + inform(); + } + } }); } } From 61507aa9fa9ae85d8f6f0d5400dab0659db16e1e Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 13:22:22 +0300 Subject: [PATCH 26/30] informers commented --- ...abric8EventBasedConfigMapChangeDetector.java | 17 +++++++++-------- .../Fabric8EventBasedSecretsChangeDetector.java | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) 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 b08ec1e5af..91584602b4 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 @@ -78,14 +78,15 @@ public void onDelete(ConfigMap configMap, boolean deletedFinalStateUnknown) { onEvent(configMap); } - @Override - public void onNothing() { - boolean isStoreEmpty = informer.getStore().list().isEmpty(); - if(!isStoreEmpty) { - // HTTP_GONE, thus re-inform - inform(); - } - } +// leave as comment on purpose, may be this will be useful in the future +// @Override +// public void onNothing() { +// boolean isStoreEmpty = informer.getStore().list().isEmpty(); +// if(!isStoreEmpty) { +// // HTTP_GONE, thus re-inform +// inform(); +// } +// } }); } } 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 ff8cf2e521..2f83d69c44 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 @@ -89,14 +89,15 @@ public void onDelete(Secret secret, boolean deletedFinalStateUnknown) { onEvent(secret); } - @Override - public void onNothing() { - boolean isStoreEmpty = informer.getStore().list().isEmpty(); - if(!isStoreEmpty) { - // HTTP_GONE, thus re-inform - inform(); - } - } +// leave as comment on purpose, may be this will be useful in the future +// @Override +// public void onNothing() { +// boolean isStoreEmpty = informer.getStore().list().isEmpty(); +// if(!isStoreEmpty) { +// // HTTP_GONE, thus re-inform +// inform(); +// } +// } }); } } From 4a47895ba67bd6518f78108c187cac7ea01c9d0e Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 13:28:17 +0300 Subject: [PATCH 27/30] k8s native --- ...netesClientConfigReloadAutoConfiguration.java | 7 +------ ...sClientEventBasedConfigMapChangeDetector.java | 16 ++++++---------- ...tesClientEventBasedSecretsChangeDetector.java | 14 +++++--------- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index 4516be2f07..896defdceb 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -57,14 +57,9 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnKubernetesAndConfigEnabled @ConditionalOnKubernetesReloadEnabled -@ConditionalOnClass(EndpointAutoConfiguration.class) +@ConditionalOnClass({ EndpointAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) @AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class, -<<<<<<< HEAD - RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class }) -======= RefreshAutoConfiguration.class }) -@Import(ConfigReloadAutoConfiguration.class) ->>>>>>> main @EnableConfigurationProperties(ConfigReloadProperties.class) @Import(ConfigReloadAutoConfiguration.class) public class KubernetesClientConfigReloadAutoConfiguration { 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 8e603b7fc9..6df2af1d91 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 @@ -25,8 +25,6 @@ import io.kubernetes.client.util.CallGeneratorParams; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator; @@ -43,8 +41,6 @@ */ public class KubernetesClientEventBasedConfigMapChangeDetector extends ConfigurationChangeDetector { - private static final Log LOG = LogFactory.getLog(KubernetesClientEventBasedConfigMapChangeDetector.class); - private final CoreV1Api coreV1Api; private final KubernetesClientConfigMapPropertySourceLocator propertySourceLocator; @@ -84,19 +80,19 @@ public void watch() { configMapInformer.addEventHandler(new ResourceEventHandler<>() { @Override public void onAdd(V1ConfigMap obj) { - LOG.info("ConfigMap " + obj.getMetadata().getName() + " was added."); + log.info("ConfigMap " + obj.getMetadata().getName() + " was added."); onEvent(obj); } @Override public void onUpdate(V1ConfigMap oldObj, V1ConfigMap newObj) { - LOG.info("ConfigMap " + newObj.getMetadata().getName() + " was added."); + log.info("ConfigMap " + newObj.getMetadata().getName() + " was added."); onEvent(newObj); } @Override public void onDelete(V1ConfigMap obj, boolean deletedFinalStateUnknown) { - LOG.info("ConfigMap " + obj.getMetadata() + " was deleted."); + log.info("ConfigMap " + obj.getMetadata() + " was deleted."); onEvent(obj); } }); @@ -110,15 +106,15 @@ public void unwatch() { } private void onEvent(V1ConfigMap configMap) { - LOG.debug("onEvent configMap: " + configMap.toString()); + log.debug("onEvent configMap: " + configMap.toString()); boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment), findPropertySources(KubernetesClientConfigMapPropertySource.class)); if (changed) { - LOG.info("Configuration change detected, reloading properties."); + log.info("Configuration change detected, reloading properties."); reloadProperties(); } else { - LOG.warn("Configuration change was not detected."); + log.warn("Configuration change was not detected."); } } diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java index a343d7b5ac..213660ad92 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java @@ -24,8 +24,6 @@ import io.kubernetes.client.openapi.models.V1SecretList; import io.kubernetes.client.util.CallGeneratorParams; import jakarta.annotation.PostConstruct; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource; import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator; @@ -42,8 +40,6 @@ */ public class KubernetesClientEventBasedSecretsChangeDetector extends ConfigurationChangeDetector { - private static final Log LOG = LogFactory.getLog(KubernetesClientEventBasedSecretsChangeDetector.class); - private final CoreV1Api coreV1Api; private final KubernetesClientSecretsPropertySourceLocator propertySourceLocator; @@ -83,19 +79,19 @@ public void watch() { configMapInformer.addEventHandler(new ResourceEventHandler<>() { @Override public void onAdd(V1Secret obj) { - LOG.info("Secret " + obj.getMetadata().getName() + " was added."); + log.info("Secret " + obj.getMetadata().getName() + " was added."); onEvent(obj); } @Override public void onUpdate(V1Secret oldObj, V1Secret newObj) { - LOG.info("Secret " + newObj.getMetadata().getName() + " was added."); + log.info("Secret " + newObj.getMetadata().getName() + " was added."); onEvent(newObj); } @Override public void onDelete(V1Secret obj, boolean deletedFinalStateUnknown) { - LOG.info("Secret " + obj.getMetadata() + " was deleted."); + log.info("Secret " + obj.getMetadata() + " was deleted."); onEvent(obj); } }); @@ -104,11 +100,11 @@ public void onDelete(V1Secret obj, boolean deletedFinalStateUnknown) { } private void onEvent(V1Secret secret) { - LOG.debug("onEvent configMap: " + secret.toString()); + log.debug("onEvent configMap: " + secret.toString()); boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment), findPropertySources(KubernetesClientSecretsPropertySource.class)); if (changed) { - LOG.info("Detected change in secrets"); + log.info("Detected change in secrets"); reloadProperties(); } } From 7886338be06826fba46339fe7f5fddabd3507b61 Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 15:18:20 +0300 Subject: [PATCH 28/30] more --- .../reload/ConfigReloadAutoConfiguration.java | 5 +---- ...ric8EventBasedConfigMapChangeDetector.java | 20 +++++++++---------- ...abric8EventBasedSecretsChangeDetector.java | 20 +++++++++---------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index c9dea5e321..856119eb34 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -16,11 +16,9 @@ package org.springframework.cloud.kubernetes.commons.config.reload; -import java.util.Objects; import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -64,8 +62,7 @@ public TaskSchedulerWrapper taskScheduler() { @Bean @ConditionalOnMissingBean public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties, - ConfigurableApplicationContext ctx, Optional restarter, - ContextRefresher refresher) { + ConfigurableApplicationContext ctx, Optional restarter, ContextRefresher refresher) { String strategyName = properties.getStrategy().name(); switch (properties.getStrategy()) { case RESTART_CONTEXT: 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 91584602b4..be4843fd7d 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 @@ -78,15 +78,15 @@ public void onDelete(ConfigMap configMap, boolean deletedFinalStateUnknown) { onEvent(configMap); } -// leave as comment on purpose, may be this will be useful in the future -// @Override -// public void onNothing() { -// boolean isStoreEmpty = informer.getStore().list().isEmpty(); -// if(!isStoreEmpty) { -// // HTTP_GONE, thus re-inform -// inform(); -// } -// } + // leave as comment on purpose, may be this will be useful in the future + // @Override + // public void onNothing() { + // boolean isStoreEmpty = informer.getStore().list().isEmpty(); + // if(!isStoreEmpty) { + // // HTTP_GONE, thus re-inform + // inform(); + // } + // } }); } } @@ -105,7 +105,7 @@ private void shutdown() { protected void onEvent(ConfigMap configMap) { log.debug("onEvent configMap: " + configMap.toString()); boolean changed = changed(locateMapPropertySources(fabric8ConfigMapPropertySourceLocator, environment), - findPropertySources(Fabric8ConfigMapPropertySource.class)); + findPropertySources(Fabric8ConfigMapPropertySource.class)); if (changed) { log.info("Detected change in config maps"); reloadProperties(); 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 2f83d69c44..0147314e86 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 @@ -89,15 +89,15 @@ public void onDelete(Secret secret, boolean deletedFinalStateUnknown) { onEvent(secret); } -// leave as comment on purpose, may be this will be useful in the future -// @Override -// public void onNothing() { -// boolean isStoreEmpty = informer.getStore().list().isEmpty(); -// if(!isStoreEmpty) { -// // HTTP_GONE, thus re-inform -// inform(); -// } -// } + // leave as comment on purpose, may be this will be useful in the future + // @Override + // public void onNothing() { + // boolean isStoreEmpty = informer.getStore().list().isEmpty(); + // if(!isStoreEmpty) { + // // HTTP_GONE, thus re-inform + // inform(); + // } + // } }); } } @@ -105,7 +105,7 @@ public void onDelete(Secret secret, boolean deletedFinalStateUnknown) { protected void onEvent(Secret secret) { log.debug("onEvent secrets: " + secret.toString()); boolean changed = changed(locateMapPropertySources(fabric8SecretsPropertySourceLocator, environment), - findPropertySources(Fabric8SecretsPropertySource.class)); + findPropertySources(Fabric8SecretsPropertySource.class)); if (changed) { log.info("Detected change in secrets"); reloadProperties(); From eaf5938698b79a6341b48e6ef8f5d6632fc8e8af Mon Sep 17 00:00:00 2001 From: wind57 Date: Mon, 4 Jul 2022 16:45:03 +0300 Subject: [PATCH 29/30] 2 minutes --- .../client/secrets/event/reload/SecretsEventReloadIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java index 09186b3579..a1b32bb58a 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-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/client/secrets/event/reload/SecretsEventReloadIT.java @@ -122,7 +122,7 @@ void testSecretEventReload() throws Exception { v1Secret.setData(secretData); api.replaceNamespacedSecret("event-reload", NAMESPACE, v1Secret, null, null, null); - Awaitility.await().timeout(Duration.ofSeconds(60)).pollInterval(Duration.ofSeconds(2)) + Awaitility.await().timeout(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)) .until(() -> secretClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class) .retryWhen(retrySpec()).block().equals("after-change")); } From 0ffbb3de28c04e8fb11bccae4e0c97a7bb84dbb9 Mon Sep 17 00:00:00 2001 From: wind57 Date: Wed, 6 Jul 2022 09:52:27 +0300 Subject: [PATCH 30/30] give more time --- .../fabric8/secrets/event/reload/SecretsEventsReloadIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java index 1ae0a9a410..6a84b0dfb5 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-secrets-event-reload/src/test/java/org/springframework/cloud/kubernetes/fabric8/secrets/event/reload/SecretsEventsReloadIT.java @@ -111,7 +111,7 @@ void test() { ((HasMetadataOperation) client.secrets().inNamespace("default").withName("event-reload")) .createOrReplace(secret); - await().timeout(Duration.ofSeconds(30)).until(() -> webClient.method(HttpMethod.GET).retrieve() + await().timeout(Duration.ofSeconds(120)).until(() -> webClient.method(HttpMethod.GET).retrieve() .bodyToMono(String.class).retryWhen(retrySpec()).block().equals("after-change")); } @@ -188,7 +188,7 @@ private WebClient.Builder builder() { } private RetryBackoffSpec retrySpec() { - return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull); + return Retry.fixedDelay(120, Duration.ofSeconds(1)).filter(Objects::nonNull); } }