From 4c754f8d9a78af0030afdcf8d2ee7b16ca436ae3 Mon Sep 17 00:00:00 2001 From: piomin Date: Sun, 7 Jun 2020 14:14:22 +0200 Subject: [PATCH 01/30] Fixing Junit tests. For spring-cloud-kubernetes-leader adding support for Junit5, for spring-cloud-kubernetes examples adding junit-vintage-engine since Arquillian Cube does not support JUnit5 --- .../pom.xml | 8 +++++ .../examples/LeaderControllerTest.java | 12 +++---- .../discovery/tests/pom.xml | 6 ++++ .../simple-configmap/pom.xml | 6 ++++ .../simple-core/pom.xml | 6 ++++ spring-cloud-kubernetes-leader/pom.xml | 14 ++++++-- .../leader/LeaderAutoConfigurationTests.java | 8 ++--- .../kubernetes/leader/LeaderContextTest.java | 12 +++---- .../leader/LeaderInfoContributorTest.java | 12 +++---- .../leader/LeaderInitiatorTest.java | 16 ++++----- .../leader/LeaderRecordWatcherTest.java | 33 +++++++++++-------- .../cloud/kubernetes/leader/LeaderTest.java | 12 +++---- .../leader/LeadershipControllerTest.java | 12 +++---- .../leader/PodReadinessWatcherTest.java | 27 +++++++++------ 14 files changed, 116 insertions(+), 68 deletions(-) diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index 9e05eb53..bfc041c0 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -78,6 +78,14 @@ true + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java index fa8c4266..686cbcf2 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/src/test/java/org/springframework/cloud/kubernetes/examples/LeaderControllerTest.java @@ -19,11 +19,11 @@ package org.springframework.cloud.kubernetes.examples; import java.net.InetAddress; import java.net.UnknownHostException; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -36,7 +36,7 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderControllerTest { @Mock @@ -52,7 +52,7 @@ public class LeaderControllerTest { private LeaderController leaderController; - @Before + @BeforeEach public void before() throws UnknownHostException { this.host = InetAddress.getLocalHost().getHostName(); this.leaderController = new LeaderController(); diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index 5987eb4b..5fa02dc8 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -19,6 +19,12 @@ spring-boot-starter-test test + + org.junit.vintage + junit-vintage-engine + 5.6.2 + test + org.arquillian.cube arquillian-cube-kubernetes diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index b7caa713..4af81d26 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -36,6 +36,12 @@ spring-boot-starter-test test + + org.junit.vintage + junit-vintage-engine + 5.6.2 + test + org.arquillian.cube arquillian-cube-kubernetes diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 77da694b..5f3982b1 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -36,6 +36,12 @@ spring-boot-starter-test test + + org.junit.vintage + junit-vintage-engine + 5.6.2 + test + org.arquillian.cube arquillian-cube-kubernetes diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 9cd05253..4993a376 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -61,14 +61,24 @@ org.springframework.boot spring-boot-starter-test test + + + org.junit.vintage + junit-vintage-engine + + + - org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + maven-failsafe-plugin - ${maven-failsafe-plugin.version} + 2.22.2 diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java index 0072a811..fee60341 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderAutoConfigurationTests.java @@ -16,8 +16,9 @@ package org.springframework.cloud.kubernetes.leader; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -25,12 +26,11 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; import static org.hamcrest.Matchers.containsString; -@RunWith(SpringRunner.class) +@ExtendWith(MockitoExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { // Make sure test passes without Kubernetes cluster "spring.cloud.kubernetes.leader.autoStartup=false" }) diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java index 7681d91b..cb291fed 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderContextTest.java @@ -18,11 +18,11 @@ package org.springframework.cloud.kubernetes.leader; import java.util.Optional; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.integration.leader.Candidate; @@ -33,7 +33,7 @@ import static org.mockito.Mockito.verify; /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderContextTest { @Mock @@ -47,7 +47,7 @@ public class LeaderContextTest { private LeaderContext leaderContext; - @Before + @BeforeEach public void before() { this.leaderContext = new LeaderContext(this.mockCandidate, this.mockLeadershipController); diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInfoContributorTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInfoContributorTest.java index abb04c3e..97de1bb3 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInfoContributorTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInfoContributorTest.java @@ -19,11 +19,11 @@ package org.springframework.cloud.kubernetes.leader; import java.util.Map; import java.util.Optional; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.boot.actuate.info.Info; import org.springframework.integration.leader.Candidate; @@ -31,7 +31,7 @@ import org.springframework.integration.leader.Candidate; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderInfoContributorTest { @Mock @@ -45,7 +45,7 @@ public class LeaderInfoContributorTest { private LeaderInfoContributor leaderInfoContributor; - @Before + @BeforeEach public void before() { this.leaderInfoContributor = new LeaderInfoContributor( this.mockLeadershipController, this.mockCandidate); diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java index 92e05f9b..844e66b2 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderInitiatorTest.java @@ -18,12 +18,12 @@ package org.springframework.cloud.kubernetes.leader; import java.time.Duration; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -33,7 +33,7 @@ import static org.mockito.internal.verification.VerificationModeFactory.atLeastO /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderInitiatorTest { @Mock @@ -53,14 +53,14 @@ public class LeaderInitiatorTest { private LeaderInitiator leaderInitiator; - @Before + @BeforeEach public void before() { this.leaderInitiator = new LeaderInitiator(this.mockLeaderProperties, this.mockLeadershipController, this.mockLeaderRecordWatcher, this.mockPodReadinessWatcher); } - @After + @AfterEach public void after() { this.leaderInitiator.stop(); } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java index 59cfead8..a609ee43 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderRecordWatcherTest.java @@ -26,11 +26,11 @@ import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.Resource; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; @@ -39,7 +39,7 @@ import static org.mockito.Mockito.verify; /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderRecordWatcherTest { @Mock @@ -71,22 +71,15 @@ public class LeaderRecordWatcherTest { private LeaderRecordWatcher watcher; - @Before + @BeforeEach public void before() { this.watcher = new LeaderRecordWatcher(this.mockLeaderProperties, this.mockLeadershipController, this.mockKubernetesClient); - - given(this.mockKubernetesClient.configMaps()) - .willReturn(this.mockConfigMapsOperation); - given(this.mockConfigMapsOperation.inNamespace(null)) - .willReturn(this.mockInNamespaceOperation); - given(this.mockInNamespaceOperation.withName(null)) - .willReturn(this.mockWithNameResource); - given(this.mockWithNameResource.watch(this.watcher)).willReturn(this.mockWatch); } @Test public void shouldStartOnce() { + initStubs(); this.watcher.start(); this.watcher.start(); @@ -95,6 +88,7 @@ public class LeaderRecordWatcherTest { @Test public void shouldStopOnce() { + initStubs(); this.watcher.start(); this.watcher.stop(); this.watcher.stop(); @@ -120,6 +114,7 @@ public class LeaderRecordWatcherTest { @Test public void shouldHandleClose() { + initStubs(); this.watcher.onClose(this.mockKubernetesClientException); verify(this.mockWithNameResource).watch(this.watcher); @@ -132,4 +127,14 @@ public class LeaderRecordWatcherTest { verify(this.mockWithNameResource, times(0)).watch(this.watcher); } + private void initStubs() { + given(this.mockKubernetesClient.configMaps()) + .willReturn(this.mockConfigMapsOperation); + given(this.mockConfigMapsOperation.inNamespace(null)) + .willReturn(this.mockInNamespaceOperation); + given(this.mockInNamespaceOperation.withName(null)) + .willReturn(this.mockWithNameResource); + given(this.mockWithNameResource.watch(this.watcher)).willReturn(this.mockWatch); + } + } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java index 9be158ba..93e8753f 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeaderTest.java @@ -16,11 +16,11 @@ package org.springframework.cloud.kubernetes.leader; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.integration.leader.Candidate; @@ -30,7 +30,7 @@ import static org.mockito.BDDMockito.given; /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeaderTest { private static final String ROLE = "test-role"; @@ -42,7 +42,7 @@ public class LeaderTest { private Leader leader; - @Before + @BeforeEach public void before() { this.leader = new Leader(ROLE, ID); } diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java index 6c94e3f6..68eb61c8 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java @@ -17,11 +17,11 @@ package org.springframework.cloud.kubernetes.leader; 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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.integration.leader.Candidate; import org.springframework.integration.leader.event.LeaderEventPublisher; @@ -31,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class LeadershipControllerTest { @Mock @@ -48,7 +48,7 @@ public class LeadershipControllerTest { private LeadershipController leadershipController; - @Before + @BeforeEach public void before() { this.leadershipController = new LeadershipController(this.mockCandidate, this.mockLeaderProperties, this.mockLeaderEventPublisher, diff --git a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java index 3b2d26c7..4e8b308d 100644 --- a/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java +++ b/spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/PodReadinessWatcherTest.java @@ -26,11 +26,11 @@ import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.PodResource; -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.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; @@ -39,7 +39,7 @@ import static org.mockito.Mockito.verify; /** * @author Gytis Trikleris */ -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class PodReadinessWatcherTest { private static final String POD_NAME = "test-pod"; @@ -70,18 +70,15 @@ public class PodReadinessWatcherTest { private PodReadinessWatcher watcher; - @Before + @BeforeEach public void before() { this.watcher = new PodReadinessWatcher(POD_NAME, this.mockKubernetesClient, this.mockLeadershipController); - - given(this.mockKubernetesClient.pods()).willReturn(this.mockPodsOperation); - given(this.mockPodsOperation.withName(POD_NAME)).willReturn(this.mockPodResource); - given(this.mockPodResource.watch(this.watcher)).willReturn(this.mockWatch); } @Test public void shouldStartOnce() { + initStubs(); this.watcher.start(); this.watcher.start(); @@ -90,6 +87,7 @@ public class PodReadinessWatcherTest { @Test public void shouldStopOnce() { + initStubs(); this.watcher.start(); this.watcher.stop(); this.watcher.stop(); @@ -99,6 +97,7 @@ public class PodReadinessWatcherTest { @Test public void shouldHandleEventWithStateChange() { + initStubs(); given(this.mockPodResource.isReady()).willReturn(true); given(this.mockPod.getStatus()).willReturn(this.mockPodStatus); @@ -110,6 +109,7 @@ public class PodReadinessWatcherTest { @Test public void shouldIgnoreEventIfStateDoesNotChange() { + initStubs(); given(this.mockPod.getStatus()).willReturn(this.mockPodStatus); this.watcher.start(); @@ -120,6 +120,7 @@ public class PodReadinessWatcherTest { @Test public void shouldHandleClose() { + initStubs(); this.watcher.onClose(this.mockKubernetesClientException); verify(this.mockPodResource).watch(this.watcher); @@ -132,4 +133,10 @@ public class PodReadinessWatcherTest { verify(this.mockPodResource, times(0)).watch(this.watcher); } + private void initStubs() { + given(this.mockKubernetesClient.pods()).willReturn(this.mockPodsOperation); + given(this.mockPodsOperation.withName(POD_NAME)).willReturn(this.mockPodResource); + given(this.mockPodResource.watch(this.watcher)).willReturn(this.mockWatch); + } + } From 966270b0f043b13d6c875aec5e11abcc0ee61b2b Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 8 Jun 2020 23:56:58 +0200 Subject: [PATCH 02/30] #561 Changing version of maven-failsafe-plugin and maven-surefire-plugin to 2.22.2 --- pom.xml | 4 ++-- spring-cloud-kubernetes-leader/pom.xml | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 9f326c33..73b06304 100644 --- a/pom.xml +++ b/pom.xml @@ -69,8 +69,8 @@ 3.5 2.8.2 - 2.18.1 - 2.21.0 + 2.22.2 + 2.22.2 4.4.0 2.4.12 3.0.2 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 4993a376..1f708a0c 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -73,12 +73,14 @@ + org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + ${maven-surefire-plugin.version} + org.apache.maven.plugins maven-failsafe-plugin - 2.22.2 + ${maven-failsafe-plugin.version} From b7dddb3577c211cb7c8465a5950a6bbd093f7a94 Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 9 Jun 2020 00:20:49 +0200 Subject: [PATCH 03/30] #561 Removing version of junit-vintage --- .../discovery/tests/pom.xml | 1 - .../simple-configmap/pom.xml | 1 - spring-cloud-kubernetes-integration-tests/simple-core/pom.xml | 1 - 3 files changed, 3 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index 5fa02dc8..97fd9aa3 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -22,7 +22,6 @@ org.junit.vintage junit-vintage-engine - 5.6.2 test diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 4af81d26..37ebae6e 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -39,7 +39,6 @@ org.junit.vintage junit-vintage-engine - 5.6.2 test diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 5f3982b1..41cd2ce2 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -39,7 +39,6 @@ org.junit.vintage junit-vintage-engine - 5.6.2 test From e78f3b176b005d1451c310394c1c18d6c7c4c2a6 Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Wed, 10 Jun 2020 11:13:55 -0500 Subject: [PATCH 04/30] discovered services filtered by labels --- .../discovery/KubernetesDiscoveryClient.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java index 8d05b49e..4e259e9d 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java @@ -17,7 +17,6 @@ package org.springframework.cloud.kubernetes.discovery; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -102,13 +101,7 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { Assert.notNull(serviceId, "[Assertion failed] - the object argument must not be null"); - List endpointsList = this.properties.isAllNamespaces() - ? this.client.endpoints().inAnyNamespace() - .withField("metadata.name", serviceId).list().getItems() - : Collections - .singletonList(this.client.endpoints().withName(serviceId).get()); - - List subsetsNS = endpointsList.stream() + List subsetsNS = this.getEndPointsList(serviceId).stream() .map(endpoints -> getSubsetsFromEndpoints(endpoints)) .collect(Collectors.toList()); @@ -122,6 +115,15 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { return instances; } + private List getEndPointsList(String serviceId) { + return this.properties.isAllNamespaces() + ? this.client.endpoints().inAnyNamespace() + .withField("metadata.name", serviceId) + .withLabels(properties.getServiceLabels()).list().getItems() + : this.client.endpoints().withField("metadata.name", serviceId) + .withLabels(properties.getServiceLabels()).list().getItems(); + } + private List getNamespaceServiceInstances(EndpointSubsetNS es, String serviceId) { String namespace = es.getNamespace(); From e2f509491f3eee10dcb4475824fbf5aac10fe38b Mon Sep 17 00:00:00 2001 From: moudatsos Date: Thu, 25 Jun 2020 00:10:10 +0300 Subject: [PATCH 05/30] Fix value data-type & entry-set order issues of properties bound to Map (#554) * Fix value data-type & entry-set order issues of properties bound to Map Issue: properties bound to a java.util.Map object do not maintain their definition order and their values lose their data-type, since they 're converted to String values. This fix mainly targets org.springframework.cloud.kubernetes.config .PropertySourceUtils.PROPERTIES_TO_MAP implementation: Configuration properties that are bound to a java.util.Map had their value's type affected by the use of .toString() on each entry's value during Map entry processing. Moreover, the use of java.util.stream .Collectors.toMap(java.util.function.Function, java.util.function.Function) when processing Map-bound properties, resulted in losing the entry insertion order of the original Map. The fix entails usage of the origina lentry value and a Collectors.toMap() variant that maintains the behavior of the method previously used, yet uses a java.util.LinkedHashMap as the target data structure for the processed entries. Ramification changes on method signature and return type have been applied where needed. * applying checkstyle * updated unit tests to account for the property loading behavior that maintains intended value data type * updated unit tests to account for the property loading behavior that maintains intended value data type * reverting test changes that target .properties files. Current fix targets only properties loaded from .yml files. org.springframework.cloud.kubernetes.config .PropertySourceUtils.KEY_VALUE_TO_PROPERTIES should be altered in order to address the same problem for configuration properties loaded from .properties files Co-authored-by: Michael Moudatsos From 407c6ee7d3a114f908e7159e916fa29bef376334 Mon Sep 17 00:00:00 2001 From: moudatsos Date: Thu, 25 Jun 2020 00:10:10 +0300 Subject: [PATCH 06/30] Fixed typo closes #511 --- .../kubernetes/config/reload/ConfigurationChangeDetector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index 2b6bace6..b0bcde8a 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -99,7 +99,7 @@ public abstract class ConfigurationChangeDetector { List l2) { if (l1.size() != l2.size()) { - this.log.warn("The current number of Confimap PropertySources does not match " + this.log.warn("The current number of ConfigMap PropertySources does not match " + "the ones loaded from the Kubernetes - No reload will take place"); return false; } From 9df02f137decc230e00daebf2f8a9d4c40ca3780 Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Wed, 24 Jun 2020 22:42:20 -0500 Subject: [PATCH 07/30] add tests --- .../discovery/KubernetesDiscoveryClient.java | 2 +- ...etesDiscoveryClientFilterMetadataTest.java | 21 +- .../KubernetesDiscoveryClientTest.java | 312 +++++++++++------- 3 files changed, 218 insertions(+), 117 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java index 4e259e9d..ac8eb75d 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClient.java @@ -115,7 +115,7 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { return instances; } - private List getEndPointsList(String serviceId) { + public List getEndPointsList(String serviceId) { return this.properties.isAllNamespaces() ? this.client.endpoints().inAnyNamespace() .withField("metadata.name", serviceId) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java index ae22dda2..c001699b 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientFilterMetadataTest.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.discovery; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,6 +35,9 @@ import io.fabric8.kubernetes.api.model.ServiceList; import io.fabric8.kubernetes.api.model.ServicePort; import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.Watch; +import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.ServiceResource; @@ -49,7 +53,9 @@ import org.springframework.cloud.client.ServiceInstance; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -79,6 +85,9 @@ public class KubernetesDiscoveryClientFilterMetadataTest { @Mock private Resource endpointsResource; + @Mock + FilterWatchListDeletable> filter; + @InjectMocks private KubernetesDiscoveryClient underTest; @@ -360,10 +369,16 @@ public class KubernetesDiscoveryClientFilterMetadataTest { .addNewSubset().addAllToPorts(getEndpointPorts(ports)).addNewAddress() .endAddress().endSubset().build(); - when(this.endpointsResource.get()).thenReturn(endpoints); - when(this.endpointsOperation.withName(serviceId)) - .thenReturn(this.endpointsResource); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + + EndpointsList endpointsList = new EndpointsList(null, + Collections.singletonList(endpoints), null, null); + when(filter.list()).thenReturn(endpointsList); + when(filter.withLabels(anyMap())).thenReturn(filter); + + when(this.kubernetesClient.endpoints().withField(eq("metadata.name"), + eq(serviceId))).thenReturn(filter); + } private List getServicePorts(Map ports) { diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java index 8eac4a77..fe05ee20 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java @@ -19,6 +19,7 @@ package org.springframework.cloud.kubernetes.discovery; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import io.fabric8.kubernetes.api.model.Endpoints; import io.fabric8.kubernetes.api.model.EndpointsBuilder; @@ -61,106 +62,44 @@ public class KubernetesDiscoveryClientTest { } @Test - public void getInstancesShouldBeAbleToHandleEndpointsFromMultipleNamespaces() { - Endpoints endPoints1 = new EndpointsBuilder().withNewMetadata() - .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() - .addNewAddress().withIp("ip1").withNewTargetRef().withUid("uid1") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + public void getInstancesShouldBeAbleToHandleEndpointsSingleAddress() { + Map labels = new HashMap(); + labels.put("l", "v"); - Endpoints endpoints2 = new EndpointsBuilder().withNewMetadata() - .withName("endpoint").withNamespace("test2").endMetadata().addNewSubset() - .addNewAddress().withIp("ip2").withNewTargetRef().withUid("uid2") + Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).endMetadata().addNewSubset() + .addNewAddress().withIp("ip1").withNewTargetRef().withUid("10") .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() .build(); List endpointsList = new ArrayList<>(); - endpointsList.add(endPoints1); - endpointsList.add(endpoints2); + endpointsList.add(endPoint); EndpointsList endpoints = new EndpointsList(); endpoints.setItems(endpointsList); + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?labelSelector=l%3Dv&fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + mockServer.expect().get() .withPath("/api/v1/endpoints?fieldSelector=metadata.name%3Dendpoint") .andReturn(200, endpoints).once(); - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint") - .andReturn(200, endPoints1).once(); + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); - mockServer.expect().get().withPath("/api/v1/namespaces/test2/endpoints/endpoint") - .andReturn(200, endpoints2).once(); - - Service service1 = new ServiceBuilder().withNewMetadata().withName("endpoint") - .withNamespace("test").withLabels(new HashMap() { - { - put("l", "v"); - } - }).endMetadata().build(); - - Service service2 = new ServiceBuilder().withNewMetadata().withName("endpoint") - .withNamespace("test2").withLabels(new HashMap() { - { - put("l", "v"); - } - }).endMetadata().build(); - - List servicesList = new ArrayList<>(); - servicesList.add(service1); - servicesList.add(service2); - - ServiceList services = new ServiceList(); - services.setItems(servicesList); - - mockServer.expect().get() - .withPath("/api/v1/services?fieldSelector=metadata.name%3Dendpoint") - .andReturn(200, services).once(); + Service service = new ServiceBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint") - .andReturn(200, service1).always(); - - mockServer.expect().get().withPath("/api/v1/namespaces/test2/services/endpoint") - .andReturn(200, service2).always(); - - final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); - properties.setAllNamespaces(true); - - final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, - properties, KubernetesClient::services, - new DefaultIsServicePortSecureResolver(properties)); - - final List instances = discoveryClient.getInstances("endpoint"); - - assertThat(instances).hasSize(2); - assertThat(instances).filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()) - .hasSize(1); - assertThat(instances).filteredOn(s -> s.getHost().equals("ip2") && !s.isSecure()) - .hasSize(1); - assertThat(instances).filteredOn(s -> s.getInstanceId().equals("uid1")) - .hasSize(1); - assertThat(instances).filteredOn(s -> s.getInstanceId().equals("uid2")) - .hasSize(1); - } - - @Test - public void getInstancesShouldBeAbleToHandleEndpointsSingleAddress() { - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint") - .andReturn(200, new EndpointsBuilder().withNewMetadata() - .withName("endpoint").endMetadata().addNewSubset().addNewAddress() - .withIp("ip1").withNewTargetRef().withUid("uid1").endTargetRef() - .endAddress().addNewPort("http", 80, "TCP").endSubset().build()) - .once(); - - mockServer.expect().get().withPath("/api/v1/services/endpoint") - .andReturn(200, new ServiceBuilder().withNewMetadata() - .withName("endpoint").withLabels(new HashMap() { - { - put("l", "v"); - } - }).endMetadata().build()) - .always(); + .andReturn(200, service).always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); + properties.setServiceLabels(labels); + properties.getMetadata().setAddLabels(false); + properties.getMetadata().setAddAnnotations(false); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, KubernetesClient::services, @@ -170,30 +109,45 @@ public class KubernetesDiscoveryClientTest { assertThat(instances).hasSize(1) .filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("uid1")).hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("10")).hasSize(1); } @Test public void getInstancesShouldBeAbleToHandleEndpointsSingleAddressAndMultiplePorts() { - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint") - .andReturn(200, new EndpointsBuilder().withNewMetadata() - .withName("endpoint").endMetadata().addNewSubset().addNewAddress() - .withIp("ip1").withNewTargetRef().withUid("uid").endTargetRef() - .endAddress().addNewPort("mgmt", 9000, "TCP") - .addNewPort("http", 80, "TCP").endSubset().build()) - .once(); + Map labels = new HashMap(); + labels.put("l2", "v2"); + + Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata() + .withName("endpoint").withNamespace("test").withLabels(labels) + .endMetadata().addNewSubset().addNewAddress().withIp("ip1") + .withNewTargetRef().withUid("20").endTargetRef().endAddress() + .addNewPort("mgmt", 900, "TCP").addNewPort("http", 80, "TCP").endSubset() + .build(); + + List endpointsList = new ArrayList<>(); + endpointsList.add(endPoint1); + + EndpointsList endpoints = new EndpointsList(); + endpoints.setItems(endpointsList); + + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?labelSelector=l2%3Dv2&fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + + Service service = new ServiceBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).withAnnotations(labels) + .endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint") - .andReturn(200, new ServiceBuilder().withNewMetadata() - .withName("endpoint").withLabels(new HashMap() { - { - put("l", "v"); - } - }).endMetadata().build()) - .always(); + .andReturn(200, service).always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); properties.setPrimaryPortName("http"); + final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, KubernetesClient::services, new DefaultIsServicePortSecureResolver(properties)); @@ -202,29 +156,81 @@ public class KubernetesDiscoveryClientTest { assertThat(instances).hasSize(1) .filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("uid")).hasSize(1) + .filteredOn(s -> s.getInstanceId().equals("20")).hasSize(1) .filteredOn(s -> 80 == s.getPort()).hasSize(1); } @Test - public void getInstancesShouldBeAbleToHandleEndpointsMultipleAddresses() { - mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint") - .andReturn(200, new EndpointsBuilder().withNewMetadata() - .withName("endpoint").endMetadata().addNewSubset().addNewAddress() - .withIp("ip1").endAddress().addNewAddress().withIp("ip2") - .endAddress().addNewPort("https", 443, "TCP").endSubset().build()) - .once(); + public void getEndPointsListTest() { + Map labels = new HashMap(); + labels.put("l", "v"); - mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint") - .andReturn(200, new ServiceBuilder().withNewMetadata() - .withName("endpoint").withLabels(new HashMap() { - { - put("l", "v"); - } - }).endMetadata().build()) - .always(); + Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).endMetadata().addNewSubset() + .addNewAddress().withIp("ip1").withNewTargetRef().withUid("30") + .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() + .build(); + + List endpointsList = new ArrayList<>(); + endpointsList.add(endPoint); + + EndpointsList endpoints = new EndpointsList(); + endpoints.setItems(endpointsList); + + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?labelSelector=l%3Dv&fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); + properties.setServiceLabels(labels); + + final KubernetesDiscoveryClient discoveryClient = new KubernetesDiscoveryClient( + mockClient, properties, KubernetesClient::services, + new DefaultIsServicePortSecureResolver(properties)); + + final List result_endpoints = discoveryClient + .getEndPointsList("endpoint"); + + assertThat(result_endpoints).hasSize(1); + } + + @Test + public void getInstancesShouldBeAbleToHandleEndpointsMultipleAddresses() { + Map labels = new HashMap(); + labels.put("l1", "v1"); + + Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).endMetadata().addNewSubset() + .addNewAddress().withIp("ip1").withNewTargetRef().withUid("40") + .endTargetRef().endAddress().addNewAddress().withIp("ip2") + .withNewTargetRef().withUid("50").endTargetRef().endAddress() + .addNewPort("https", 443, "TCP").endSubset().build(); + + List endpointsList = new ArrayList<>(); + endpointsList.add(endPoint); + + EndpointsList endpoints = new EndpointsList(); + endpoints.setItems(endpointsList); + + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?labelSelector=l1%3Dv1&fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + + mockServer.expect().get().withPath( + "/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + + Service service = new ServiceBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(labels).endMetadata().build(); + + mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint") + .andReturn(200, service).always(); + + final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); + properties.setServiceLabels(labels); + properties.getMetadata().setAddAnnotations(false); + properties.getMetadata().setAddLabels(false); + final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, KubernetesClient::services, new DefaultIsServicePortSecureResolver(properties)); @@ -295,4 +301,84 @@ public class KubernetesDiscoveryClientTest { assertThat(services).containsOnly("s1", "s2"); } + @Test + public void getInstancesShouldBeAbleToHandleEndpointsFromMultipleNamespaces() { + Endpoints endPoints1 = new EndpointsBuilder().withNewMetadata() + .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() + .addNewAddress().withIp("ip1").withNewTargetRef().withUid("60") + .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() + .build(); + + Endpoints endpoints2 = new EndpointsBuilder().withNewMetadata() + .withName("endpoint").withNamespace("test2").endMetadata().addNewSubset() + .addNewAddress().withIp("ip2").withNewTargetRef().withUid("70") + .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() + .build(); + + List endpointsList = new ArrayList<>(); + endpointsList.add(endPoints1); + endpointsList.add(endpoints2); + + EndpointsList endpoints = new EndpointsList(); + endpoints.setItems(endpointsList); + + mockServer.expect().get() + .withPath("/api/v1/endpoints?fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, endpoints).once(); + + mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint") + .andReturn(200, endPoints1).once(); + + mockServer.expect().get().withPath("/api/v1/namespaces/test2/endpoints/endpoint") + .andReturn(200, endpoints2).once(); + + Service service1 = new ServiceBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test").withLabels(new HashMap() { + { + put("l", "v"); + } + }).endMetadata().build(); + + Service service2 = new ServiceBuilder().withNewMetadata().withName("endpoint") + .withNamespace("test2").withLabels(new HashMap() { + { + put("l", "v"); + } + }).endMetadata().build(); + + List servicesList = new ArrayList<>(); + servicesList.add(service1); + servicesList.add(service2); + + ServiceList services = new ServiceList(); + services.setItems(servicesList); + + mockServer.expect().get() + .withPath("/api/v1/services?fieldSelector=metadata.name%3Dendpoint") + .andReturn(200, services).once(); + + mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint") + .andReturn(200, service1).always(); + + mockServer.expect().get().withPath("/api/v1/namespaces/test2/services/endpoint") + .andReturn(200, service2).always(); + + final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); + properties.setAllNamespaces(true); + + final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, + properties, KubernetesClient::services, + new DefaultIsServicePortSecureResolver(properties)); + + final List instances = discoveryClient.getInstances("endpoint"); + + assertThat(instances).hasSize(2); + assertThat(instances).filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()) + .hasSize(1); + assertThat(instances).filteredOn(s -> s.getHost().equals("ip2") && !s.isSecure()) + .hasSize(1); + assertThat(instances).filteredOn(s -> s.getInstanceId().equals("60")).hasSize(1); + assertThat(instances).filteredOn(s -> s.getInstanceId().equals("70")).hasSize(1); + } + } From d73df86ee62819cea3939e4472e618c738b7fa99 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 25 Jun 2020 11:46:04 +0000 Subject: [PATCH 08/30] Bumping versions --- .../config/reload/ConfigurationChangeDetector.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index b0bcde8a..12034a49 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -99,8 +99,9 @@ public abstract class ConfigurationChangeDetector { List l2) { if (l1.size() != l2.size()) { - this.log.warn("The current number of ConfigMap PropertySources does not match " - + "the ones loaded from the Kubernetes - No reload will take place"); + this.log.warn( + "The current number of ConfigMap PropertySources does not match " + + "the ones loaded from the Kubernetes - No reload will take place"); return false; } From 07925b3ac8440274616521ce1c3dbcbb58a2ebd0 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Fri, 26 Jun 2020 19:29:14 +0000 Subject: [PATCH 09/30] Update SNAPSHOT to 1.1.4.RELEASE --- README.adoc | 17 ++++++++--------- docs/pom.xml | 2 +- docs/src/main/asciidoc/_configprops.adoc | 2 +- pom.xml | 10 +++++----- spring-cloud-kubernetes-config/pom.xml | 2 +- .../reload/ConfigurationChangeDetector.java | 5 +++-- spring-cloud-kubernetes-core/pom.xml | 2 +- spring-cloud-kubernetes-dependencies/pom.xml | 4 ++-- spring-cloud-kubernetes-discovery/pom.xml | 2 +- .../greeting-service/pom.xml | 2 +- .../name-service/pom.xml | 2 +- .../pom.xml | 2 +- .../kubernetes-hello-world-example/pom.xml | 2 +- .../kubernetes-leader-election-example/pom.xml | 2 +- .../kubernetes-reload-example/pom.xml | 2 +- .../kubernetes-zipkin-example/pom.xml | 2 +- spring-cloud-kubernetes-examples/pom.xml | 2 +- .../discovery/discovery-client/pom.xml | 2 +- .../discovery/discovery-service-a/pom.xml | 2 +- .../discovery/discovery-service-b/pom.xml | 2 +- .../discovery/pom.xml | 2 +- .../discovery/tests/pom.xml | 2 +- .../istio/pom.xml | 2 +- .../pom.xml | 2 +- .../simple-configmap/pom.xml | 2 +- .../simple-core/pom.xml | 2 +- spring-cloud-kubernetes-istio/pom.xml | 2 +- spring-cloud-kubernetes-leader/pom.xml | 2 +- spring-cloud-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- spring-cloud-starter-kubernetes-config/pom.xml | 2 +- spring-cloud-starter-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes/pom.xml | 2 +- 33 files changed, 47 insertions(+), 47 deletions(-) diff --git a/README.adoc b/README.adoc index 132c003f..8965dadc 100644 --- a/README.adoc +++ b/README.adoc @@ -4,7 +4,6 @@ Manual changes to this file will be lost when it is generated again. Edit the files in the src/main/asciidoc/ directory instead. //// - = Spring Cloud Kubernetes :doctype: book :idprefix: @@ -428,13 +427,13 @@ spec: metadata: labels: app: deployment-name - spec: - containers: - - name: container-name - image: your-image - env: - - name: SPRING_PROFILES_ACTIVE - value: "development" + spec: + containers: + - name: container-name + image: your-image + env: + - name: SPRING_PROFILES_ACTIVE + value: "development" ---- ==== @@ -1265,4 +1264,4 @@ Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on t - `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL. - `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`. -IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. +IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. \ No newline at end of file diff --git a/docs/pom.xml b/docs/pom.xml index d2ec0163..e36eef35 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE pom Spring Cloud Kubernetes Docs diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index f743abbb..fc73b2fe 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -82,4 +82,4 @@ |spring.cloud.kubernetes.secrets.paths | | |spring.cloud.kubernetes.secrets.sources | | -|=== \ No newline at end of file +|=== diff --git a/pom.xml b/pom.xml index fdf3214e..996989fe 100644 --- a/pom.xml +++ b/pom.xml @@ -24,13 +24,13 @@ org.springframework.cloud spring-cloud-build - 2.3.1.BUILD-SNAPSHOT + 2.3.0.RELEASE org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE pom Spring Cloud Kubernetes @@ -63,9 +63,9 @@ - 2.2.4.BUILD-SNAPSHOT - 2.2.4.BUILD-SNAPSHOT - 2.2.4.BUILD-SNAPSHOT + 2.2.3.RELEASE + 2.2.3.RELEASE + 2.2.3.RELEASE 3.5 diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index f80f7b62..a36fd7a7 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index b0bcde8a..12034a49 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -99,8 +99,9 @@ public abstract class ConfigurationChangeDetector { List l2) { if (l1.size() != l2.size()) { - this.log.warn("The current number of ConfigMap PropertySources does not match " - + "the ones loaded from the Kubernetes - No reload will take place"); + this.log.warn( + "The current number of ConfigMap PropertySources does not match " + + "the ones loaded from the Kubernetes - No reload will take place"); return false; } diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index c1782473..9b75ba65 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index d8ddc8e3..28ddf81b 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -23,11 +23,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 2.3.1.BUILD-SNAPSHOT + 2.3.0.RELEASE spring-cloud-kubernetes-dependencies - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE pom Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index 06f4f2e3..c9dcc27f 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml index f9617e9e..c66c3c8d 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.3.BUILD-SNAPSHOT + 1.1.4.RELEASE greeting-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml index 4d8360b2..e503b5da 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.3.BUILD-SNAPSHOT + 1.1.4.RELEASE name-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml index 6bd44d9f..7915099d 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.3.BUILD-SNAPSHOT + 1.1.4.RELEASE org.springframework.cloud diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index 157945da..c4b747f0 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index 3572e5f3..feecaa36 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes-examples - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE kubernetes-leader-election-example diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index 1e372a59..e69b6cea 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml index 256afed5..e2b7b9b5 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.3.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index 4f87e54e..ee66836f 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index f46d12ed..48483a7f 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE discovery-client diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index b7326079..b36ba615 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE discovery-service-a diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index ca15c465..3286df9b 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE discovery-service-b diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index c5150465..499e27db 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index cd3abe09..44c0a710 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE tests diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index 829b07ea..c9ddb251 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE Spring Cloud Kubernetes :: Integration Tests :: Istio diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index ddc01da9..cba70d5f 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE spring-cloud-kubernetes-integration-tests diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 7cd19084..df800cf3 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 408308d1..3461e1b6 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE Spring Cloud Kubernetes :: Integration Tests :: Simple Core diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index cbafddd6..fbc62732 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 07ef29fe..6e4d4f5d 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE spring-cloud-kubernetes-leader diff --git a/spring-cloud-kubernetes-ribbon/pom.xml b/spring-cloud-kubernetes-ribbon/pom.xml index e1604281..6664821d 100644 --- a/spring-cloud-kubernetes-ribbon/pom.xml +++ b/spring-cloud-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index a6f4c53d..774968d3 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index cac3a621..102d465e 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-starter-kubernetes-ribbon/pom.xml b/spring-cloud-starter-kubernetes-ribbon/pom.xml index 2ccb5dff..36d6cda2 100644 --- a/spring-cloud-starter-kubernetes-ribbon/pom.xml +++ b/spring-cloud-starter-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index fa32313a..c9e570f5 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.4.RELEASE 4.0.0 From a30d8133f611778ead5e6b7551e5bcf3801f1df2 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Fri, 26 Jun 2020 19:31:29 +0000 Subject: [PATCH 10/30] Going back to snapshots --- README.adoc | 17 +++++++++-------- docs/pom.xml | 2 +- docs/src/main/asciidoc/_configprops.adoc | 2 +- pom.xml | 10 +++++----- spring-cloud-kubernetes-config/pom.xml | 2 +- .../reload/ConfigurationChangeDetector.java | 5 ++--- spring-cloud-kubernetes-core/pom.xml | 2 +- spring-cloud-kubernetes-dependencies/pom.xml | 4 ++-- spring-cloud-kubernetes-discovery/pom.xml | 2 +- .../greeting-service/pom.xml | 2 +- .../name-service/pom.xml | 2 +- .../pom.xml | 2 +- .../kubernetes-hello-world-example/pom.xml | 2 +- .../kubernetes-leader-election-example/pom.xml | 2 +- .../kubernetes-reload-example/pom.xml | 2 +- .../kubernetes-zipkin-example/pom.xml | 2 +- spring-cloud-kubernetes-examples/pom.xml | 2 +- .../discovery/discovery-client/pom.xml | 2 +- .../discovery/discovery-service-a/pom.xml | 2 +- .../discovery/discovery-service-b/pom.xml | 2 +- .../discovery/pom.xml | 2 +- .../discovery/tests/pom.xml | 2 +- .../istio/pom.xml | 2 +- .../pom.xml | 2 +- .../simple-configmap/pom.xml | 2 +- .../simple-core/pom.xml | 2 +- spring-cloud-kubernetes-istio/pom.xml | 2 +- spring-cloud-kubernetes-leader/pom.xml | 2 +- spring-cloud-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- spring-cloud-starter-kubernetes-config/pom.xml | 2 +- spring-cloud-starter-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes/pom.xml | 2 +- 33 files changed, 47 insertions(+), 47 deletions(-) diff --git a/README.adoc b/README.adoc index 8965dadc..132c003f 100644 --- a/README.adoc +++ b/README.adoc @@ -4,6 +4,7 @@ Manual changes to this file will be lost when it is generated again. Edit the files in the src/main/asciidoc/ directory instead. //// + = Spring Cloud Kubernetes :doctype: book :idprefix: @@ -427,13 +428,13 @@ spec: metadata: labels: app: deployment-name - spec: - containers: - - name: container-name - image: your-image - env: - - name: SPRING_PROFILES_ACTIVE - value: "development" + spec: + containers: + - name: container-name + image: your-image + env: + - name: SPRING_PROFILES_ACTIVE + value: "development" ---- ==== @@ -1264,4 +1265,4 @@ Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on t - `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL. - `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`. -IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. \ No newline at end of file +IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. diff --git a/docs/pom.xml b/docs/pom.xml index e36eef35..d2ec0163 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT pom Spring Cloud Kubernetes Docs diff --git a/docs/src/main/asciidoc/_configprops.adoc b/docs/src/main/asciidoc/_configprops.adoc index fc73b2fe..f743abbb 100644 --- a/docs/src/main/asciidoc/_configprops.adoc +++ b/docs/src/main/asciidoc/_configprops.adoc @@ -82,4 +82,4 @@ |spring.cloud.kubernetes.secrets.paths | | |spring.cloud.kubernetes.secrets.sources | | -|=== +|=== \ No newline at end of file diff --git a/pom.xml b/pom.xml index 996989fe..fdf3214e 100644 --- a/pom.xml +++ b/pom.xml @@ -24,13 +24,13 @@ org.springframework.cloud spring-cloud-build - 2.3.0.RELEASE + 2.3.1.BUILD-SNAPSHOT org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT pom Spring Cloud Kubernetes @@ -63,9 +63,9 @@ - 2.2.3.RELEASE - 2.2.3.RELEASE - 2.2.3.RELEASE + 2.2.4.BUILD-SNAPSHOT + 2.2.4.BUILD-SNAPSHOT + 2.2.4.BUILD-SNAPSHOT 3.5 diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index a36fd7a7..f80f7b62 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index 12034a49..b0bcde8a 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -99,9 +99,8 @@ public abstract class ConfigurationChangeDetector { List l2) { if (l1.size() != l2.size()) { - this.log.warn( - "The current number of ConfigMap PropertySources does not match " - + "the ones loaded from the Kubernetes - No reload will take place"); + this.log.warn("The current number of ConfigMap PropertySources does not match " + + "the ones loaded from the Kubernetes - No reload will take place"); return false; } diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index 9b75ba65..c1782473 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 28ddf81b..d8ddc8e3 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -23,11 +23,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 2.3.0.RELEASE + 2.3.1.BUILD-SNAPSHOT spring-cloud-kubernetes-dependencies - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT pom Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index c9dcc27f..06f4f2e3 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml index c66c3c8d..f9617e9e 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.4.RELEASE + 1.1.3.BUILD-SNAPSHOT greeting-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml index e503b5da..4d8360b2 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.4.RELEASE + 1.1.3.BUILD-SNAPSHOT name-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml index 7915099d..6bd44d9f 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.RELEASE + 1.1.3.BUILD-SNAPSHOT org.springframework.cloud diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index c4b747f0..157945da 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index feecaa36..3572e5f3 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes-examples - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT kubernetes-leader-election-example diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index e69b6cea..1e372a59 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml index e2b7b9b5..256afed5 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.RELEASE + 1.1.3.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index ee66836f..4f87e54e 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index 48483a7f..f46d12ed 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT discovery-client diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index b36ba615..b7326079 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT discovery-service-a diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index 3286df9b..ca15c465 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT discovery-service-b diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index 499e27db..c5150465 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index 44c0a710..cd3abe09 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT tests diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index c9ddb251..829b07ea 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Istio diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index cba70d5f..ddc01da9 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT spring-cloud-kubernetes-integration-tests diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index df800cf3..7cd19084 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 3461e1b6..408308d1 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Core diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index fbc62732..cbafddd6 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 6e4d4f5d..07ef29fe 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT spring-cloud-kubernetes-leader diff --git a/spring-cloud-kubernetes-ribbon/pom.xml b/spring-cloud-kubernetes-ribbon/pom.xml index 6664821d..e1604281 100644 --- a/spring-cloud-kubernetes-ribbon/pom.xml +++ b/spring-cloud-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index 774968d3..a6f4c53d 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index 102d465e..cac3a621 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-ribbon/pom.xml b/spring-cloud-starter-kubernetes-ribbon/pom.xml index 36d6cda2..2ccb5dff 100644 --- a/spring-cloud-starter-kubernetes-ribbon/pom.xml +++ b/spring-cloud-starter-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index c9e570f5..fa32313a 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.RELEASE + 1.1.4.BUILD-SNAPSHOT 4.0.0 From 19cbdceabbb46d6d2237159f18a0b43fa8cc2c75 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Fri, 26 Jun 2020 19:31:29 +0000 Subject: [PATCH 11/30] Bumping versions to 1.1.5.BUILD-SNAPSHOT after release --- docs/pom.xml | 2 +- pom.xml | 2 +- spring-cloud-kubernetes-config/pom.xml | 2 +- spring-cloud-kubernetes-core/pom.xml | 2 +- spring-cloud-kubernetes-dependencies/pom.xml | 2 +- spring-cloud-kubernetes-discovery/pom.xml | 2 +- .../greeting-service/pom.xml | 2 +- .../name-service/pom.xml | 2 +- .../kubernetes-circuitbreaker-ribbon-example/pom.xml | 2 +- .../kubernetes-hello-world-example/pom.xml | 2 +- .../kubernetes-leader-election-example/pom.xml | 2 +- .../kubernetes-reload-example/pom.xml | 2 +- .../kubernetes-zipkin-example/pom.xml | 2 +- spring-cloud-kubernetes-examples/pom.xml | 2 +- .../discovery/discovery-client/pom.xml | 2 +- .../discovery/discovery-service-a/pom.xml | 2 +- .../discovery/discovery-service-b/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/discovery/pom.xml | 2 +- .../discovery/tests/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/istio/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/pom.xml | 2 +- .../simple-configmap/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/simple-core/pom.xml | 2 +- spring-cloud-kubernetes-istio/pom.xml | 2 +- spring-cloud-kubernetes-leader/pom.xml | 2 +- spring-cloud-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- spring-cloud-starter-kubernetes-config/pom.xml | 2 +- spring-cloud-starter-kubernetes-ribbon/pom.xml | 2 +- spring-cloud-starter-kubernetes/pom.xml | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index d2ec0163..95dd87f4 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT pom Spring Cloud Kubernetes Docs diff --git a/pom.xml b/pom.xml index fdf3214e..6be73261 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT pom Spring Cloud Kubernetes diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index f80f7b62..cc9a7782 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index c1782473..de5e73fb 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index d8ddc8e3..9a89aca7 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -27,7 +27,7 @@ spring-cloud-kubernetes-dependencies - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT pom Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index 06f4f2e3..9d77049e 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml index f9617e9e..7280c346 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/greeting-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.3.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT greeting-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml index 4d8360b2..53d4db60 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/name-service/pom.xml @@ -23,7 +23,7 @@ org.springframework.cloud kubernetes-circuitbreaker-ribbon-example - 1.1.3.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT name-service diff --git a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml index 6bd44d9f..745deeec 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-circuitbreaker-ribbon-example/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.3.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT org.springframework.cloud diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index 157945da..1fffcac5 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index 3572e5f3..f3372266 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes-examples - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT kubernetes-leader-election-example diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index 1e372a59..ebddce11 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml index 256afed5..7c65abba 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-zipkin-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 1.1.3.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index 4f87e54e..d65691b6 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index f46d12ed..30844baa 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT discovery-client diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index b7326079..de68db9a 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT discovery-service-a diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index ca15c465..d148a7df 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT discovery-service-b diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index c5150465..c7c43ade 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index cd3abe09..8cb06f53 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT tests diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index 829b07ea..407832c8 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Istio diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index ddc01da9..0b1bd839 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT spring-cloud-kubernetes-integration-tests diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 7cd19084..cfcdf934 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 408308d1..27d30e96 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Core diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index cbafddd6..da3f9b10 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 07ef29fe..f53fc16e 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT spring-cloud-kubernetes-leader diff --git a/spring-cloud-kubernetes-ribbon/pom.xml b/spring-cloud-kubernetes-ribbon/pom.xml index e1604281..0a097c58 100644 --- a/spring-cloud-kubernetes-ribbon/pom.xml +++ b/spring-cloud-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index a6f4c53d..57ddcb57 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index cac3a621..6ffd84aa 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-ribbon/pom.xml b/spring-cloud-starter-kubernetes-ribbon/pom.xml index 2ccb5dff..5bd0d73c 100644 --- a/spring-cloud-starter-kubernetes-ribbon/pom.xml +++ b/spring-cloud-starter-kubernetes-ribbon/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index fa32313a..cf433d43 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 1.1.4.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT 4.0.0 From 0951e892cebd3fbc9f5b0d651dffe0cfb6e46b7a Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Thu, 9 Jul 2020 18:16:37 -0500 Subject: [PATCH 12/30] addressing related fix to #472 --- .../discovery/KubernetesCatalogWatch.java | 13 +- ...bernetesCatalogWatchAutoConfiguration.java | 5 +- .../discovery/KubernetesCatalogWatchTest.java | 150 ++++++++++++++++++ 3 files changed, 163 insertions(+), 5 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java index 03511b14..416c5371 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatch.java @@ -45,12 +45,16 @@ public class KubernetesCatalogWatch implements ApplicationEventPublisherAware { private final KubernetesClient kubernetesClient; + private final KubernetesDiscoveryProperties properties; + private final AtomicReference> catalogEndpointsState = new AtomicReference<>(); private ApplicationEventPublisher publisher; - public KubernetesCatalogWatch(KubernetesClient kubernetesClient) { + public KubernetesCatalogWatch(KubernetesClient kubernetesClient, + KubernetesDiscoveryProperties properties) { this.kubernetesClient = kubernetesClient; + this.properties = properties; } @Override @@ -66,8 +70,11 @@ public class KubernetesCatalogWatch implements ApplicationEventPublisherAware { // not all pods participate in the service discovery. only those that have // endpoints. - List endpoints = this.kubernetesClient.endpoints().list() - .getItems(); + List endpoints = this.properties.isAllNamespaces() + ? this.kubernetesClient.endpoints().inAnyNamespace() + .withLabels(properties.getServiceLabels()).list().getItems() + : this.kubernetesClient.endpoints() + .withLabels(properties.getServiceLabels()).list().getItems(); List endpointsPodNames = endpoints.stream().map(Endpoints::getSubsets) .filter(Objects::nonNull).flatMap(Collection::stream) .map(EndpointSubset::getAddresses).filter(Objects::nonNull) diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchAutoConfiguration.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchAutoConfiguration.java index 7fd8b229..c0cb2a5f 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchAutoConfiguration.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchAutoConfiguration.java @@ -42,8 +42,9 @@ public class KubernetesCatalogWatchAutoConfiguration { @ConditionalOnProperty( name = "spring.cloud.kubernetes.discovery.catalog-services-watch.enabled", matchIfMissing = true) - public KubernetesCatalogWatch kubernetesCatalogWatch(KubernetesClient client) { - return new KubernetesCatalogWatch(client); + public KubernetesCatalogWatch kubernetesCatalogWatch(KubernetesClient client, + KubernetesDiscoveryProperties properties) { + return new KubernetesCatalogWatch(client, properties); } } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index 8102e9e6..081dc2f1 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -44,6 +44,7 @@ import org.springframework.context.ApplicationEventPublisher; import static java.util.Arrays.stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -54,6 +55,9 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class KubernetesCatalogWatchTest { + @Mock + private KubernetesDiscoveryProperties properties; + @Mock private KubernetesClient kubernetesClient; @@ -81,7 +85,31 @@ public class KubernetesCatalogWatchTest { createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", "api-pod")); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + // second execution on shuffleServices + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + } + + @Test + public void testRandomOrderChangePodsAllNamespaces() throws Exception { + when(this.endpointsOperation.list()) + .thenReturn( + createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) + .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", + "api-pod")); + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); // second execution on shuffleServices @@ -97,7 +125,31 @@ public class KubernetesCatalogWatchTest { createEndpointsListByServiceName("api-service", "other-service")) .thenReturn( createEndpointsListByServiceName("other-service", "api-service")); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + // second execution on shuffleServices + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + } + + @Test + public void testRandomOrderChangeServicesAllNamespaces() throws Exception { + when(this.endpointsOperation.list()) + .thenReturn( + createEndpointsListByServiceName("api-service", "other-service")) + .thenReturn( + createEndpointsListByServiceName("other-service", "api-service")); + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); // second execution on shuffleServices @@ -110,7 +162,33 @@ public class KubernetesCatalogWatchTest { public void testEventBody() throws Exception { when(this.endpointsOperation.list()).thenReturn( createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher) + .publishEvent(this.heartbeatEventArgumentCaptor.capture()); + + HeartbeatEvent event = this.heartbeatEventArgumentCaptor.getValue(); + assertThat(event.getValue()).isInstanceOf(List.class); + + List expectedPodsList = Arrays.asList("api-pod", "other-pod"); + assertThat(event.getValue()).isEqualTo(expectedPodsList); + } + + @Test + public void testEventBodyAllNamespaces() throws Exception { + when(this.endpointsOperation.list()).thenReturn( + createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); @@ -129,8 +207,31 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListWithoutSubsets(); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + // second execution on shuffleServices + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + } + + @Test + public void testEndpointsWithoutSubsetsAllNamespaces() { + + EndpointsList endpoints = createSingleEndpointEndpointListWithoutSubsets(); + + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); // second execution on shuffleServices @@ -145,8 +246,32 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); endpoints.getItems().get(0).getSubsets().get(0).setAddresses(null); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + // second execution on shuffleServices + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + } + + @Test + public void testEndpointsWithoutAddressesAllNamespaces() { + + EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); + endpoints.getItems().get(0).getSubsets().get(0).setAddresses(null); + + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); // second execution on shuffleServices @@ -162,8 +287,33 @@ public class KubernetesCatalogWatchTest { endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0) .setTargetRef(null); + when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); + + this.underTest.catalogServicesWatch(); + // second execution on shuffleServices + this.underTest.catalogServicesWatch(); + + verify(this.applicationEventPublisher).publishEvent(any(HeartbeatEvent.class)); + } + + @Test + public void testEndpointsWithoutTargetRefsAllNamespaces() { + + EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); + endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0) + .setTargetRef(null); + + when(this.properties.isAllNamespaces()).thenReturn(true); + when(this.endpointsOperation.list()).thenReturn(endpoints); + when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace()) + .thenReturn(this.endpointsOperation); + when(this.kubernetesClient.endpoints().inAnyNamespace().withLabels(anyMap())) + .thenReturn(this.endpointsOperation); this.underTest.catalogServicesWatch(); // second execution on shuffleServices From f6b467323f0f82f29bd763c18825814b775219cb Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Thu, 16 Jul 2020 10:47:00 -0500 Subject: [PATCH 13/30] formatting --- .../config/reload/ConfigurationChangeDetector.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java index b0bcde8a..12034a49 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigurationChangeDetector.java @@ -99,8 +99,9 @@ public abstract class ConfigurationChangeDetector { List l2) { if (l1.size() != l2.size()) { - this.log.warn("The current number of ConfigMap PropertySources does not match " - + "the ones loaded from the Kubernetes - No reload will take place"); + this.log.warn( + "The current number of ConfigMap PropertySources does not match " + + "the ones loaded from the Kubernetes - No reload will take place"); return false; } From ca5380453ec1b90ff5aa0373b4b1c2c4efdd55c5 Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Thu, 16 Jul 2020 11:50:47 -0500 Subject: [PATCH 14/30] upgrade k8s fabric8 client to 4.10.3 --- spring-cloud-kubernetes-dependencies/pom.xml | 2 +- .../KubernetesDiscoveryClientTest.java | 24 +++++++++---------- ...ubernetesReactiveDiscoveryClientTests.java | 16 ++++++------- .../kubernetes/ribbon/RibbonFallbackTest.java | 2 +- .../cloud/kubernetes/ribbon/RibbonTest.java | 24 +++++++++---------- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 9a89aca7..1642c08d 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -34,7 +34,7 @@ 1.4.0.Final 1.15.2 - 4.4.1 + 4.10.3 1.0.0 0.1.2 3.12.0 diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java index fe05ee20..85a77231 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientTest.java @@ -69,8 +69,8 @@ public class KubernetesDiscoveryClientTest { Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint") .withNamespace("test").withLabels(labels).endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("10") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint); @@ -121,8 +121,8 @@ public class KubernetesDiscoveryClientTest { .withName("endpoint").withNamespace("test").withLabels(labels) .endMetadata().addNewSubset().addNewAddress().withIp("ip1") .withNewTargetRef().withUid("20").endTargetRef().endAddress() - .addNewPort("mgmt", 900, "TCP").addNewPort("http", 80, "TCP").endSubset() - .build(); + .addNewPort("mgmt", "mgmt_tcp", 900, "TCP") + .addNewPort("http", "http_tcp", 80, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -146,7 +146,7 @@ public class KubernetesDiscoveryClientTest { .andReturn(200, service).always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); - properties.setPrimaryPortName("http"); + properties.setPrimaryPortName("http_tcp"); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, KubernetesClient::services, @@ -168,8 +168,8 @@ public class KubernetesDiscoveryClientTest { Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint") .withNamespace("test").withLabels(labels).endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("30") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint); @@ -204,7 +204,7 @@ public class KubernetesDiscoveryClientTest { .addNewAddress().withIp("ip1").withNewTargetRef().withUid("40") .endTargetRef().endAddress().addNewAddress().withIp("ip2") .withNewTargetRef().withUid("50").endTargetRef().endAddress() - .addNewPort("https", 443, "TCP").endSubset().build(); + .addNewPort("https", "https_tcp", 443, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint); @@ -306,14 +306,14 @@ public class KubernetesDiscoveryClientTest { Endpoints endPoints1 = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("60") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); Endpoints endpoints2 = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test2").endMetadata().addNewSubset() .addNewAddress().withIp("ip2").withNewTargetRef().withUid("70") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoints1); diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java index fa35fa23..a09e7cad 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java @@ -160,8 +160,8 @@ class KubernetesReactiveDiscoveryClientTests { Endpoints endPoints = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("uid1") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); kubernetesServer.expect().get() .withPath("/api/v1/namespaces/test/endpoints/existing-service") @@ -204,8 +204,8 @@ class KubernetesReactiveDiscoveryClientTests { Endpoints endPoints = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("uid1") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP").endSubset() - .build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .endSubset().build(); kubernetesServer.expect().get() .withPath("/api/v1/namespaces/test/endpoints/existing-service") @@ -251,8 +251,8 @@ class KubernetesReactiveDiscoveryClientTests { Endpoints endPoints = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("uid1") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP") - .addNewPort("https", 443, "TCP").endSubset().build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .addNewPort("https", "https_tcp", 443, "TCP").endSubset().build(); kubernetesServer.expect().get() .withPath("/api/v1/namespaces/test/endpoints/existing-service") @@ -296,8 +296,8 @@ class KubernetesReactiveDiscoveryClientTests { Endpoints endpoints = new EndpointsBuilder().withNewMetadata() .withName("endpoint").withNamespace("test").endMetadata().addNewSubset() .addNewAddress().withIp("ip1").withNewTargetRef().withUid("uid1") - .endTargetRef().endAddress().addNewPort("http", 80, "TCP") - .addNewPort("https", 443, "TCP").endSubset().build(); + .endTargetRef().endAddress().addNewPort("http", "http_tcp", 80, "TCP") + .addNewPort("https", "https_tcp", 443, "TCP").endSubset().build(); EndpointsList endpointsList = new EndpointsList(); endpointsList.setItems(singletonList(endpoints)); diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java index 6422d641..bb14424b 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java @@ -100,7 +100,7 @@ public class RibbonFallbackTest { .addNewAddress() .withIp(mockServer.getHostName()) .endAddress() - .addNewPort("http", mockServer.getPort(), "http") + .addNewPort("http", "http_tcp",mockServer.getPort(), "http") .endSubset() .build(); // @formatter:on diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java index 08514363..a6413a01 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonTest.java @@ -79,19 +79,17 @@ public class RibbonTest { // Configured server.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp") - .andReturn(200, - new EndpointsBuilder().withNewMetadata().withName("testapp-a") - .endMetadata().addNewSubset().addNewAddress() - .withIp(mockEndpointA.getMockServer().getHostName()) - .endAddress() - .addNewPort("http", - mockEndpointA.getMockServer().getPort(), "http") - .endSubset().addNewSubset().addNewAddress() - .withIp(mockEndpointB.getMockServer().getHostName()) - .endAddress() - .addNewPort("http", - mockEndpointB.getMockServer().getPort(), "http") - .endSubset().build()) + .andReturn(200, new EndpointsBuilder().withNewMetadata() + .withName("testapp-a").endMetadata().addNewSubset() + .addNewAddress() + .withIp(mockEndpointA.getMockServer().getHostName()).endAddress() + .addNewPort("http", "http_tcp", + mockEndpointA.getMockServer().getPort(), "http") + .endSubset().addNewSubset().addNewAddress() + .withIp(mockEndpointB.getMockServer().getHostName()).endAddress() + .addNewPort("http", "http_tcp", + mockEndpointB.getMockServer().getPort(), "http") + .endSubset().build()) .always(); mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A") From d82282c3dde85ada8c6bda867b5ac1644f8e5e2f Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 21 Jul 2020 15:10:06 -0400 Subject: [PATCH 15/30] Config Refresh Controller (#567) * Deprecate KubernetesAutoServiceRegistration * Document service registry in kubernetes. Fixes #348 * Initial commit for refresh controller and tests * Running kind first * fixing config * Added some docs * Making sure the tests run as integration tests * Updates and new test for rabbitmq * Code review changes --- .circleci/config.yml | 13 +- README.adoc | 185 ++++++++++++ .../main/asciidoc/property-source-config.adoc | 4 + ...loud-kubernetes-configuration-watcher.adoc | 180 +++++++++++ .../asciidoc/spring-cloud-kubernetes.adoc | 2 + pom.xml | 19 ++ .../ConfigReloadDefaultAutoConfiguration.java | 125 ++++++++ ...EventBasedConfigurationChangeDetector.java | 12 +- spring-cloud-kubernetes-controllers/pom.xml | 19 ++ .../k8s/configmap.yaml | 21 ++ .../k8s/deployment.yaml | 74 +++++ .../pom.xml | 144 +++++++++ .../skaffold.yaml | 20 ++ ...sedConfigurationWatcherChangeDetector.java | 80 +++++ .../ConfigurationWatcherApplication.java | 37 +++ ...ConfigurationWatcherAutoConfiguration.java | 96 ++++++ .../ConfigurationWatcherChangeDetector.java | 126 ++++++++ ...urationWatcherConfigurationProperties.java | 103 +++++++ ...BasedConfigurationWatchChangeDetector.java | 153 ++++++++++ .../main/resources/META-INF/spring.factories | 2 + .../src/main/resources/application.yml | 19 ++ ...nfigurationWatcherChangeDetectorTests.java | 119 ++++++++ ...onWatcherConfigurationPropertiesTests.java | 37 +++ ...ConfigurationWatchChangeDetectorTests.java | 228 ++++++++++++++ .../pom.xml | 2 + .../deployment-it.yaml | 27 ++ .../kind-config.yaml | 28 ++ .../permissions.yaml | 32 ++ .../pom.xml | 106 +++++++ .../run.sh | 143 +++++++++ .../watcher/ConfigWatcherTestApplication.java | 55 ++++ .../src/main/resources/application.yaml | 7 + .../watcher/ActuatorRefreshIT.java | 235 +++++++++++++++ .../watcher/ActuatorRefreshRabbitMQIT.java | 285 ++++++++++++++++++ .../configuration/watcher/K8SUtils.java | 200 ++++++++++++ .../test/resources/rabbitmq-controller.yaml | 36 +++ .../src/test/resources/rabbitmq-service.yaml | 17 ++ ...-configuration-watcher-bus-deployment.yaml | 33 ++ ...netes-configuration-watcher-configmap.yaml | 9 + ...configuration-watcher-http-deployment.yaml | 28 ++ ...s-configuration-watcher-it-deployment.yaml | 30 ++ ...etes-configuration-watcher-it-ingress.yaml | 14 + ...etes-configuration-watcher-it-service.yaml | 14 + ...ernetes-configuration-watcher-service.yaml | 14 + .../test/resources/wiremock-deployment.yaml | 27 ++ .../src/test/resources/wiremock-ingress.yaml | 14 + .../src/test/resources/wiremock-service.yaml | 14 + src/checkstyle/checkstyle-suppressions.xml | 1 + 48 files changed, 3183 insertions(+), 6 deletions(-) create mode 100644 docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc create mode 100644 spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadDefaultAutoConfiguration.java create mode 100644 spring-cloud-kubernetes-controllers/pom.xml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/configmap.yaml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetector.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherApplication.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherAutoConfiguration.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherChangeDetector.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationProperties.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetector.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/application.yml create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetectorTests.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java create mode 100644 spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetectorTests.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/kind-config.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/permissions.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml create mode 100755 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/run.sh create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigWatcherTestApplication.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/resources/application.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/K8SUtils.java create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-controller.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-service.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-bus-deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-configmap.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-ingress.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-service.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-service.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-deployment.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-ingress.yaml create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-service.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index 4f44fd06..2fe21bbd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,12 +14,11 @@ # limitations under the License. # -version: 2 +orbs: + kube-orb: circleci/kubernetes@0.11.0 +version: 2.1 jobs: build: - branches: - ignore: - - gh-pages machine: true environment: _JAVA_OPTIONS: "-Xms1024m -Xmx2048m" @@ -52,6 +51,12 @@ jobs: command: | sudo apt update sudo apt install snapd + - kube-orb/install-kubectl + - run: + name: Run Kind Integration Tests + command: | + cd spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it + ./run.sh - run: name: Launch Kubernetes with microk8s command: | diff --git a/README.adoc b/README.adoc index 0c5184f5..a01f5dca 100644 --- a/README.adoc +++ b/README.adoc @@ -625,6 +625,10 @@ https://github.com/fabric8-quickstarts/spring-boot-camel-config[spring-boot-came === `PropertySource` Reload +WARNING: This functionality has been deprecated in the 2020.0 release. Please see +the <> controller for an alternative way +to achieve the same functionality. + Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud Kubernetes is able to trigger an application reload when a related `ConfigMap` or `Secret` changes. @@ -862,6 +866,187 @@ In Kubernetes service registration is controlled by the platform, the applicatio registration as it may do in other platforms. For this reason using `spring.cloud.service-registry.auto-registration.enabled` or setting `@EnableDiscoveryClient(autoRegister=false)` will have no effect in Spring Cloud Kubernetes. +[#spring-cloud-kubernetes-configuration-watcher] +## Spring Cloud Kubernetes Configuration Watcher + +Kubernetes provides the ability to https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-volume[mount a ConfigMap or Secret as a volume] +in the container of your application. When the contents of the ConfigMap or Secret changes, the https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#mounted-configmaps-are-updated-automatically[mounted volume will be updated with those changes]. + +However, Spring Boot will not automatically update those changes unless you restart the application. Spring Cloud +provides the ability refresh the application context without restarting the application by either hitting the +actuator endpoint `/refresh` or via publishing a `RefreshRemoteApplicationEvent` using Spring Cloud Bus. + +To achieve this configuration refresh of a Spring Cloud app running on Kubernetes, you can deploy the Spring Cloud +Kubernetes Configuration Watcher controller into your Kubernetes cluster. + +The application is published as a container and is available on Docker Hub. + +Spring Cloud Kubernetes Configuration Watcher can send refresh notifications to applications in two ways. + +1. Over HTTP in which case the application being notified must of the `/refresh` actuator endpoint exposed and accessible from within the cluster +2. Using Spring Cloud Bus, in which case you will need a message broker deployed to your custer for the application to use. + +### Deployment YAML + +Below is a sample deployment YAML you can use to deploy the Kubernetes Configuration Watcher to Kubernetes. + +==== +[source,yaml] +---- +--- +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: Service + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + spec: + ports: + - name: http + port: 8888 + targetPort: 8888 + selector: + app: spring-cloud-kubernetes-configuration-watcher + type: ClusterIP + - apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher:view + roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: namespace-reader + subjects: + - kind: ServiceAccount + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + namespace: default + name: namespace-reader + rules: + - apiGroups: ["", "extensions", "apps"] + resources: ["configmaps", "pods", "services", "endpoints", "secrets"] + verbs: ["get", "list", "watch"] + - apiVersion: apps/v1 + kind: Deployment + metadata: + name: spring-cloud-kubernetes-configuration-watcher-deployment + spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + spec: + serviceAccount: spring-cloud-kubernetes-configuration-watcher + containers: + - name: spring-cloud-kubernetes-configuration-watcher + image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8888 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8888 + path: /actuator/health/liveness + ports: + - containerPort: 8888 + +---- +==== + +The Service Account and associated Role Binding is important for Spring Cloud Kubernetes Configuration to work properly. +The controller needs access to read data about ConfigMaps, Pods, Services, Endpoints and Secrets in the Kubernetes cluster. + +### Monitoring ConfigMaps and Secrets + +Spring Cloud Kubernetes Configuration Watcher will react to changes in ConfigMaps with a label of `spring.cloud.kubernetes.config` with the value `true` +or any Secret with a label of `spring.cloud.kubernetes.secret` with the value `true`. If the ConfigMap or Secret does not have either of those labels +or the values of those labels is not `true` then any changes will be ignored. + +The labels Spring Cloud Kubernetes Configuration Watcher looks for on ConfigMaps and Secrets can be changed by setting +`spring.cloud.kubernetes.configuration.watcher.configLabel` and `spring.cloud.kubernetes.configuration.watcher.secretLabel` respectively. + +If a change is made to a ConfigMap or Secret with valid labels then Spring Cloud Kubernetes Configuration Watcher will take the name of the ConfigMap or Secret +and send a notification to the application with that name. + +### HTTP Implementation + +The HTTP implementation is what is used by default. When this implementation is used Spring Cloud Kubernetes Configuration Watcher and a +change to a ConfigMap or Secret occurs then the HTTP implementation will use the Spring Cloud Kubernetes Discovery Client to fetch all +instances of the application which match the name of the ConfigMap or Secret and send an HTTP POST request to the application's actuator +`/refresh` endpoint. By default it will send the post request to `/actuator/refresh` using the port registered in the discovery client. + +#### Non-Default Management Port and Actuator Path + +If the application is using a non-default actuator path and/or using a different port for the management endpoints, the Kubernetes service for the application +can add an annotation called `boot.spring.io/actuator` and set its value to the path and port used by the application. For example + +==== +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + labels: + app: config-map-demo + name: config-map-demo + annotations: + boot.spring.io/actuator: http://:9090/myactuator/home +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: config-map-demo +---- +==== + + +Another way you can choose to configure the actuator path and/or management port is by setting +`spring.cloud.kubernetes.configuration.watcher.actuatorPath` and `spring.cloud.kubernetes.configuration.watcher.actuatorPort`. + +### Messaging Implementation + +The messaging implementation can be enabled by setting the profile `bus` when the Spring Cloud Kubernetes Configuration Watcher +application is deployed to Kubernetes. + +WARNING: Currently the only supported message broker is RabbitMQ + +### Configuring RabbitMQ + +When the `bus` profile is enabled you will need to configure Spring RabbitMQ to point it to the location of the RabbitMQ +instance you would like to use as well as any credentials necessary to authenticate. This can be done +by setting the standard Spring RabbitMQ properties, for example + +==== +[source,yaml] +---- +spring: + rabbitmq: + username: user + password: password + host: rabbitmq +---- +==== + == Examples Spring Cloud Kubernetes tries to make it transparent for your applications to consume Kubernetes Native Services by diff --git a/docs/src/main/asciidoc/property-source-config.adoc b/docs/src/main/asciidoc/property-source-config.adoc index 72b435b3..9e2f3184 100644 --- a/docs/src/main/asciidoc/property-source-config.adoc +++ b/docs/src/main/asciidoc/property-source-config.adoc @@ -466,6 +466,10 @@ https://github.com/fabric8-quickstarts/spring-boot-camel-config[spring-boot-came === `PropertySource` Reload +WARNING: This functionality has been deprecated in the 2020.0 release. Please see +the <> controller for an alternative way +to achieve the same functionality. + Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud Kubernetes is able to trigger an application reload when a related `ConfigMap` or `Secret` changes. diff --git a/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc new file mode 100644 index 00000000..0801d56f --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc @@ -0,0 +1,180 @@ +[#spring-cloud-kubernetes-configuration-watcher] +## Spring Cloud Kubernetes Configuration Watcher + +Kubernetes provides the ability to https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-volume[mount a ConfigMap or Secret as a volume] +in the container of your application. When the contents of the ConfigMap or Secret changes, the https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#mounted-configmaps-are-updated-automatically[mounted volume will be updated with those changes]. + +However, Spring Boot will not automatically update those changes unless you restart the application. Spring Cloud +provides the ability refresh the application context without restarting the application by either hitting the +actuator endpoint `/refresh` or via publishing a `RefreshRemoteApplicationEvent` using Spring Cloud Bus. + +To achieve this configuration refresh of a Spring Cloud app running on Kubernetes, you can deploy the Spring Cloud +Kubernetes Configuration Watcher controller into your Kubernetes cluster. + +The application is published as a container and is available on Docker Hub. + +Spring Cloud Kubernetes Configuration Watcher can send refresh notifications to applications in two ways. + +1. Over HTTP in which case the application being notified must of the `/refresh` actuator endpoint exposed and accessible from within the cluster +2. Using Spring Cloud Bus, in which case you will need a message broker deployed to your custer for the application to use. + +### Deployment YAML + +Below is a sample deployment YAML you can use to deploy the Kubernetes Configuration Watcher to Kubernetes. + +==== +[source,yaml] +---- +--- +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: Service + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + spec: + ports: + - name: http + port: 8888 + targetPort: 8888 + selector: + app: spring-cloud-kubernetes-configuration-watcher + type: ClusterIP + - apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher:view + roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: namespace-reader + subjects: + - kind: ServiceAccount + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + namespace: default + name: namespace-reader + rules: + - apiGroups: ["", "extensions", "apps"] + resources: ["configmaps", "pods", "services", "endpoints", "secrets"] + verbs: ["get", "list", "watch"] + - apiVersion: apps/v1 + kind: Deployment + metadata: + name: spring-cloud-kubernetes-configuration-watcher-deployment + spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + spec: + serviceAccount: spring-cloud-kubernetes-configuration-watcher + containers: + - name: spring-cloud-kubernetes-configuration-watcher + image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8888 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8888 + path: /actuator/health/liveness + ports: + - containerPort: 8888 + +---- +==== + +The Service Account and associated Role Binding is important for Spring Cloud Kubernetes Configuration to work properly. +The controller needs access to read data about ConfigMaps, Pods, Services, Endpoints and Secrets in the Kubernetes cluster. + +### Monitoring ConfigMaps and Secrets + +Spring Cloud Kubernetes Configuration Watcher will react to changes in ConfigMaps with a label of `spring.cloud.kubernetes.config` with the value `true` +or any Secret with a label of `spring.cloud.kubernetes.secret` with the value `true`. If the ConfigMap or Secret does not have either of those labels +or the values of those labels is not `true` then any changes will be ignored. + +The labels Spring Cloud Kubernetes Configuration Watcher looks for on ConfigMaps and Secrets can be changed by setting +`spring.cloud.kubernetes.configuration.watcher.configLabel` and `spring.cloud.kubernetes.configuration.watcher.secretLabel` respectively. + +If a change is made to a ConfigMap or Secret with valid labels then Spring Cloud Kubernetes Configuration Watcher will take the name of the ConfigMap or Secret +and send a notification to the application with that name. + +### HTTP Implementation + +The HTTP implementation is what is used by default. When this implementation is used Spring Cloud Kubernetes Configuration Watcher and a +change to a ConfigMap or Secret occurs then the HTTP implementation will use the Spring Cloud Kubernetes Discovery Client to fetch all +instances of the application which match the name of the ConfigMap or Secret and send an HTTP POST request to the application's actuator +`/refresh` endpoint. By default it will send the post request to `/actuator/refresh` using the port registered in the discovery client. + +#### Non-Default Management Port and Actuator Path + +If the application is using a non-default actuator path and/or using a different port for the management endpoints, the Kubernetes service for the application +can add an annotation called `boot.spring.io/actuator` and set its value to the path and port used by the application. For example + +==== +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + labels: + app: config-map-demo + name: config-map-demo + annotations: + boot.spring.io/actuator: http://:9090/myactuator/home +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: config-map-demo +---- +==== + + +Another way you can choose to configure the actuator path and/or management port is by setting +`spring.cloud.kubernetes.configuration.watcher.actuatorPath` and `spring.cloud.kubernetes.configuration.watcher.actuatorPort`. + +### Messaging Implementation + +The messaging implementation can be enabled by setting the profile `bus` when the Spring Cloud Kubernetes Configuration Watcher +application is deployed to Kubernetes. + +WARNING: Currently the only supported message broker is RabbitMQ + +### Configuring RabbitMQ + +When the `bus` profile is enabled you will need to configure Spring RabbitMQ to point it to the location of the RabbitMQ +instance you would like to use as well as any credentials necessary to authenticate. This can be done +by setting the standard Spring RabbitMQ properties, for example + +==== +[source,yaml] +---- +spring: + rabbitmq: + username: user + password: password + host: rabbitmq +---- +==== diff --git a/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc b/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc index 2b194831..83839184 100644 --- a/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc +++ b/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc @@ -26,6 +26,8 @@ include::security-service-accounts.adoc[] include::service-registry.adoc[] +include::spring-cloud-kubernetes-configuration-watcher.adoc[] + include::examples.adoc[] include::other-resources.adoc[] diff --git a/pom.xml b/pom.xml index 73b06304..078bf347 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,8 @@ 3.0.0-SNAPSHOT 3.0.0-SNAPSHOT + 3.0.0-SNAPSHOT + 3.0.0-SNAPSHOT 3.5 @@ -94,6 +96,7 @@ spring-cloud-kubernetes-examples spring-cloud-kubernetes-leader spring-cloud-kubernetes-istio + spring-cloud-kubernetes-controllers spring-cloud-kubernetes-integration-tests docs @@ -125,6 +128,22 @@ import + + org.springframework.cloud + spring-cloud-bus-dependencies + ${spring-cloud-bus.version} + pom + import + + + + org.springframework.cloud + spring-cloud-contract-dependencies + ${spring-cloud-contract.version} + pom + import + + org.codehaus.groovy groovy-all diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadDefaultAutoConfiguration.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadDefaultAutoConfiguration.java new file mode 100644 index 00000000..d4097f97 --- /dev/null +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/ConfigReloadDefaultAutoConfiguration.java @@ -0,0 +1,125 @@ +/* + * 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.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.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * @author Ryan Baxter + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true) +@ConditionalOnMissingBean(ConfigReloadAutoConfiguration.class) +@EnableConfigurationProperties(ConfigReloadProperties.class) +public class ConfigReloadDefaultAutoConfiguration { + + /** + * Configuration reload must be enabled explicitly. + */ + @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") + @EnableScheduling + @EnableAsync + protected static class ConfigReloadAutoConfigurationBeans { + + @Autowired + private AbstractEnvironment environment; + + @Autowired + private KubernetesClient kubernetesClient; + + @Autowired + private ConfigMapPropertySourceLocator configMapPropertySourceLocator; + + @Autowired + private SecretsPropertySourceLocator secretsPropertySourceLocator; + + /** + * @param properties config reload properties + * @param strategy configuration update strategy + * @return a bean that listen to configuration changes and fire a reload. + */ + @Bean + @ConditionalOnMissingBean + public ConfigurationChangeDetector propertyChangeWatcher( + ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) { + switch (properties.getMode()) { + case POLLING: + return new PollingConfigurationChangeDetector(this.environment, + properties, this.kubernetesClient, strategy, + this.configMapPropertySourceLocator, + this.secretsPropertySourceLocator); + case EVENT: + return new EventBasedConfigurationChangeDetector(this.environment, + properties, this.kubernetesClient, strategy, + this.configMapPropertySourceLocator, + this.secretsPropertySourceLocator); + } + throw new IllegalStateException( + "Unsupported configuration reload mode: " + properties.getMode()); + } + + /** + * @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) { + switch (properties.getStrategy()) { + 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-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java index 32a9d463..43b675f6 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/reload/EventBasedConfigurationChangeDetector.java @@ -74,6 +74,10 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe @Override public void eventReceived(Action action, ConfigMap configMap) { + if (log.isDebugEnabled()) { + log.debug(name + " received event for ConfigMap " + + configMap.getMetadata().getName()); + } onEvent(configMap); } @@ -99,6 +103,10 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe this.kubernetesClient.secrets().watch(new Watcher() { @Override public void eventReceived(Action action, Secret secret) { + if (log.isDebugEnabled()) { + log.debug(name + " received and event for Secret " + + secret.getMetadata().getName()); + } onEvent(secret); } @@ -138,7 +146,7 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe } } - private void onEvent(ConfigMap configMap) { + protected void onEvent(ConfigMap configMap) { boolean changed = changed( locateMapPropertySources(this.configMapPropertySourceLocator, this.environment), @@ -149,7 +157,7 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe } } - private void onEvent(Secret secret) { + protected void onEvent(Secret secret) { boolean changed = changed( locateMapPropertySources(this.secretsPropertySourceLocator, this.environment), diff --git a/spring-cloud-kubernetes-controllers/pom.xml b/spring-cloud-kubernetes-controllers/pom.xml new file mode 100644 index 00000000..5be61521 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/pom.xml @@ -0,0 +1,19 @@ + + + + spring-cloud-kubernetes + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + pom + + spring-cloud-kubernetes-controllers + + + spring-cloud-kubernetes-configuration-watcher + + + diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/configmap.yaml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/configmap.yaml new file mode 100644 index 00000000..548aabd8 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +data: + application.yaml: |- + spring: + rabbitmq: + username: rbaxter + password: password + logging: + level: + org: + springframework: + cloud: + kubernetes: TRACE + management: + endpoints: + web: + exposure: + include: "*" +kind: ConfigMap +metadata: + name: spring-cloud-kubernetes-configuration-watcher diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml new file mode 100644 index 00000000..025cd71f --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: Service + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + spec: + ports: + - name: http + port: 8888 + targetPort: 8888 + selector: + app: spring-cloud-kubernetes-configuration-watcher + type: ClusterIP + - apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher:view + roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: namespace-reader + subjects: + - kind: ServiceAccount + name: spring-cloud-kubernetes-configuration-watcher + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + namespace: default + name: namespace-reader + rules: + - apiGroups: ["", "extensions", "apps"] + resources: ["configmaps", "pods", "services", "endpoints", "secrets"] + verbs: ["get", "list", "watch"] + - apiVersion: apps/v1 + kind: Deployment + metadata: + name: spring-cloud-kubernetes-configuration-watcher-deployment + spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + spec: + serviceAccount: spring-cloud-kubernetes-configuration-watcher + containers: + - name: spring-cloud-kubernetes-configuration-watcher + image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8888 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8888 + path: /actuator/health/liveness + ports: + - containerPort: 8888 diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml new file mode 100644 index 00000000..c0377dc8 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml @@ -0,0 +1,144 @@ + + + + spring-cloud-kubernetes-controllers + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-configuration-watcher + + + 1.8.0 + openjdk:8u222-slim + + + + + org.springframework.cloud + spring-cloud-starter-kubernetes-config + + + org.springframework.cloud + spring-cloud-starter-kubernetes + + + org.springframework.cloud + spring-cloud-starter-kubernetes-all + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-starter-contract-stub-runner + test + + + io.projectreactor + reactor-test + test + + + org.springframework.amqp + spring-rabbit-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + ${env.IMAGE} + + build-image + + + + package + + build-image + + + + + + + + + + imagename + + + + !env.IMAGE + + + + spring-cloud/${project.artifactId}:${project.version} + + + + jib + + + + com.google.cloud.tools + jib-maven-plugin + ${jib.version} + + + ${base.image} + + + spring-cloud/${project.artifactId} + + + nobody:nogroup + + + + + + + package + + dockerBuild + + + + + + + + + + + diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml new file mode 100644 index 00000000..345fe104 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml @@ -0,0 +1,20 @@ +apiVersion: skaffold/v2alpha3 +kind: Config +metadata: + name: spring-cloud-kubernetes-configuration-watcher +build: + artifacts: + - image: spring-cloud/spring-cloud-kubernetes-configuration-watcher + custom: + buildCommand: "../../mvnw clean install" + dependencies: + paths: + - src + - pom.xml +# jib: { +# args: ["-Pjib"] +# } +deploy: + kubectl: + manifests: + - k8s/deployment.yaml diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetector.java new file mode 100644 index 00000000..9a0485d1 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetector.java @@ -0,0 +1,80 @@ +/* + * 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.configuration.watcher; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.KubernetesClient; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.bus.BusProperties; +import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +/** + * @author Ryan Baxter + */ +public class BusEventBasedConfigurationWatcherChangeDetector extends + ConfigurationWatcherChangeDetector implements ApplicationEventPublisherAware { + + private ApplicationEventPublisher applicationEventPublisher; + + private BusProperties busProperties; + + public BusEventBasedConfigurationWatcherChangeDetector( + AbstractEnvironment environment, ConfigReloadProperties properties, + KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy, + ConfigMapPropertySourceLocator configMapPropertySourceLocator, + SecretsPropertySourceLocator secretsPropertySourceLocator, + BusProperties busProperties, + ConfigurationWatcherConfigurationProperties k8SConfigurationProperties, + ThreadPoolTaskExecutor threadPoolTaskExecutor) { + super(environment, properties, kubernetesClient, strategy, + configMapPropertySourceLocator, secretsPropertySourceLocator, + k8SConfigurationProperties, threadPoolTaskExecutor); + + this.busProperties = busProperties; + } + + @Override + protected Mono triggerRefresh(Secret secret) { + this.applicationEventPublisher.publishEvent(new RefreshRemoteApplicationEvent( + secret, busProperties.getId(), secret.getMetadata().getName())); + return Mono.empty(); + } + + @Override + protected Mono triggerRefresh(ConfigMap configMap) { + this.applicationEventPublisher.publishEvent(new RefreshRemoteApplicationEvent( + configMap, busProperties.getId(), configMap.getMetadata().getName())); + return Mono.empty(); + } + + @Override + public void setApplicationEventPublisher( + ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherApplication.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherApplication.java new file mode 100644 index 00000000..e58da7e5 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherApplication.java @@ -0,0 +1,37 @@ +/* + * 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.configuration.watcher; + +import org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthContributorAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +/** + * @author Ryan Baxter + */ +@Configuration(proxyBeanMethods = false) +@SpringBootApplication(exclude = { ContextFunctionCatalogAutoConfiguration.class, + RabbitHealthContributorAutoConfiguration.class }) +public class ConfigurationWatcherApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(ConfigurationWatcherApplication.class).run(args); + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherAutoConfiguration.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherAutoConfiguration.java new file mode 100644 index 00000000..e94429fa --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherAutoConfiguration.java @@ -0,0 +1,96 @@ +/* + * 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.configuration.watcher; + +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthContributorAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.bus.BusProperties; +import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.cloud.kubernetes.discovery.reactive.KubernetesReactiveDiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * @author Ryan Baxter + */ +@Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties({ ConfigurationWatcherConfigurationProperties.class }) +public class ConfigurationWatcherAutoConfiguration { + + protected Log log = LogFactory.getLog(getClass()); + + @Bean + @ConditionalOnMissingBean + public WebClient webClient(WebClient.Builder webClientBuilder) { + return webClientBuilder.build(); + } + + @Bean + @ConditionalOnMissingBean(ConfigurationWatcherChangeDetector.class) + public ConfigurationWatcherChangeDetector httpBasedConfigurationWatchChangeDetector( + AbstractEnvironment environment, KubernetesClient kubernetesClient, + ConfigMapPropertySourceLocator configMapPropertySourceLocator, + SecretsPropertySourceLocator secretsPropertySourceLocator, + ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, + ConfigurationWatcherConfigurationProperties k8SConfigurationProperties, + ThreadPoolTaskExecutor threadFactory, WebClient webClient, + KubernetesReactiveDiscoveryClient kubernetesReactiveDiscoveryClient) { + return new HttpBasedConfigurationWatchChangeDetector(environment, properties, + kubernetesClient, strategy, configMapPropertySourceLocator, + secretsPropertySourceLocator, k8SConfigurationProperties, threadFactory, + webClient, kubernetesReactiveDiscoveryClient); + } + + @Configuration + @Profile("bus") + @Import({ ContextFunctionCatalogAutoConfiguration.class, + RabbitHealthContributorAutoConfiguration.class }) + static class BusConfiguration { + + @Bean + @ConditionalOnMissingBean(ConfigurationWatcherChangeDetector.class) + public ConfigurationWatcherChangeDetector busPropertyChangeWatcher( + BusProperties busProperties, AbstractEnvironment environment, + KubernetesClient kubernetesClient, + ConfigMapPropertySourceLocator configMapPropertySourceLocator, + SecretsPropertySourceLocator secretsPropertySourceLocator, + ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, + ConfigurationWatcherConfigurationProperties k8SConfigurationProperties, + ThreadPoolTaskExecutor threadFactory) { + return new BusEventBasedConfigurationWatcherChangeDetector(environment, + properties, kubernetesClient, strategy, + configMapPropertySourceLocator, secretsPropertySourceLocator, + busProperties, k8SConfigurationProperties, threadFactory); + } + + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherChangeDetector.java new file mode 100644 index 00000000..2551848e --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherChangeDetector.java @@ -0,0 +1,126 @@ +/* + * 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.configuration.watcher; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.KubernetesClient; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.cloud.kubernetes.config.reload.EventBasedConfigurationChangeDetector; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +/** + * @author Ryan Baxter + */ +public abstract class ConfigurationWatcherChangeDetector + extends EventBasedConfigurationChangeDetector { + + private ScheduledExecutorService executorService; + + protected ConfigurationWatcherConfigurationProperties k8SConfigurationProperties; + + public ConfigurationWatcherChangeDetector(AbstractEnvironment environment, + ConfigReloadProperties properties, KubernetesClient kubernetesClient, + ConfigurationUpdateStrategy strategy, + ConfigMapPropertySourceLocator configMapPropertySourceLocator, + SecretsPropertySourceLocator secretsPropertySourceLocator, + ConfigurationWatcherConfigurationProperties k8SConfigurationProperties, + ThreadPoolTaskExecutor threadPoolTaskExecutor) { + super(environment, properties, kubernetesClient, strategy, + configMapPropertySourceLocator, secretsPropertySourceLocator); + this.executorService = Executors.newScheduledThreadPool( + k8SConfigurationProperties.getThreadPoolSize(), threadPoolTaskExecutor); + this.k8SConfigurationProperties = k8SConfigurationProperties; + } + + @Override + protected void onEvent(ConfigMap configMap) { + if (isSpringCloudKubernetesConfig(configMap)) { + if (log.isDebugEnabled()) { + log.debug("Scheduling remote refresh event to be published for ConfigMap " + + configMap.getMetadata().getName() + " to be published in " + + k8SConfigurationProperties.getRefreshDelay().toMillis() + + " milliseconds"); + } + executorService.schedule(() -> triggerRefresh(configMap).subscribe(), + k8SConfigurationProperties.getRefreshDelay().toMillis(), + TimeUnit.MILLISECONDS); + } + else { + if (log.isDebugEnabled()) { + log.debug("Not publishing event. ConfigMap " + + configMap.getMetadata().getName() + + " does not contain the label " + + k8SConfigurationProperties.getConfigLabel()); + } + } + } + + protected boolean isSpringCloudKubernetesConfig(ConfigMap configMap) { + if (configMap.getMetadata() == null + || configMap.getMetadata().getLabels() == null) { + return false; + } + return Boolean.parseBoolean(configMap.getMetadata().getLabels() + .getOrDefault(k8SConfigurationProperties.getConfigLabel(), "false")); + } + + protected boolean isSpringCloudKubernetesSecret(Secret secret) { + if (secret.getMetadata() == null || secret.getMetadata().getLabels() == null) { + return false; + } + return Boolean.parseBoolean(secret.getMetadata().getLabels() + .getOrDefault(k8SConfigurationProperties.getSecretLabel(), "false")); + } + + protected abstract Mono triggerRefresh(Secret secret); + + protected abstract Mono triggerRefresh(ConfigMap configMap); + + @Override + protected void onEvent(Secret secret) { + if (isSpringCloudKubernetesSecret(secret)) { + if (log.isDebugEnabled()) { + log.debug("Scheduling remote refresh event to be published for Secret " + + secret.getMetadata().getName() + " to be published in " + + k8SConfigurationProperties.getRefreshDelay().toMillis() + + " milliseconds"); + } + executorService.schedule(() -> triggerRefresh(secret).subscribe(), + k8SConfigurationProperties.getRefreshDelay().toMillis(), + TimeUnit.MILLISECONDS); + } + else { + if (log.isDebugEnabled()) { + log.debug("Not publishing event. Secret " + secret.getMetadata().getName() + + " does not contain the label " + + k8SConfigurationProperties.getSecretLabel()); + } + } + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationProperties.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationProperties.java new file mode 100644 index 00000000..b7cb2004 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationProperties.java @@ -0,0 +1,103 @@ +/* + * 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.configuration.watcher; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.convert.DurationUnit; + +/** + * @author Ryan Baxter + */ +@ConfigurationProperties("spring.cloud.kubernetes.configuration.watcher") +public class ConfigurationWatcherConfigurationProperties { + + /** + * Amount of time to delay the posting of the event to allow the app volume to update + * data. + */ + @DurationUnit(ChronoUnit.MILLIS) + private Duration refreshDelay = Duration.ofMillis(120000); + + private int threadPoolSize = 1; + + private String configLabel = "spring.cloud.kubernetes.config"; + + private String secretLabel = "spring.cloud.kubernetes.secret"; + + private String actuatorPath = "/actuator"; + + private Integer actuatorPort = -1; + + public String getActuatorPath() { + return actuatorPath; + } + + public void setActuatorPath(String actuatorPath) { + String normalizedPath = actuatorPath; + if (!normalizedPath.startsWith("/")) { + normalizedPath = "/" + normalizedPath; + } + if (normalizedPath.endsWith("/")) { + normalizedPath = normalizedPath.substring(0, normalizedPath.length() - 1); + } + this.actuatorPath = normalizedPath; + } + + public Integer getActuatorPort() { + return actuatorPort; + } + + public void setActuatorPort(Integer actuatorPort) { + this.actuatorPort = actuatorPort; + } + + public String getSecretLabel() { + return secretLabel; + } + + public void setSecretLabel(String secretLabel) { + this.secretLabel = secretLabel; + } + + public String getConfigLabel() { + return configLabel; + } + + public void setConfigLabel(String configLabel) { + this.configLabel = configLabel; + } + + public Duration getRefreshDelay() { + return refreshDelay; + } + + public void setRefreshDelay(Duration refreshDelay) { + this.refreshDelay = refreshDelay; + } + + public int getThreadPoolSize() { + return threadPoolSize; + } + + public void setThreadPoolSize(int threadPoolSize) { + this.threadPoolSize = threadPoolSize; + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetector.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetector.java new file mode 100644 index 00000000..671d36f7 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetector.java @@ -0,0 +1,153 @@ +/* + * 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.configuration.watcher; + +import java.net.URI; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.KubernetesClient; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.cloud.kubernetes.discovery.reactive.KubernetesReactiveDiscoveryClient; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.StringUtils; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponentsBuilder; + +/** + * @author Ryan Baxter + */ +public class HttpBasedConfigurationWatchChangeDetector + extends ConfigurationWatcherChangeDetector { + + /** + * Annotation key for actuator port and path. + */ + public static String ANNOTATION_KEY = "boot.spring.io/actuator"; + + private WebClient webClient; + + private KubernetesReactiveDiscoveryClient kubernetesReactiveDiscoveryClient; + + public HttpBasedConfigurationWatchChangeDetector(AbstractEnvironment environment, + ConfigReloadProperties properties, KubernetesClient kubernetesClient, + ConfigurationUpdateStrategy strategy, + ConfigMapPropertySourceLocator configMapPropertySourceLocator, + SecretsPropertySourceLocator secretsPropertySourceLocator, + ConfigurationWatcherConfigurationProperties k8SConfigurationProperties, + ThreadPoolTaskExecutor threadPoolTaskExecutor, WebClient webClient, + KubernetesReactiveDiscoveryClient k8sReactiveDiscoveryClient) { + super(environment, properties, kubernetesClient, strategy, + configMapPropertySourceLocator, secretsPropertySourceLocator, + k8SConfigurationProperties, threadPoolTaskExecutor); + this.webClient = webClient; + this.kubernetesReactiveDiscoveryClient = k8sReactiveDiscoveryClient; + } + + @Override + protected Mono triggerRefresh(Secret secret) { + return refresh(secret.getMetadata()).then(); + } + + private void setActuatorUriFromAnnotation(UriComponentsBuilder actuatorUriBuilder, + String metadataUri) { + URI annotationUri = URI.create(metadataUri); + actuatorUriBuilder.path(annotationUri.getPath() + "/refresh"); + + // The URI may not contain a host so if that is the case the port in the URI will + // be -1 + // The authority of the URI will be : for example :9090, we just need the + // 9090 in this case + if (annotationUri.getPort() < 0) { + if (annotationUri.getAuthority() != null) { + actuatorUriBuilder + .port(annotationUri.getAuthority().replaceFirst(":", "")); + } + } + else { + actuatorUriBuilder.port(annotationUri.getPort()); + } + } + + private URI getActuatorUri(ServiceInstance si) { + String metadataUri = si.getMetadata().getOrDefault(ANNOTATION_KEY, ""); + if (log.isDebugEnabled()) { + log.debug("Metadata actuator uri is: " + metadataUri); + } + + UriComponentsBuilder actuatorUriBuilder = UriComponentsBuilder.newInstance() + .scheme(si.getScheme()).host(si.getHost()); + + if (!StringUtils.isEmpty(metadataUri)) { + if (log.isDebugEnabled()) { + log.debug("Found actuator URI in service instance metadata"); + } + setActuatorUriFromAnnotation(actuatorUriBuilder, metadataUri); + } + else { + Integer port = k8SConfigurationProperties.getActuatorPort() < 0 ? si.getPort() + : k8SConfigurationProperties.getActuatorPort(); + actuatorUriBuilder = actuatorUriBuilder + .path(k8SConfigurationProperties.getActuatorPath() + "/refresh") + .port(port); + } + + return actuatorUriBuilder.build().toUri(); + } + + protected Flux> refresh(ObjectMeta objectMeta) { + + return kubernetesReactiveDiscoveryClient.getInstances(objectMeta.getName()) + .flatMap(si -> { + URI actuatorUri = getActuatorUri(si); + if (log.isDebugEnabled()) { + log.debug("Sending refresh request for " + objectMeta.getName() + + " to URI " + actuatorUri.toString()); + } + Mono> response = webClient.post() + .uri(actuatorUri).retrieve().toBodilessEntity() + .doOnSuccess(re -> { + if (log.isDebugEnabled()) { + log.debug("Refresh sent to " + objectMeta.getName() + + " at URI address " + actuatorUri + + " returned a " + + re.getStatusCode().toString()); + } + }).doOnError(t -> { + log.warn("Refresh sent to " + objectMeta.getName() + + " failed", t); + }); + return response; + }); + } + + @Override + protected Mono triggerRefresh(ConfigMap configMap) { + return refresh(configMap.getMetadata()).then(); + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..c2377568 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.kubernetes.configuration.watcher.ConfigurationWatcherAutoConfiguration diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/application.yml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/application.yml new file mode 100644 index 00000000..3df5355d --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring: + application: + name: spring-cloud-kubernetes-configuration-watcher + cloud: + kubernetes: + reload: + enabled: true + monitoring-secrets: true + strategy: shutdown + bus: + enabled: false +server: + port: 8888 +--- +spring: + profiles: bus + cloud: + bus: + enabled: true diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetectorTests.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetectorTests.java new file mode 100644 index 00000000..be8c3c46 --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/BusEventBasedConfigurationWatcherChangeDetectorTests.java @@ -0,0 +1,119 @@ +/* + * 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.configuration.watcher; + +import io.fabric8.kubernetes.api.model.ConfigMap; +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.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.bus.BusProperties; +import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.mock.env.MockEnvironment; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +/** + * @author Ryan Baxter + */ +@RunWith(MockitoJUnitRunner.class) +public class BusEventBasedConfigurationWatcherChangeDetectorTests { + + @Mock + private KubernetesClient client; + + @Mock + private ConfigurationUpdateStrategy updateStrategy; + + @Mock + private ConfigMapPropertySourceLocator configMapPropertySourceLocator; + + @Mock + private SecretsPropertySourceLocator secretsPropertySourceLocator; + + @Mock + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + @Mock + private ApplicationEventPublisher applicationEventPublisher; + + private BusEventBasedConfigurationWatcherChangeDetector changeDetector; + + private ConfigurationWatcherConfigurationProperties configurationWatcherConfigurationProperties; + + private BusProperties busProperties; + + @Before + public void setup() { + MockEnvironment mockEnvironment = new MockEnvironment(); + ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(); + configurationWatcherConfigurationProperties = new ConfigurationWatcherConfigurationProperties(); + busProperties = new BusProperties(); + changeDetector = new BusEventBasedConfigurationWatcherChangeDetector( + mockEnvironment, configReloadProperties, client, updateStrategy, + configMapPropertySourceLocator, secretsPropertySourceLocator, + busProperties, configurationWatcherConfigurationProperties, + threadPoolTaskExecutor); + changeDetector.setApplicationEventPublisher(applicationEventPublisher); + } + + @Test + public void triggerRefreshWithConfigMap() { + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + ConfigMap configMap = new ConfigMap(); + configMap.setMetadata(objectMeta); + changeDetector.triggerRefresh(configMap); + ArgumentCaptor argumentCaptor = ArgumentCaptor + .forClass(RefreshRemoteApplicationEvent.class); + verify(applicationEventPublisher).publishEvent(argumentCaptor.capture()); + assertThat(argumentCaptor.getValue().getSource()).isEqualTo(configMap); + assertThat(argumentCaptor.getValue().getOriginService()) + .isEqualTo(busProperties.getId()); + assertThat(argumentCaptor.getValue().getDestinationService()).isEqualTo("foo:**"); + } + + @Test + public void triggerRefreshWithSecret() { + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + Secret secret = new Secret(); + secret.setMetadata(objectMeta); + changeDetector.triggerRefresh(secret); + ArgumentCaptor argumentCaptor = ArgumentCaptor + .forClass(RefreshRemoteApplicationEvent.class); + verify(applicationEventPublisher).publishEvent(argumentCaptor.capture()); + assertThat(argumentCaptor.getValue().getSource()).isEqualTo(secret); + assertThat(argumentCaptor.getValue().getOriginService()) + .isEqualTo(busProperties.getId()); + assertThat(argumentCaptor.getValue().getDestinationService()).isEqualTo("foo:**"); + } + +} 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 new file mode 100644 index 00000000..9c08860c --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigurationWatcherConfigurationPropertiesTests.java @@ -0,0 +1,37 @@ +/* + * 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.configuration.watcher; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ryan Baxter + */ +public class ConfigurationWatcherConfigurationPropertiesTests { + + @Test + public void setActuatorPath() { + ConfigurationWatcherConfigurationProperties properties = new ConfigurationWatcherConfigurationProperties(); + properties.setActuatorPath("foo"); + assertThat(properties.getActuatorPath()).isEqualTo("/foo"); + properties.setActuatorPath("/foo/bar/"); + assertThat(properties.getActuatorPath()).isEqualTo("/foo/bar"); + } + +} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetectorTests.java b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetectorTests.java new file mode 100644 index 00000000..3636bbca --- /dev/null +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/HttpBasedConfigurationWatchChangeDetectorTests.java @@ -0,0 +1,228 @@ +/* + * 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.configuration.watcher; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.EndpointAddress; +import io.fabric8.kubernetes.api.model.EndpointPort; +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.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import reactor.core.publisher.Flux; +import reactor.test.StepVerifier; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.SecretsPropertySourceLocator; +import org.springframework.cloud.kubernetes.config.reload.ConfigReloadProperties; +import org.springframework.cloud.kubernetes.config.reload.ConfigurationUpdateStrategy; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; +import org.springframework.cloud.kubernetes.discovery.reactive.KubernetesReactiveDiscoveryClient; +import org.springframework.mock.env.MockEnvironment; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.reactive.function.client.WebClient; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.springframework.cloud.kubernetes.configuration.watcher.HttpBasedConfigurationWatchChangeDetector.ANNOTATION_KEY; + +/** + * @author Ryan Baxter + */ +@RunWith(MockitoJUnitRunner.class) +public class HttpBasedConfigurationWatchChangeDetectorTests { + + @Rule + public WireMockRule wireMockRule = new WireMockRule(0); + + @Mock + private KubernetesClient client; + + @Mock + private ConfigurationUpdateStrategy updateStrategy; + + @Mock + private ConfigMapPropertySourceLocator configMapPropertySourceLocator; + + @Mock + private SecretsPropertySourceLocator secretsPropertySourceLocator; + + @Mock + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + @Mock + private KubernetesReactiveDiscoveryClient reactiveDiscoveryClient; + + private HttpBasedConfigurationWatchChangeDetector changeDetector; + + private ConfigurationWatcherConfigurationProperties configurationWatcherConfigurationProperties; + + @Before + public void setup() { + EndpointAddress fooEndpointAddress = new EndpointAddress(); + fooEndpointAddress.setIp("127.0.0.1"); + fooEndpointAddress.setHostname("localhost"); + EndpointPort fooEndpointPort = new EndpointPort(); + fooEndpointPort.setPort(wireMockRule.port()); + List instances = new ArrayList<>(); + KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( + "foo", "foo", fooEndpointAddress, fooEndpointPort, new HashMap<>(), + false); + instances.add(fooServiceInstance); + when(reactiveDiscoveryClient.getInstances(eq("foo"))) + .thenReturn(Flux.fromIterable(instances)); + MockEnvironment mockEnvironment = new MockEnvironment(); + ConfigReloadProperties configReloadProperties = new ConfigReloadProperties(); + configurationWatcherConfigurationProperties = new ConfigurationWatcherConfigurationProperties(); + WebClient webClient = WebClient.builder().build(); + changeDetector = new HttpBasedConfigurationWatchChangeDetector(mockEnvironment, + configReloadProperties, client, updateStrategy, + configMapPropertySourceLocator, secretsPropertySourceLocator, + configurationWatcherConfigurationProperties, threadPoolTaskExecutor, + webClient, reactiveDiscoveryClient); + } + + @Test + public void triggerConfigMapRefresh() { + ConfigMap configMap = new ConfigMap(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + configMap.setMetadata(objectMeta); + WireMock.configureFor("localhost", wireMockRule.port()); + stubFor(post(WireMock.urlEqualTo("/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(configMap)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/actuator/refresh"))); + } + + @Test + public void triggerSecretRefresh() throws InterruptedException { + Secret secret = new Secret(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + secret.setMetadata(objectMeta); + WireMock.configureFor("localhost", wireMockRule.port()); + stubFor(post(WireMock.urlEqualTo("/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(secret)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/actuator/refresh"))); + } + + @Test + public void triggerConfigMapRefreshWithPropertiesBasedActuatorPath() + throws InterruptedException { + configurationWatcherConfigurationProperties + .setActuatorPath("/my/custom/actuator"); + ConfigMap configMap = new ConfigMap(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + configMap.setMetadata(objectMeta); + WireMock.configureFor("localhost", wireMockRule.port()); + stubFor(post(WireMock.urlEqualTo("/my/custom/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(configMap)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/my/custom/actuator/refresh"))); + } + + @Test + public void triggerSecretRefreshWithPropertiesBasedActuatorPath() + throws InterruptedException { + configurationWatcherConfigurationProperties + .setActuatorPath("/my/custom/actuator"); + Secret secret = new Secret(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + secret.setMetadata(objectMeta); + WireMock.configureFor("localhost", wireMockRule.port()); + stubFor(post(WireMock.urlEqualTo("/my/custom/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(secret)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/my/custom/actuator/refresh"))); + } + + @Test + public void triggerConfigMapRefreshWithAnnotationActuatorPath() { + Map metadata = new HashMap<>(); + metadata.put(ANNOTATION_KEY, + "http://:" + wireMockRule.port() + "/my/custom/actuator"); + EndpointAddress fooEndpointAddress = new EndpointAddress(); + fooEndpointAddress.setIp("127.0.0.1"); + fooEndpointAddress.setHostname("localhost"); + EndpointPort fooEndpointPort = new EndpointPort(); + fooEndpointPort.setPort(wireMockRule.port()); + List instances = new ArrayList<>(); + KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( + "foo", "foo", fooEndpointAddress, fooEndpointPort, metadata, false); + instances.add(fooServiceInstance); + when(reactiveDiscoveryClient.getInstances(eq("foo"))) + .thenReturn(Flux.fromIterable(instances)); + ConfigMap configMap = new ConfigMap(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + configMap.setMetadata(objectMeta); + stubFor(post(WireMock.urlEqualTo("/my/custom/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(configMap)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/my/custom/actuator/refresh"))); + } + + @Test + public void triggerSecretRefreshWithAnnotationActuatorPath() { + Map metadata = new HashMap<>(); + metadata.put(ANNOTATION_KEY, + "http://:" + wireMockRule.port() + "/my/custom/actuator"); + EndpointAddress fooEndpointAddress = new EndpointAddress(); + fooEndpointAddress.setIp("127.0.0.1"); + fooEndpointAddress.setHostname("localhost"); + EndpointPort fooEndpointPort = new EndpointPort(); + fooEndpointPort.setPort(wireMockRule.port()); + List instances = new ArrayList<>(); + KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( + "foo", "foo", fooEndpointAddress, fooEndpointPort, metadata, false); + instances.add(fooServiceInstance); + when(reactiveDiscoveryClient.getInstances(eq("foo"))) + .thenReturn(Flux.fromIterable(instances)); + Secret secret = new Secret(); + ObjectMeta objectMeta = new ObjectMeta(); + objectMeta.setName("foo"); + secret.setMetadata(objectMeta); + stubFor(post(WireMock.urlEqualTo("/my/custom/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + StepVerifier.create(changeDetector.triggerRefresh(secret)).verifyComplete(); + verify(postRequestedFor(urlEqualTo("/my/custom/actuator/refresh"))); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index c666a61e..5e6f91a5 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -133,6 +133,8 @@ simple-configmap discovery + + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml new file mode 100644 index 00000000..a9d91dc6 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: k8s-demo-app + name: k8s-demo-app +spec: + replicas: 1 + selector: + matchLabels: + app: k8s-demo-app + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: k8s-demo-app + spec: + containers: + - image: docker.io/spring-cloud/spring-cloud-kubernetes-configuration-watcher-it:2.0.0-SNAPSHOT + name: spring-cloud-kubernetes-configuration-watcher-it + resources: {} + env: + - name: SPRING_RABBITMQ_HOST + value: rabbitmq-service +status: {} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/kind-config.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/kind-config.yaml new file mode 100644 index 00000000..90afa077 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/kind-config.yaml @@ -0,0 +1,28 @@ +# this config file contains all config fields with comments +# NOTE: this is not a particularly useful config file +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +containerdConfigPatches: +- |- + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"] + endpoint = ["http://kind-registry:5000"] + +# 1 control plane node and 3 workers +nodes: + - role: control-plane + image: kindest/node:v1.14.10@sha256:6cd43ff41ae9f02bb46c8f455d5323819aec858b99534a290517ebc181b443c6 + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + - role: worker + image: kindest/node:v1.14.10@sha256:6cd43ff41ae9f02bb46c8f455d5323819aec858b99534a290517ebc181b443c6 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/permissions.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/permissions.yaml new file mode 100644 index 00000000..f5183e04 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/permissions.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: v1 +kind: List +items: + - apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-serviceaccount + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-serviceaccount:view + roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: namespace-reader + subjects: + - kind: ServiceAccount + name: spring-cloud-kubernetes-serviceaccount + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + namespace: default + name: namespace-reader + rules: + - apiGroups: ["", "extensions", "apps"] + resources: ["configmaps", "pods", "services", "endpoints", "secrets"] + verbs: ["get", "list", "watch"] diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml new file mode 100644 index 00000000..4897f9c0 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml @@ -0,0 +1,106 @@ + + + + org.springframework.cloud + spring-cloud-kubernetes-integration-tests + 2.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-configuration-watcher-it + jar + + + 2.26.3 + 6.0.1 + 3.2.2 + 4.0.3 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + com.github.tomakehurst + wiremock-jre8 + ${wiremock.version} + test + + + io.kubernetes + client-java + ${kubernetes-client.version} + test + + + io.kubernetes + client-java-extended + ${kubernetes-client.version} + test + + + com.github.docker-java + docker-java-core + ${docker-java.version} + test + + + com.github.docker-java + docker-java-transport-httpclient5 + ${docker-java.version} + test + + + org.awaitility + awaitility + ${awaitility.version} + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + spring-cloud/${project.artifactId}:${project.version} + + build-image + + + + package + + build-image + + + + + + + diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/run.sh b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/run.sh new file mode 100755 index 00000000..3f266f2b --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/run.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +# standard bash error handling +set -o errexit; +set -o pipefail; +set -o nounset; +# debug commands +set -x; + +# working dir to install binaries etc, cleaned up on exit +BIN_DIR="$(mktemp -d)" +# kind binary will be here +KIND="${BIN_DIR}/kind" + +ISTIOCTL="${BIN_DIR}/istio-1.6.2/bin/istioctl" + +CURRENT_DIR="$(pwd)" + +# cleanup on exit (useful for running locally) +cleanup() { + "${KIND}" delete cluster || true + rm -rf "${BIN_DIR}" + + docker kill kind-registry + docker rm kind-registry + docker network rm kind +} +trap cleanup EXIT + +# util to install the latest kind version into ${BIN_DIR} +install_latest_kind() { + # clone kind into a tempdir within BIN_DIR + local tmp_dir + tmp_dir="$(TMPDIR="${BIN_DIR}" mktemp -d "${BIN_DIR}/kind-source.XXXXX")" + cd "${tmp_dir}" || exit + git clone https://github.com/kubernetes-sigs/kind && cd ./kind + make install INSTALL_DIR="${BIN_DIR}" +} + +# util to install a released kind version into ${BIN_DIR} +install_kind_release() { + VERSION="v0.5.1" + KIND_BINARY_URL="https://github.com/kubernetes-sigs/kind/releases/download/${VERSION}/kind-linux-amd64" + if [[ "$OSTYPE" == "darwin"* ]]; then + KIND_BINARY_URL="https://github.com/kubernetes-sigs/kind/releases/download/${VERSION}/kind-darwin-amd64" + elif [[ "$OSTYPE" == "cygwin" ]]; then + KIND_BINARY_URL="https://github.com/kubernetes-sigs/kind/releases/download/${VERSION}/kind-windows-amd64" + elif [[ "$OSTYPE" == "msys" ]]; then + KIND_BINARY_URL="https://github.com/kubernetes-sigs/kind/releases/download/${VERSION}/kind-windows-amd64" + elif [[ "$OSTYPE" == "win32" ]]; then + KIND_BINARY_URL="https://github.com/kubernetes-sigs/kind/releases/download/${VERSION}/kind-windows-amd64" + else + echo "Uknown OS, using linux binary" + fi + wget -O "${KIND}" "${KIND_BINARY_URL}" + chmod +x "${KIND}" +} + +setup_registry() { +set -o errexit + +# create registry container unless it already exists +reg_name='kind-registry' +reg_port='5000' +running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" +if [ "${running}" != 'true' ]; then + docker run \ + -d --restart=always -p "${reg_port}:5000" --name "${reg_name}" \ + registry:2 +fi + +# create a cluster with the local registry enabled in containerd +cat </dev/null || true)" + if [ "${running}" != 'true' ]; then + docker run \ + -d --restart=always -p "${reg_port}:5000" --name "${reg_name}" \ + registry:2 + fi + + #TODO what happens if cluster is already there???? + "${KIND}" create cluster --config kind-config.yaml --loglevel=debug + + # connect the registry to the cluster network + docker network connect "kind" "${reg_name}" + + # tell https://tilt.dev to use the registry + # https://docs.tilt.dev/choosing_clusters.html#discovering-the-registry + for node in $("${KIND}" get nodes); do + kubectl annotate node "${node}" "kind.x-k8s.io/registry=localhost:${reg_port}"; + done + + # set KUBECONFIG to point to the cluster + kubectl cluster-info --context kind-kind + + #setup nginx ingress + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml + kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=360s + + # This creates the service account, role, and role binding necessary for Spring Cloud k8s apps + kubectl apply -f ./permissions.yaml + +# cd ${BIN_DIR} +# curl -L https://istio.io/downloadIstio | sh - + #"${ISTIOCTL}" install --set profile=demo + + cd $CURRENT_DIR + + # TODO: invoke your tests here + ../../mvnw clean install -P it + # teardown will happen automatically on exit +} + +main diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigWatcherTestApplication.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigWatcherTestApplication.java new file mode 100644 index 00000000..9f8ce737 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/java/org/springframework/cloud/kubernetes/configuration/watcher/ConfigWatcherTestApplication.java @@ -0,0 +1,55 @@ +/* + * 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.configuration.watcher; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class ConfigWatcherTestApplication + implements ApplicationListener { + + protected Log log = LogFactory.getLog(getClass()); + + private boolean value = false; + + public static void main(String[] args) { + SpringApplication.run(ConfigWatcherTestApplication.class, args); + } + + @GetMapping("/") + public boolean index() { + log.warn("Current value: " + value); + return value; + } + + @Override + public void onApplicationEvent( + RefreshRemoteApplicationEvent refreshRemoteApplicationEvent) { + log.warn("Received remote refresh event"); + this.value = true; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/resources/application.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/resources/application.yaml new file mode 100644 index 00000000..2a10259c --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/main/resources/application.yaml @@ -0,0 +1,7 @@ +spring: + application: + name: spring-cloud-kubernetes-configuration-watcher-it + cloud: + bus: + refresh: + enabled: false #disable this because we are going to provide our own refresh listener for testing purposes 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 new file mode 100644 index 00000000..e0c15ee2 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java @@ -0,0 +1,235 @@ +/* + * 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.configuration.watcher; + +import java.time.Duration; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.core.DefaultDockerClientConfig; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; +import com.github.dockerjava.transport.DockerHttpClient; +import com.github.tomakehurst.wiremock.client.WireMock; +import io.kubernetes.client.ApiClient; +import io.kubernetes.client.Configuration; +import io.kubernetes.client.apis.AppsV1Api; +import io.kubernetes.client.apis.CoreV1Api; +import io.kubernetes.client.apis.NetworkingV1beta1Api; +import io.kubernetes.client.models.NetworkingV1beta1Ingress; +import io.kubernetes.client.models.V1ConfigMap; +import io.kubernetes.client.models.V1ConfigMapBuilder; +import io.kubernetes.client.models.V1Deployment; +import io.kubernetes.client.models.V1Service; +import io.kubernetes.client.util.Config; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.findAll; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.awaitility.Awaitility.await; + +/** + * @author Ryan Baxter + */ +@RunWith(MockitoJUnitRunner.class) +public class ActuatorRefreshIT { + + private static final String KIND_REPO_HOST_PORT = "localhost:5000"; + + private static final String KIND_REPO_URL = "http://" + KIND_REPO_HOST_PORT; + + private static final String IMAGE = "spring-cloud-kubernetes-configuration-watcher"; + + private static final String IMAGE_TAG = "2.0.0-SNAPSHOT"; + + private static final String LOCAL_REPO = "docker.io/spring-cloud"; + + private static final String LOCAL_IMAGE = LOCAL_REPO + "/" + IMAGE + ":" + IMAGE_TAG; + + private static final String KIND_IMAGE = KIND_REPO_HOST_PORT + "/" + IMAGE; + + private static final String KIND_IMAGE_WITH_TAG = KIND_IMAGE + ":" + IMAGE_TAG; + + private static final String CONFIG_WATCHER_WIREMOCK_DEPLOYMENT_NAME = "config-watcher-wiremock-deployment"; + + private static final String CONFIG_WATCHER_WIREMOCK_APP_NAME = "config-watcher-wiremock"; + + private static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME = "spring-cloud-kubernetes-configuration-watcher-deployment"; + + private static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME = "spring-cloud-kubernetes-configuration-watcher"; + + private static final String WIREMOCK_HOST = "localhost"; + + private static final String WIREMOCK_PATH = "/wiremock"; + + private static final int WIREMOCK_PORT = 80; + + private static final String NAMESPACE = "default"; + + private ApiClient client; + + private CoreV1Api api; + + private AppsV1Api appsApi; + + private NetworkingV1beta1Api networkingApi; + + private K8SUtils k8SUtils; + + @Before + public void setup() throws Exception { + this.client = Config.defaultClient(); + // client.setDebugging(true); + Configuration.setDefaultApiClient(client); + this.api = new CoreV1Api(); + this.appsApi = new AppsV1Api(); + this.networkingApi = new NetworkingV1beta1Api(); + this.k8SUtils = new K8SUtils(api, appsApi); + + DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() + .withRegistryUrl(KIND_REPO_URL).build(); + DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() + .dockerHost(config.getDockerHost()).sslConfig(config.getSSLConfig()) + .build(); + + DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient); + dockerClient.tagImageCmd(LOCAL_IMAGE, KIND_IMAGE, IMAGE_TAG).exec(); + dockerClient.pushImageCmd(KIND_IMAGE_WITH_TAG).start(); + + deployWiremock(); + + // Check to make sure the wiremock deployment is ready + k8SUtils.waitForDeployment(CONFIG_WATCHER_WIREMOCK_DEPLOYMENT_NAME, NAMESPACE); + + // Check to see if endpoint is ready + k8SUtils.waitForEndpointReady(CONFIG_WATCHER_WIREMOCK_APP_NAME, NAMESPACE); + + deployConfigWatcher(); + + // Check to make sure the controller deployment is ready + k8SUtils.waitForDeployment(SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME, + NAMESPACE); + } + + @Test + public void testActuatorRefresh() throws Exception { + // Configure wiremock to point at the server + WireMock.configureFor(WIREMOCK_HOST, WIREMOCK_PORT, WIREMOCK_PATH); + + // Setup stubs for actuator refresh + stubFor(post(urlEqualTo("/actuator/refresh")) + .willReturn(aResponse().withStatus(200))); + + // Create new configmap to trigger controller to signal app to refresh + V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata() + .withName(CONFIG_WATCHER_WIREMOCK_APP_NAME) + .addToLabels("spring.cloud.kubernetes.config", "true").endMetadata() + .addToData("foo", "bar").build(); + api.createNamespacedConfigMap(NAMESPACE, configMap, null, null, null); + + // Wait a bit before we verify + await().atMost(Duration.ofMillis(3400)) + .until(() -> !findAll(postRequestedFor(urlEqualTo("/actuator/refresh"))) + .isEmpty()); + + verify(postRequestedFor(urlEqualTo("/actuator/refresh"))); + } + + @After + public void after() throws Exception { + + appsApi.deleteCollectionNamespacedDeployment(NAMESPACE, null, null, + "metadata.name=" + SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME, null, + null, null, null, null); + appsApi.deleteCollectionNamespacedDeployment(NAMESPACE, null, null, + "metadata.name=" + CONFIG_WATCHER_WIREMOCK_DEPLOYMENT_NAME, null, null, + null, null, null); + api.deleteNamespacedService(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, NAMESPACE, + null, null, null, null, null, null); + api.deleteNamespacedService(CONFIG_WATCHER_WIREMOCK_APP_NAME, NAMESPACE, null, + null, null, null, null, null); + networkingApi.deleteNamespacedIngress("nginx-ingress", NAMESPACE, null, null, + null, null, null, null); + api.deleteNamespacedConfigMap(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, NAMESPACE, + null, null, null, null, null, null); + api.deleteNamespacedConfigMap(CONFIG_WATCHER_WIREMOCK_APP_NAME, NAMESPACE, null, + null, null, null, null, null); + } + + private void deployConfigWatcher() throws Exception { + api.createNamespacedConfigMap(NAMESPACE, getConfigWatcherConfigMap(), null, null, + null); + appsApi.createNamespacedDeployment(NAMESPACE, getConfigWatcherDeployment(), null, + null, null); + api.createNamespacedService(NAMESPACE, getConfigWatcherService(), null, null, + null); + } + + private V1Service getConfigWatcherService() throws Exception { + V1Service service = (V1Service) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-service.yaml"); + return service; + } + + private V1ConfigMap getConfigWatcherConfigMap() throws Exception { + V1ConfigMap configMap = (V1ConfigMap) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-configmap.yaml"); + return configMap; + } + + private V1Deployment getConfigWatcherDeployment() throws Exception { + V1Deployment deployment = (V1Deployment) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml"); + return deployment; + } + + private void deployWiremock() throws Exception { + appsApi.createNamespacedDeployment(NAMESPACE, getWireockDeployment(), null, null, + null); + api.createNamespacedService(NAMESPACE, getWiremockAppService(), null, null, null); + networkingApi.createNamespacedIngress(NAMESPACE, getWiremockIngress(), null, null, + null); + } + + private NetworkingV1beta1Ingress getWiremockIngress() throws Exception { + NetworkingV1beta1Ingress ingress = (NetworkingV1beta1Ingress) k8SUtils + .readYamlFromClasspath("wiremock-ingress.yaml"); + return ingress; + } + + private V1Service getWiremockAppService() throws Exception { + V1Service service = (V1Service) k8SUtils + .readYamlFromClasspath("wiremock-service.yaml"); + return service; + } + + private V1Deployment getWireockDeployment() throws Exception { + V1Deployment deployment = (V1Deployment) k8SUtils + .readYamlFromClasspath("wiremock-deployment.yaml"); + return deployment; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java new file mode 100644 index 00000000..a3158ba6 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java @@ -0,0 +1,285 @@ +/* + * 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.configuration.watcher; + +import java.time.Duration; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.core.DefaultDockerClientConfig; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; +import com.github.dockerjava.transport.DockerHttpClient; +import io.kubernetes.client.ApiClient; +import io.kubernetes.client.Configuration; +import io.kubernetes.client.apis.AppsV1Api; +import io.kubernetes.client.apis.CoreV1Api; +import io.kubernetes.client.apis.NetworkingV1beta1Api; +import io.kubernetes.client.models.NetworkingV1beta1Ingress; +import io.kubernetes.client.models.V1ConfigMap; +import io.kubernetes.client.models.V1ConfigMapBuilder; +import io.kubernetes.client.models.V1Deployment; +import io.kubernetes.client.models.V1ReplicationController; +import io.kubernetes.client.models.V1Service; +import io.kubernetes.client.util.Config; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +/** + * @author Ryan Baxter + */ +@RunWith(MockitoJUnitRunner.class) +public class ActuatorRefreshRabbitMQIT { + + private Log log = LogFactory.getLog(getClass()); + + private static final String KIND_REPO_HOST_PORT = "localhost:5000"; + + private static final String KIND_REPO_URL = "http://" + KIND_REPO_HOST_PORT; + + private static final String CONFIG_WATCHER_IMAGE = "spring-cloud-kubernetes-configuration-watcher"; + + private static final String CONFIG_WATCHER_IT_IMAGE = "spring-cloud-kubernetes-configuration-watcher-it"; + + private static final String IMAGE_TAG = "2.0.0-SNAPSHOT"; + + private static final String LOCAL_REPO = "docker.io/spring-cloud"; + + private static final String CONFIG_WATCHER_LOCAL_IMAGE = LOCAL_REPO + "/" + + CONFIG_WATCHER_IMAGE + ":" + IMAGE_TAG; + + private static final String CONFIG_WATCHER_IT_LOCAL_IMAGE = LOCAL_REPO + "/" + + CONFIG_WATCHER_IT_IMAGE + ":" + IMAGE_TAG; + + private static final String CONFIG_WATCHER_KIND_IMAGE = KIND_REPO_HOST_PORT + "/" + + CONFIG_WATCHER_IMAGE; + + private static final String CONFIG_WATCHER_IT_KIND_IMAGE = KIND_REPO_HOST_PORT + "/" + + CONFIG_WATCHER_IT_IMAGE; + + private static final String CONFIG_WATCHER_KIND_IMAGE_WITH_TAG = CONFIG_WATCHER_KIND_IMAGE + + ":" + IMAGE_TAG; + + private static final String CONFIG_WATCHER_IT_KIND_IMAGE_WITH_TAG = CONFIG_WATCHER_IT_KIND_IMAGE + + ":" + IMAGE_TAG; + + private static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME = "spring-cloud-kubernetes-configuration-watcher-deployment"; + + private static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_IT_DEPLOYMENT_NAME = "spring-cloud-kubernetes-configuration-watcher-it-deployment"; + + private static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME = "spring-cloud-kubernetes-configuration-watcher"; + + private static final String NAMESPACE = "default"; + + private static final String RABBIT_MQ_CONTROLLER_NAME = "rabbitmq-controller"; + + private ApiClient client; + + private CoreV1Api api; + + private AppsV1Api appsApi; + + private NetworkingV1beta1Api networkingApi; + + private K8SUtils k8SUtils; + + @Before + public void setup() throws Exception { + this.client = Config.defaultClient(); + // client.setDebugging(true); + Configuration.setDefaultApiClient(client); + this.api = new CoreV1Api(); + this.appsApi = new AppsV1Api(); + this.networkingApi = new NetworkingV1beta1Api(); + this.k8SUtils = new K8SUtils(api, appsApi); + + DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() + .withRegistryUrl(KIND_REPO_URL).build(); + DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() + .dockerHost(config.getDockerHost()).sslConfig(config.getSSLConfig()) + .build(); + + DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient); + dockerClient.tagImageCmd(CONFIG_WATCHER_LOCAL_IMAGE, CONFIG_WATCHER_KIND_IMAGE, + IMAGE_TAG).exec(); + dockerClient.pushImageCmd(CONFIG_WATCHER_KIND_IMAGE_WITH_TAG).start(); + + dockerClient.tagImageCmd(CONFIG_WATCHER_IT_LOCAL_IMAGE, + CONFIG_WATCHER_IT_KIND_IMAGE, IMAGE_TAG).exec(); + dockerClient.pushImageCmd(CONFIG_WATCHER_IT_KIND_IMAGE_WITH_TAG).start(); + + deployRabbitMQ(); + + k8SUtils.waitForReplicationController(RABBIT_MQ_CONTROLLER_NAME, NAMESPACE); + + deployTestApp(); + + k8SUtils.waitForDeployment(SPRING_CLOUD_K8S_CONFIG_WATCHER_IT_DEPLOYMENT_NAME, + NAMESPACE); + + deployConfigWatcher(); + + // Check to make sure the controller deployment is ready + k8SUtils.waitForDeployment(SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME, + NAMESPACE); + } + + @Test + public void testRefresh() throws Exception { + // Create new configmap to trigger controller to signal app to refresh + V1ConfigMap configMap = new V1ConfigMapBuilder().editOrNewMetadata() + .withName(CONFIG_WATCHER_IT_IMAGE) + .addToLabels("spring.cloud.kubernetes.config", "true").endMetadata() + .addToData("foo", "hello world").build(); + api.createNamespacedConfigMap(NAMESPACE, configMap, null, null, null); + RestTemplate rest = new RestTemplateBuilder().build(); + // Wait a bit before we verify + await().pollInterval(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(90)) + .until(() -> { + Boolean value = rest.getForObject("http://localhost:80/it", + Boolean.class); + log.info("Returned " + value + " from http://localhost:80/it"); + return value; + }); + + assertThat(rest.getForObject("http://localhost:80/it", Boolean.class)).isTrue(); + } + + @After + public void after() throws Exception { + api.deleteNamespacedService("rabbitmq-service", NAMESPACE, null, null, null, null, + null, null); + api.deleteNamespacedService(CONFIG_WATCHER_IT_IMAGE, NAMESPACE, null, null, null, + null, null, null); + api.deleteNamespacedService(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, NAMESPACE, + null, null, null, null, null, null); + + appsApi.deleteNamespacedDeployment( + SPRING_CLOUD_K8S_CONFIG_WATCHER_DEPLOYMENT_NAME, NAMESPACE, null, null, + null, null, null, null); + appsApi.deleteNamespacedDeployment( + SPRING_CLOUD_K8S_CONFIG_WATCHER_IT_DEPLOYMENT_NAME, NAMESPACE, null, null, + null, null, null, null); + + try { + api.deleteNamespacedReplicationController(RABBIT_MQ_CONTROLLER_NAME, + NAMESPACE, null, null, null, null, null, null); + } + catch (Exception e) { + // swallowing this exception, the delete does actually happen, its a problem + // downstream from the k8s + // client + // see + // https://github.com/kubernetes-client/java/issues/86#issuecomment-411234259 + } + + networkingApi.deleteNamespacedIngress("it-ingress", NAMESPACE, null, null, null, + null, null, null); + + api.deleteNamespacedConfigMap(SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME, NAMESPACE, + null, null, null, null, null, null); + api.deleteNamespacedConfigMap(CONFIG_WATCHER_IT_IMAGE, NAMESPACE, null, null, + null, null, null, null); + + } + + private void deployTestApp() throws Exception { + appsApi.createNamespacedDeployment(NAMESPACE, getItDeployment(), null, null, + null); + api.createNamespacedService(NAMESPACE, getItAppService(), null, null, null); + networkingApi.createNamespacedIngress(NAMESPACE, getItIngress(), null, null, + null); + } + + private void deployConfigWatcher() throws Exception { + api.createNamespacedConfigMap(NAMESPACE, getConfigWatcherConfigMap(), null, null, + null); + appsApi.createNamespacedDeployment(NAMESPACE, getConfigWatcherDeployment(), null, + null, null); + api.createNamespacedService(NAMESPACE, getConfigWatcherService(), null, null, + null); + } + + private void deployRabbitMQ() throws Exception { + api.createNamespacedService(NAMESPACE, getRabbitMQService(), null, null, null); + api.createNamespacedReplicationController(NAMESPACE, + getRabbitMQRepplicationController(), null, null, null); + } + + private V1Service getConfigWatcherService() throws Exception { + V1Service service = (V1Service) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-service.yaml"); + return service; + } + + private V1ConfigMap getConfigWatcherConfigMap() throws Exception { + V1ConfigMap configMap = (V1ConfigMap) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-configmap.yaml"); + return configMap; + } + + private V1Deployment getConfigWatcherDeployment() throws Exception { + V1Deployment deployment = (V1Deployment) k8SUtils.readYamlFromClasspath( + "spring-cloud-kubernetes-configuration-watcher-bus-deployment.yaml"); + return deployment; + } + + private V1Service getItAppService() throws Exception { + String urlString = "spring-cloud-kubernetes-configuration-watcher-it-service.yaml"; + V1Service service = (V1Service) k8SUtils.readYamlFromClasspath(urlString); + return service; + } + + private V1Deployment getItDeployment() throws Exception { + String urlString = "spring-cloud-kubernetes-configuration-watcher-it-deployment.yaml"; + V1Deployment deployment = (V1Deployment) k8SUtils + .readYamlFromClasspath(urlString); + return deployment; + } + + private NetworkingV1beta1Ingress getItIngress() throws Exception { + String urlString = "spring-cloud-kubernetes-configuration-watcher-it-ingress.yaml"; + NetworkingV1beta1Ingress ingress = (NetworkingV1beta1Ingress) k8SUtils + .readYamlFromClasspath(urlString); + return ingress; + } + + private V1ReplicationController getRabbitMQRepplicationController() throws Exception { + String urlString = "rabbitmq-controller.yaml"; + V1ReplicationController replicationController = (V1ReplicationController) k8SUtils + .readYamlFromClasspath(urlString); + return replicationController; + } + + private V1Service getRabbitMQService() throws Exception { + String urlString = "rabbitmq-service.yaml"; + V1Service service = (V1Service) k8SUtils.readYamlFromClasspath(urlString); + return service; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/K8SUtils.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/K8SUtils.java new file mode 100644 index 00000000..e953f956 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/K8SUtils.java @@ -0,0 +1,200 @@ +/* + * 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.configuration.watcher; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.time.Duration; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import io.kubernetes.client.ApiException; +import io.kubernetes.client.apis.AppsV1Api; +import io.kubernetes.client.apis.CoreV1Api; +import io.kubernetes.client.models.V1Deployment; +import io.kubernetes.client.models.V1DeploymentBuilder; +import io.kubernetes.client.models.V1DeploymentList; +import io.kubernetes.client.models.V1Endpoints; +import io.kubernetes.client.models.V1EndpointsList; +import io.kubernetes.client.models.V1EnvVar; +import io.kubernetes.client.models.V1ReplicationController; +import io.kubernetes.client.models.V1ReplicationControllerList; +import io.kubernetes.client.models.V1Service; +import io.kubernetes.client.models.V1ServiceBuilder; +import io.kubernetes.client.util.Yaml; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.fail; + +/** + * @author Ryan Baxter + */ +public class K8SUtils { + + private Log log = LogFactory.getLog(getClass()); + + private CoreV1Api api; + + private AppsV1Api appsApi; + + public K8SUtils(CoreV1Api api, AppsV1Api appsApi) { + this.api = api; + this.appsApi = appsApi; + } + + public Object readYaml(String urlString) throws Exception { + // create the url + URL url = new URL(urlString); + BufferedReader reader = null; + Object yamlObj = null; + try { + // open the url stream, wrap it an a few "readers" + reader = new BufferedReader(new InputStreamReader(url.openStream())); + yamlObj = Yaml.load(reader); + } + catch (Exception e) { + throw e; + } + finally { + if (reader != null) { + reader.close(); + } + } + return yamlObj; + } + + public Object readYamlFromClasspath(String fileName) throws Exception { + ClassLoader classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource(fileName).getFile()); + BufferedReader reader = null; + Object yamlObj = null; + try { + // open the url stream, wrap it an a few "readers" + reader = new BufferedReader(new FileReader(file)); + yamlObj = Yaml.load(reader); + } + catch (Exception e) { + throw e; + } + finally { + if (reader != null) { + reader.close(); + } + } + return yamlObj; + } + + public V1Service createService(String name, Map labels, + Map specSelectors, String type, String portName, int port, + int targetPort, String namespace) throws ApiException { + V1Service wiremockService = new V1ServiceBuilder().editOrNewMetadata() + .withName(name).addToLabels(labels).endMetadata().editOrNewSpec() + .addToSelector(specSelectors).withNewType(type).addNewPort() + .withName(portName).withPort(port).withNewTargetPort(targetPort).endPort() + .endSpec().build(); + return api.createNamespacedService(namespace, wiremockService, null, null, null); + } + + public V1Deployment createDeployment(String name, + Map selectorMatchLabels, + Map templateMetadataLabels, String containerName, + String image, String pullPolicy, int containerPort, int readinessProbePort, + String readinessProbePath, int livenessProbePort, String livenessProbePath, + String serviceAccountName, Collection envVars, String namespace) + throws ApiException { + + V1Deployment wiremockDeployment = new V1DeploymentBuilder().editOrNewMetadata() + .withName(name).endMetadata().editOrNewSpec().withNewSelector() + .addToMatchLabels(selectorMatchLabels).endSelector().editOrNewTemplate() + .editOrNewMetadata().addToLabels(templateMetadataLabels).endMetadata() + .editOrNewSpec().withServiceAccountName(serviceAccountName) + .addNewContainer().withName(containerName).withImage(image) + .withImagePullPolicy(pullPolicy).addNewPort() + .withContainerPort(containerPort).endPort().editOrNewReadinessProbe() + .editOrNewHttpGet().withNewPort(readinessProbePort) + .withNewPath(readinessProbePath).endHttpGet().endReadinessProbe() + .editOrNewLivenessProbe().editOrNewHttpGet() + .withNewPort(livenessProbePort).withNewPath(livenessProbePath) + .endHttpGet().endLivenessProbe().addAllToEnv(envVars).endContainer() + .endSpec().endTemplate().endSpec().build(); + return appsApi.createNamespacedDeployment(namespace, wiremockDeployment, null, + null, null); + + } + + public void waitForEndpointReady(String name, String namespace) throws Exception { + await().pollInterval(Duration.ofSeconds(1)).atMost(90, TimeUnit.SECONDS) + .until(() -> isEndpointReady(name, namespace)); + } + + public boolean isEndpointReady(String name, String namespace) throws ApiException { + V1EndpointsList endpoints = api.listNamespacedEndpoints(namespace, null, null, + "metadata.name=" + name, null, null, null, null, null); + if (endpoints.getItems().isEmpty()) { + fail("no endpoints for " + name); + } + V1Endpoints endpoint = endpoints.getItems().get(0); + return endpoint.getSubsets().get(0).getAddresses().size() >= 1; + } + + public void waitForReplicationController(String name, String namespace) { + await().pollInterval(Duration.ofSeconds(1)).atMost(90, TimeUnit.SECONDS) + .until(() -> isReplicationControllerReady(name, namespace)); + } + + public boolean isReplicationControllerReady(String name, String namespace) + throws ApiException { + V1ReplicationControllerList controllerList = api + .listNamespacedReplicationController(namespace, null, null, + "metadata.name=" + name, null, null, null, null, null); + if (controllerList.getItems().size() < 1) { + fail("Replication controller with name " + name + "could not be found"); + } + + V1ReplicationController replicationController = controllerList.getItems().get(0); + Integer availableReplicas = replicationController.getStatus() + .getAvailableReplicas(); + log.info("Available replicas for " + name + ": " + availableReplicas); + return availableReplicas != null && availableReplicas >= 1; + + } + + public void waitForDeployment(String deploymentName, String namespace) { + await().pollInterval(Duration.ofSeconds(1)).atMost(90, TimeUnit.SECONDS) + .until(() -> isDeployentReady(deploymentName, namespace)); + } + + public boolean isDeployentReady(String deploymentName, String namespace) + throws ApiException { + V1DeploymentList deployments = appsApi.listNamespacedDeployment(namespace, null, + null, "metadata.name=" + deploymentName, null, null, null, null, null); + if (deployments.getItems().size() < 1) { + fail("No deployments with the name " + deploymentName); + } + V1Deployment deployment = deployments.getItems().get(0); + Integer availableReplicas = deployment.getStatus().getAvailableReplicas(); + log.info("Available replicas for " + deploymentName + ": " + availableReplicas); + return availableReplicas != null && availableReplicas >= 1; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-controller.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-controller.yaml new file mode 100644 index 00000000..81dd5aec --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-controller.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + labels: + component: rabbitmq + name: rabbitmq-controller +spec: + replicas: 1 + template: + metadata: + labels: + app: taskQueue + component: rabbitmq + spec: + containers: + - image: rabbitmq:3-management + name: rabbitmq + ports: + - name: amqp + containerPort: 5672 + - name: http-stats + containerPort: 15672 + readinessProbe: + httpGet: + port: 15672 + path: /api/healthchecks/node + httpHeaders: + - name: Authorization + value: Basic Z3Vlc3Q6Z3Vlc3Q= +# livenessProbe: +# httpGet: +# port: 15672 +# path: /api/healthchecks/node +# httpHeaders: +# - name: Authorization +# value: Basic Z3Vlc3Q6Z3Vlc3Q= diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-service.yaml new file mode 100644 index 00000000..e960e5f4 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/rabbitmq-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + component: rabbitmq + name: rabbitmq-service +spec: + ports: + - port: 5672 + name: amqp + targetPort: 5672 + - port: 15672 + name: http-stats + targetPort: 15672 + selector: + app: taskQueue + component: rabbitmq diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-bus-deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-bus-deployment.yaml new file mode 100644 index 00000000..2a6bd3e5 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-bus-deployment.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-configuration-watcher-deployment +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + spec: + serviceAccountName: spring-cloud-kubernetes-serviceaccount + containers: + - name: spring-cloud-kubernetes-configuration-watcher + image: localhost:5000/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + env: + - name: SPRING_PROFILES_ACTIVE + value: bus + - name: SPRING_RABBITMQ_HOST + value: rabbitmq-service + readinessProbe: + httpGet: + port: 8888 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8888 + path: /actuator/health/liveness + ports: + - containerPort: 8888 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-configmap.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-configmap.yaml new file mode 100644 index 00000000..9c2ea62e --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + application.properties: |- + # Set the refresh interval to 0 so the refresh event gets sent immediately + spring.cloud.kubernetes.configuration.watcher.refreshDelay=0 + logging.level.org.springframework.cloud.kubernetes=TRACE +kind: ConfigMap +metadata: + name: spring-cloud-kubernetes-configuration-watcher diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml new file mode 100644 index 00000000..68089e13 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-http-deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-configuration-watcher-deployment +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + spec: + serviceAccountName: spring-cloud-kubernetes-serviceaccount + containers: + - name: spring-cloud-kubernetes-configuration-watcher + image: localhost:5000/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8888 + path: /actuator/health/readiness + livenessProbe: + httpGet: + port: 8888 + path: /actuator/health/liveness + ports: + - containerPort: 8888 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-deployment.yaml new file mode 100644 index 00000000..949adc28 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-cloud-kubernetes-configuration-watcher-it-deployment +spec: + selector: + matchLabels: + app: spring-cloud-kubernetes-configuration-watcher-it + template: + metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher-it + spec: + containers: + - name: spring-cloud-kubernetes-configuration-watcher-it + image: localhost:5000/spring-cloud-kubernetes-configuration-watcher-it:2.0.0-SNAPSHOT + imagePullPolicy: IfNotPresent + env: + - name: SPRING_RABBITMQ_HOST + value: rabbitmq-service + 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-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-ingress.yaml new file mode 100644 index 00000000..8f8d3473 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-ingress.yaml @@ -0,0 +1,14 @@ +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: it-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + rules: + - http: + paths: + - path: /it(/|$)(.*) + backend: + serviceName: spring-cloud-kubernetes-configuration-watcher-it + servicePort: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-service.yaml new file mode 100644 index 00000000..7b8a1c21 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-it-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher-it + name: spring-cloud-kubernetes-configuration-watcher-it +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: spring-cloud-kubernetes-configuration-watcher-it + type: ClusterIP diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-service.yaml new file mode 100644 index 00000000..c8496317 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/spring-cloud-kubernetes-configuration-watcher-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: spring-cloud-kubernetes-configuration-watcher + name: spring-cloud-kubernetes-configuration-watcher +spec: + ports: + - name: http + port: 8888 + targetPort: 8888 + selector: + app: spring-cloud-kubernetes-configuration-watcher + type: ClusterIP diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-deployment.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-deployment.yaml new file mode 100644 index 00000000..2ee9b179 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: config-watcher-wiremock-deployment +spec: + selector: + matchLabels: + app: config-watcher-wiremock + template: + metadata: + labels: + app: config-watcher-wiremock + spec: + containers: + - name: config-watcher-wiremock + image: rodolpheche/wiremock + imagePullPolicy: IfNotPresent + readinessProbe: + httpGet: + port: 8080 + path: /__admin/mappings + livenessProbe: + httpGet: + port: 8080 + path: /__admin/mappings + ports: + - containerPort: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-ingress.yaml new file mode 100644 index 00000000..bf6835a0 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-ingress.yaml @@ -0,0 +1,14 @@ +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: nginx-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + rules: + - http: + paths: + - path: /wiremock(/|$)(.*) + backend: + serviceName: config-watcher-wiremock + servicePort: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-service.yaml new file mode 100644 index 00000000..559c7645 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/resources/wiremock-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: config-watcher-wiremock + name: config-watcher-wiremock +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: config-watcher-wiremock + type: ClusterIP diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index c4698b11..b7714c41 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -12,4 +12,5 @@ + From e27dbbc66d8f4dfacc8385b8918aaf8165b0f596 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Wed, 22 Jul 2020 17:18:06 -0400 Subject: [PATCH 16/30] Updating dockerhub org name --- README.adoc | 2 +- .../asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc | 2 +- .../k8s/deployment.yaml | 2 +- .../spring-cloud-kubernetes-configuration-watcher/pom.xml | 2 +- .../spring-cloud-kubernetes-configuration-watcher/skaffold.yaml | 2 +- .../deployment-it.yaml | 2 +- .../spring-cloud-kubernetes-configuration-watcher-it/pom.xml | 2 +- .../kubernetes/configuration/watcher/ActuatorRefreshIT.java | 2 +- .../configuration/watcher/ActuatorRefreshRabbitMQIT.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.adoc b/README.adoc index a01f5dca..8e0aa682 100644 --- a/README.adoc +++ b/README.adoc @@ -955,7 +955,7 @@ items: serviceAccount: spring-cloud-kubernetes-configuration-watcher containers: - name: spring-cloud-kubernetes-configuration-watcher - image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + image: springcloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT imagePullPolicy: IfNotPresent readinessProbe: httpGet: diff --git a/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc index 0801d56f..af2586b1 100644 --- a/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc +++ b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc @@ -87,7 +87,7 @@ items: serviceAccount: spring-cloud-kubernetes-configuration-watcher containers: - name: spring-cloud-kubernetes-configuration-watcher - image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + image: springcloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT imagePullPolicy: IfNotPresent readinessProbe: httpGet: diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml index 025cd71f..9404f7b7 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/k8s/deployment.yaml @@ -60,7 +60,7 @@ items: serviceAccount: spring-cloud-kubernetes-configuration-watcher containers: - name: spring-cloud-kubernetes-configuration-watcher - image: spring-cloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT + image: springcloud/spring-cloud-kubernetes-configuration-watcher:2.0.0-SNAPSHOT imagePullPolicy: IfNotPresent readinessProbe: httpGet: diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml index c0377dc8..552e1aa0 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml @@ -102,7 +102,7 @@ - spring-cloud/${project.artifactId}:${project.version} + springcloud/${project.artifactId}:${project.version} diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml index 345fe104..4157f0d4 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/skaffold.yaml @@ -4,7 +4,7 @@ metadata: name: spring-cloud-kubernetes-configuration-watcher build: artifacts: - - image: spring-cloud/spring-cloud-kubernetes-configuration-watcher + - image: springcloud/spring-cloud-kubernetes-configuration-watcher custom: buildCommand: "../../mvnw clean install" dependencies: diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml index a9d91dc6..7d513fab 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/deployment-it.yaml @@ -18,7 +18,7 @@ spec: app: k8s-demo-app spec: containers: - - image: docker.io/spring-cloud/spring-cloud-kubernetes-configuration-watcher-it:2.0.0-SNAPSHOT + - image: docker.io/springcloud/spring-cloud-kubernetes-configuration-watcher-it:2.0.0-SNAPSHOT name: spring-cloud-kubernetes-configuration-watcher-it resources: {} env: diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml index 4897f9c0..c01b65a2 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml @@ -88,7 +88,7 @@ spring-boot-maven-plugin - spring-cloud/${project.artifactId}:${project.version} + springcloud/${project.artifactId}:${project.version} build-image 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 e0c15ee2..c8d67adc 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 @@ -65,7 +65,7 @@ public class ActuatorRefreshIT { private static final String IMAGE_TAG = "2.0.0-SNAPSHOT"; - private static final String LOCAL_REPO = "docker.io/spring-cloud"; + private static final String LOCAL_REPO = "docker.io/springcloud"; private static final String LOCAL_IMAGE = LOCAL_REPO + "/" + IMAGE + ":" + IMAGE_TAG; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java index a3158ba6..3ce5e2da 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshRabbitMQIT.java @@ -68,7 +68,7 @@ public class ActuatorRefreshRabbitMQIT { private static final String IMAGE_TAG = "2.0.0-SNAPSHOT"; - private static final String LOCAL_REPO = "docker.io/spring-cloud"; + private static final String LOCAL_REPO = "docker.io/springcloud"; private static final String CONFIG_WATCHER_LOCAL_IMAGE = LOCAL_REPO + "/" + CONFIG_WATCHER_IMAGE + ":" + IMAGE_TAG; From 208a3704b9ec7e9444f5ae11f0f4cbb55685e6ce Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 23 Jul 2020 19:27:22 +0000 Subject: [PATCH 17/30] Update SNAPSHOT to 2.0.0-M3 --- docs/pom.xml | 2 +- pom.xml | 12 ++++++------ spring-cloud-kubernetes-config/pom.xml | 2 +- spring-cloud-kubernetes-controllers/pom.xml | 2 +- .../pom.xml | 2 +- spring-cloud-kubernetes-core/pom.xml | 2 +- spring-cloud-kubernetes-dependencies/pom.xml | 4 ++-- spring-cloud-kubernetes-discovery/pom.xml | 2 +- .../kubernetes-hello-world-example/pom.xml | 2 +- .../kubernetes-leader-election-example/pom.xml | 2 +- .../kubernetes-reload-example/pom.xml | 2 +- spring-cloud-kubernetes-examples/pom.xml | 2 +- .../discovery/discovery-client/pom.xml | 2 +- .../discovery/discovery-service-a/pom.xml | 2 +- .../discovery/discovery-service-b/pom.xml | 2 +- .../discovery/pom.xml | 2 +- .../discovery/tests/pom.xml | 2 +- .../istio/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/pom.xml | 2 +- .../simple-configmap/pom.xml | 2 +- .../simple-core/pom.xml | 2 +- .../pom.xml | 2 +- spring-cloud-kubernetes-istio/pom.xml | 2 +- spring-cloud-kubernetes-leader/pom.xml | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- spring-cloud-starter-kubernetes-config/pom.xml | 2 +- spring-cloud-starter-kubernetes/pom.xml | 2 +- 27 files changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 80413d89..e2ab1a1d 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 jar Spring Cloud Kubernetes Docs diff --git a/pom.xml b/pom.xml index 078bf347..04c2d96b 100644 --- a/pom.xml +++ b/pom.xml @@ -24,13 +24,13 @@ org.springframework.cloud spring-cloud-build - 3.0.0-SNAPSHOT + 3.0.0-M3 org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 pom Spring Cloud Kubernetes @@ -63,10 +63,10 @@ - 3.0.0-SNAPSHOT - 3.0.0-SNAPSHOT - 3.0.0-SNAPSHOT - 3.0.0-SNAPSHOT + 3.0.0-M3 + 3.0.0-M3 + 3.0.0-M3 + 3.0.0-M3 3.5 diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index c5df2ea0..6a1e1910 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-controllers/pom.xml b/spring-cloud-kubernetes-controllers/pom.xml index 5be61521..cb4dffdd 100644 --- a/spring-cloud-kubernetes-controllers/pom.xml +++ b/spring-cloud-kubernetes-controllers/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 pom diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml index 552e1aa0..393323e4 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-controllers org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index 112105a6..05985c60 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index e2c50435..fd284198 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -23,11 +23,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.0-SNAPSHOT + 3.0.0-M3 spring-cloud-kubernetes-dependencies - 2.0.0-SNAPSHOT + 2.0.0-M3 pom Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index 80c18886..2be2749d 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index 2e92c3de..2320b028 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index ae237902..83d460ac 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes-examples - 2.0.0-SNAPSHOT + 2.0.0-M3 kubernetes-leader-election-example diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index 15fe55b5..ad6f9e29 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index adce1fcb..2e2599dd 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index 09e8a156..1386b39a 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-SNAPSHOT + 2.0.0-M3 discovery-client diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index 0df6efb0..4d557a68 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-SNAPSHOT + 2.0.0-M3 discovery-service-a diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index ddcd6b8b..12397cdb 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-SNAPSHOT + 2.0.0-M3 discovery-service-b diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index bbef858b..1d318d33 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-SNAPSHOT + 2.0.0-M3 Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index 97fd9aa3..0aedf57e 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-SNAPSHOT + 2.0.0-M3 tests diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index 1782ed11..52b2e2b5 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-SNAPSHOT + 2.0.0-M3 Spring Cloud Kubernetes :: Integration Tests :: Istio diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index 5e6f91a5..41021166 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 spring-cloud-kubernetes-integration-tests diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 37ebae6e..2560a5ed 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-SNAPSHOT + 2.0.0-M3 Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 41cd2ce2..851906be 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-SNAPSHOT + 2.0.0-M3 Spring Cloud Kubernetes :: Integration Tests :: Simple Core diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml index c01b65a2..57d5a0c9 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index 0d5e51d6..b67bcea6 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index 64932d90..d62e1c01 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-SNAPSHOT + 2.0.0-M3 spring-cloud-kubernetes-leader diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index b0d46cb5..c89f2225 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index 35b167b4..b24fc1f2 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index 9b17a860..7a977cf1 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-SNAPSHOT + 2.0.0-M3 4.0.0 From 090c970d4f19e9ae604359fe4437c331ac7e58e0 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 23 Jul 2020 19:29:15 +0000 Subject: [PATCH 18/30] Going back to snapshots --- docs/pom.xml | 2 +- pom.xml | 12 ++++++------ spring-cloud-kubernetes-config/pom.xml | 2 +- spring-cloud-kubernetes-controllers/pom.xml | 2 +- .../pom.xml | 2 +- spring-cloud-kubernetes-core/pom.xml | 2 +- spring-cloud-kubernetes-dependencies/pom.xml | 4 ++-- spring-cloud-kubernetes-discovery/pom.xml | 2 +- .../kubernetes-hello-world-example/pom.xml | 2 +- .../kubernetes-leader-election-example/pom.xml | 2 +- .../kubernetes-reload-example/pom.xml | 2 +- spring-cloud-kubernetes-examples/pom.xml | 2 +- .../discovery/discovery-client/pom.xml | 2 +- .../discovery/discovery-service-a/pom.xml | 2 +- .../discovery/discovery-service-b/pom.xml | 2 +- .../discovery/pom.xml | 2 +- .../discovery/tests/pom.xml | 2 +- .../istio/pom.xml | 2 +- spring-cloud-kubernetes-integration-tests/pom.xml | 2 +- .../simple-configmap/pom.xml | 2 +- .../simple-core/pom.xml | 2 +- .../pom.xml | 2 +- spring-cloud-kubernetes-istio/pom.xml | 2 +- spring-cloud-kubernetes-leader/pom.xml | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- spring-cloud-starter-kubernetes-config/pom.xml | 2 +- spring-cloud-starter-kubernetes/pom.xml | 2 +- 27 files changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index e2ab1a1d..80413d89 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT jar Spring Cloud Kubernetes Docs diff --git a/pom.xml b/pom.xml index 04c2d96b..078bf347 100644 --- a/pom.xml +++ b/pom.xml @@ -24,13 +24,13 @@ org.springframework.cloud spring-cloud-build - 3.0.0-M3 + 3.0.0-SNAPSHOT org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT pom Spring Cloud Kubernetes @@ -63,10 +63,10 @@ - 3.0.0-M3 - 3.0.0-M3 - 3.0.0-M3 - 3.0.0-M3 + 3.0.0-SNAPSHOT + 3.0.0-SNAPSHOT + 3.0.0-SNAPSHOT + 3.0.0-SNAPSHOT 3.5 diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index 6a1e1910..c5df2ea0 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-controllers/pom.xml b/spring-cloud-kubernetes-controllers/pom.xml index cb4dffdd..5be61521 100644 --- a/spring-cloud-kubernetes-controllers/pom.xml +++ b/spring-cloud-kubernetes-controllers/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 pom diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml index 393323e4..552e1aa0 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-controllers org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-core/pom.xml b/spring-cloud-kubernetes-core/pom.xml index 05985c60..112105a6 100644 --- a/spring-cloud-kubernetes-core/pom.xml +++ b/spring-cloud-kubernetes-core/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index fd284198..e2c50435 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -23,11 +23,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 3.0.0-M3 + 3.0.0-SNAPSHOT spring-cloud-kubernetes-dependencies - 2.0.0-M3 + 2.0.0-SNAPSHOT pom Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies diff --git a/spring-cloud-kubernetes-discovery/pom.xml b/spring-cloud-kubernetes-discovery/pom.xml index 2be2749d..80c18886 100644 --- a/spring-cloud-kubernetes-discovery/pom.xml +++ b/spring-cloud-kubernetes-discovery/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml index 2320b028..2e92c3de 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index 83d460ac..ae237902 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes-examples - 2.0.0-M3 + 2.0.0-SNAPSHOT kubernetes-leader-election-example diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml index ad6f9e29..15fe55b5 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes-examples org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-examples/pom.xml b/spring-cloud-kubernetes-examples/pom.xml index 2e2599dd..adce1fcb 100644 --- a/spring-cloud-kubernetes-examples/pom.xml +++ b/spring-cloud-kubernetes-examples/pom.xml @@ -23,7 +23,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml index 1386b39a..09e8a156 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-client/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-M3 + 2.0.0-SNAPSHOT discovery-client diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml index 4d557a68..0df6efb0 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-a/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-M3 + 2.0.0-SNAPSHOT discovery-service-a diff --git a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml index 12397cdb..ddcd6b8b 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/discovery-service-b/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-M3 + 2.0.0-SNAPSHOT discovery-service-b diff --git a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml index 1d318d33..bbef858b 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-M3 + 2.0.0-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent diff --git a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml index 0aedf57e..97fd9aa3 100644 --- a/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/discovery/tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud discovery-parent - 2.0.0-M3 + 2.0.0-SNAPSHOT tests diff --git a/spring-cloud-kubernetes-integration-tests/istio/pom.xml b/spring-cloud-kubernetes-integration-tests/istio/pom.xml index 52b2e2b5..1782ed11 100644 --- a/spring-cloud-kubernetes-integration-tests/istio/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/istio/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-M3 + 2.0.0-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Istio diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index 41021166..5e6f91a5 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT spring-cloud-kubernetes-integration-tests diff --git a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml index 2560a5ed..37ebae6e 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-configmap/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-M3 + 2.0.0-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap diff --git a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml index 851906be..41cd2ce2 100644 --- a/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/simple-core/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-M3 + 2.0.0-SNAPSHOT Spring Cloud Kubernetes :: Integration Tests :: Simple Core diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml index 57d5a0c9..c01b65a2 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-configuration-watcher-it/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-kubernetes-integration-tests - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-istio/pom.xml b/spring-cloud-kubernetes-istio/pom.xml index b67bcea6..0d5e51d6 100644 --- a/spring-cloud-kubernetes-istio/pom.xml +++ b/spring-cloud-kubernetes-istio/pom.xml @@ -5,7 +5,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-leader/pom.xml b/spring-cloud-kubernetes-leader/pom.xml index d62e1c01..64932d90 100644 --- a/spring-cloud-kubernetes-leader/pom.xml +++ b/spring-cloud-kubernetes-leader/pom.xml @@ -22,7 +22,7 @@ org.springframework.cloud spring-cloud-kubernetes - 2.0.0-M3 + 2.0.0-SNAPSHOT spring-cloud-kubernetes-leader diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index c89f2225..b0d46cb5 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes-config/pom.xml b/spring-cloud-starter-kubernetes-config/pom.xml index b24fc1f2..35b167b4 100644 --- a/spring-cloud-starter-kubernetes-config/pom.xml +++ b/spring-cloud-starter-kubernetes-config/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-starter-kubernetes/pom.xml b/spring-cloud-starter-kubernetes/pom.xml index 7a977cf1..9b17a860 100644 --- a/spring-cloud-starter-kubernetes/pom.xml +++ b/spring-cloud-starter-kubernetes/pom.xml @@ -22,7 +22,7 @@ spring-cloud-kubernetes org.springframework.cloud - 2.0.0-M3 + 2.0.0-SNAPSHOT 4.0.0 From a53935f4fa137aad005f4f9f13f947490a273cc9 Mon Sep 17 00:00:00 2001 From: Haytham Mohamed Date: Mon, 27 Jul 2020 11:57:28 -0500 Subject: [PATCH 19/30] upgrading okhttp3 from 3.12.0 to 3.14.4 fixes gh-504 --- spring-cloud-kubernetes-dependencies/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 1642c08d..dd481ba3 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -37,7 +37,7 @@ 4.10.3 1.0.0 0.1.2 - 3.12.0 + 3.14.4 From 57bfaa38841e1ed1265896ad4ff52d9daa6fc574 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 30 Jul 2020 16:49:45 -0400 Subject: [PATCH 20/30] Do not use settings.xml in circleci build --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2fe21bbd..205df285 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,7 +33,7 @@ jobs: - run: name: dependencies command: | - ./mvnw -s .settings.xml -U --fail-never dependency:go-offline -Dservice.occurence=${_SERVICE_OCCURENCE} || true + ./mvnw -U --fail-never dependency:go-offline -Dservice.occurence=${_SERVICE_OCCURENCE} || true - save_cache: paths: - ~/.m2 @@ -41,7 +41,7 @@ jobs: - run: name: Run regular tests command: | - ./mvnw -s .settings.xml clean install -Dservice.occurence=${_SERVICE_OCCURENCE} #org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + ./mvnw clean install -Dservice.occurence=${_SERVICE_OCCURENCE} #org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn mkdir -p $HOME/artifacts/junit/ find . -type f -regex ".*/spring-cloud-*.*/target/*.*" -exec cp {} $HOME/artifacts/ \; find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} $HOME/artifacts/junit/ \; From 09237a07ceac82367a60585f190b98f02894a1f4 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Fri, 31 Jul 2020 14:54:56 -0400 Subject: [PATCH 21/30] fixes checkstyle --- .../cloud/kubernetes/ribbon/RibbonFallbackTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java index bb14424b..e71cdaf7 100644 --- a/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java +++ b/spring-cloud-kubernetes-ribbon/src/test/java/org/springframework/cloud/kubernetes/ribbon/RibbonFallbackTest.java @@ -100,7 +100,7 @@ public class RibbonFallbackTest { .addNewAddress() .withIp(mockServer.getHostName()) .endAddress() - .addNewPort("http", "http_tcp",mockServer.getPort(), "http") + .addNewPort("http", "http_tcp", mockServer.getPort(), "http") .endSubset() .build(); // @formatter:on From a340afa2683c65e730ed3f53998ec40864a62749 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Thu, 6 Aug 2020 16:18:29 -0400 Subject: [PATCH 22/30] Disables broken tests. See https://github.com/spring-cloud/spring-cloud-kubernetes/issues/603 --- .../reactive/KubernetesReactiveDiscoveryClientTests.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java index a09e7cad..6c89ba81 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/reactive/KubernetesReactiveDiscoveryClientTests.java @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import reactor.core.publisher.Flux; @@ -112,6 +113,7 @@ class KubernetesReactiveDiscoveryClientTests { } @Test + @Disabled // see gh-603 public void shouldReturnEmptyFluxForNonExistingService( @Client KubernetesClient kubernetesClient) { KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); @@ -122,6 +124,7 @@ class KubernetesReactiveDiscoveryClientTests { } @Test + @Disabled // see gh-603 public void shouldReturnEmptyFluxWhenServiceHasNoSubsets( @Client KubernetesClient kubernetesClient, @Server KubernetesServer kubernetesServer) { @@ -144,6 +147,7 @@ class KubernetesReactiveDiscoveryClientTests { } @Test + @Disabled // see gh-603 public void shouldReturnFlux(@Client KubernetesClient kubernetesClient, @Server KubernetesServer kubernetesServer) { kubernetesServer.expect().get().withPath("/api/v1/namespaces/test/services") @@ -187,6 +191,7 @@ class KubernetesReactiveDiscoveryClientTests { } @Test + @Disabled // see gh-603 public void shouldReturnFluxWithPrefixedMetadata( @Client KubernetesClient kubernetesClient, @Server KubernetesServer kubernetesServer) { @@ -234,6 +239,7 @@ class KubernetesReactiveDiscoveryClientTests { } @Test + @Disabled // see gh-603 public void shouldReturnFluxWhenServiceHasMultiplePortsAndPrimaryPortNameIsSet( @Client KubernetesClient kubernetesClient, @Server KubernetesServer kubernetesServer) { From bc553934231593f867f15f648dc336674cdf4702 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Thu, 6 Aug 2020 16:20:23 -0400 Subject: [PATCH 23/30] Removes unneeded stubs --- .../kubernetes/discovery/KubernetesCatalogWatchTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index e7832947..257787cb 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -88,7 +88,6 @@ public class KubernetesCatalogWatchTest { createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", "api-pod")); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) .thenReturn(this.endpointsOperation); @@ -128,7 +127,6 @@ public class KubernetesCatalogWatchTest { createEndpointsListByServiceName("api-service", "other-service")) .thenReturn( createEndpointsListByServiceName("other-service", "api-service")); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) .thenReturn(this.endpointsOperation); @@ -147,7 +145,6 @@ public class KubernetesCatalogWatchTest { createEndpointsListByServiceName("api-service", "other-service")) .thenReturn( createEndpointsListByServiceName("other-service", "api-service")); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) .thenReturn(this.endpointsOperation); @@ -186,7 +183,6 @@ public class KubernetesCatalogWatchTest { public void testEventBodyAllNamespaces() throws Exception { when(this.endpointsOperation.list()).thenReturn( createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) .thenReturn(this.endpointsOperation); @@ -268,7 +264,6 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); endpoints.getItems().get(0).getSubsets().get(0).setAddresses(null); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) @@ -310,7 +305,6 @@ public class KubernetesCatalogWatchTest { endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0) .setTargetRef(null); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) From ccc4b5d8fbc7dc8c62aaf2f3b1992503396d1cfa Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 10 Aug 2020 16:06:19 -0400 Subject: [PATCH 24/30] Updates to use new spring-cloud-starter-bootstrap. This opts in to enabling bootstrap via the classpath. If s-c-k8s gets a ConfigData impl, this may need to change to put the property on individual tests. --- spring-cloud-kubernetes-config/pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-config/pom.xml b/spring-cloud-kubernetes-config/pom.xml index c5df2ea0..c6fc4afd 100644 --- a/spring-cloud-kubernetes-config/pom.xml +++ b/spring-cloud-kubernetes-config/pom.xml @@ -54,7 +54,12 @@ org.springframework.cloud - spring-cloud-context + spring-cloud-starter + + + + org.springframework.cloud + spring-cloud-starter-bootstrap From ddc53c26af2cb64c8c1f11f0da51d2283624eaea Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 10 Aug 2020 16:11:08 -0400 Subject: [PATCH 25/30] Removes unneeded stubs --- .../cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index 257787cb..6a49db24 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -162,7 +162,6 @@ public class KubernetesCatalogWatchTest { public void testEventBody() throws Exception { when(this.endpointsOperation.list()).thenReturn( createSingleEndpointEndpointListByPodName("api-pod", "other-pod")); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) .thenReturn(this.endpointsOperation); @@ -206,7 +205,6 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListWithoutSubsets(); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) @@ -285,7 +283,6 @@ public class KubernetesCatalogWatchTest { endpoints.getItems().get(0).getSubsets().get(0).getAddresses().get(0) .setTargetRef(null); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) From af821b641a13f3c5f3acacc9082106a177b35e0d Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 10 Aug 2020 16:16:25 -0400 Subject: [PATCH 26/30] Removes unneeded stubs --- .../cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index 6a49db24..351ce991 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -106,7 +106,6 @@ public class KubernetesCatalogWatchTest { createSingleEndpointEndpointListByPodName("api-pod", "other-pod")) .thenReturn(createSingleEndpointEndpointListByPodName("other-pod", "api-pod")); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) .thenReturn(this.endpointsOperation); From 561003ffbc1dcb4598746b5b21ef389aca2453be Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 10 Aug 2020 16:29:54 -0400 Subject: [PATCH 27/30] Removes unneeded stubs --- .../cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java index 351ce991..19075075 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesCatalogWatchTest.java @@ -221,7 +221,6 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListWithoutSubsets(); - when(this.properties.isAllNamespaces()).thenReturn(true); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().inAnyNamespace()) @@ -242,7 +241,6 @@ public class KubernetesCatalogWatchTest { EndpointsList endpoints = createSingleEndpointEndpointListByPodName("api-pod"); endpoints.getItems().get(0).getSubsets().get(0).setAddresses(null); - when(this.properties.isAllNamespaces()).thenReturn(false); when(this.endpointsOperation.list()).thenReturn(endpoints); when(this.kubernetesClient.endpoints()).thenReturn(this.endpointsOperation); when(this.kubernetesClient.endpoints().withLabels(anyMap())) From b2bbff6642fb051f97fd47b5bc444efd8059ad19 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Wed, 12 Aug 2020 11:48:04 -0400 Subject: [PATCH 28/30] Changes to add dockerfile-maven-plugin --- .../pom.xml | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml index 552e1aa0..89ede593 100644 --- a/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml +++ b/spring-cloud-kubernetes-controllers/spring-cloud-kubernetes-configuration-watcher/pom.xml @@ -14,6 +14,8 @@ 1.8.0 openjdk:8u222-slim + springcloud + 4.1.0 @@ -93,10 +95,37 @@ + + dockerpush + + + + com.spotify + dockerfile-maven-plugin + 1.4.12 + + ${docker.registry.organization}/${artifactId} + ${project.version} + ${env.DOCKER_HUB_USERNAME} + ${env.DOCKER_HUB_PASSWORD} + + true + + + + + org.codehaus.plexus + plexus-archiver + ${plexus-archiver.version} + + + + + + imagename - !env.IMAGE From 26ba69a9034e3c75822b94ed493cc63790e645de Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Wed, 12 Aug 2020 16:42:28 -0400 Subject: [PATCH 29/30] Updating documentation with link to Docker Hub repo --- .../asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc index af2586b1..d1f737d9 100644 --- a/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc +++ b/docs/src/main/asciidoc/spring-cloud-kubernetes-configuration-watcher.adoc @@ -11,7 +11,7 @@ actuator endpoint `/refresh` or via publishing a `RefreshRemoteApplicationEvent` To achieve this configuration refresh of a Spring Cloud app running on Kubernetes, you can deploy the Spring Cloud Kubernetes Configuration Watcher controller into your Kubernetes cluster. -The application is published as a container and is available on Docker Hub. +The application is published as a container and is available on https://hub.docker.com/repository/docker/springcloud/spring-cloud-kubernetes-configuration-watcher[Docker Hub]. Spring Cloud Kubernetes Configuration Watcher can send refresh notifications to applications in two ways. From b158fd8aa3bb6e7bdcde31cabb88ebee643e8cf4 Mon Sep 17 00:00:00 2001 From: buildmaster Date: Thu, 13 Aug 2020 11:48:18 +0000 Subject: [PATCH 30/30] Bumping versions --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 8e0aa682..b90afb99 100644 --- a/README.adoc +++ b/README.adoc @@ -879,7 +879,7 @@ actuator endpoint `/refresh` or via publishing a `RefreshRemoteApplicationEvent` To achieve this configuration refresh of a Spring Cloud app running on Kubernetes, you can deploy the Spring Cloud Kubernetes Configuration Watcher controller into your Kubernetes cluster. -The application is published as a container and is available on Docker Hub. +The application is published as a container and is available on https://hub.docker.com/repository/docker/springcloud/spring-cloud-kubernetes-configuration-watcher[Docker Hub]. Spring Cloud Kubernetes Configuration Watcher can send refresh notifications to applications in two ways.