From 7aabfcc44628643ae23dfe22be0deb77d2a2ad4b Mon Sep 17 00:00:00 2001 From: piomin Date: Sun, 7 Jun 2020 23:14:33 +0200 Subject: [PATCH 01/24] #516 Adding spring-cloud-starter-loadbalancer to spring-cloud-starter-kubernetes-all and provide integration tests inside module spring-cloud-kubernetes-integration-tests --- .../load-balancer/pom.xml | 36 +++++++++ .../loadbalancer/SimpleLoadBalancerApp.java | 31 ++++++++ .../LoadBalancerAllNamespacesTest.java | 71 ++++++++++++++++++ .../loadbalancer/LoadBalancerTest.java | 74 +++++++++++++++++++ .../pom.xml | 1 + spring-cloud-starter-kubernetes-all/pom.xml | 5 ++ 6 files changed, 218 insertions(+) create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml new file mode 100644 index 00000000..4f69d13b --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -0,0 +1,36 @@ + + + + spring-cloud-kubernetes-integration-tests + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + + load-balancer + + + + org.springframework.cloud + spring-cloud-starter-kubernetes-all + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + io.fabric8 + kubernetes-server-mock + 4.10.2 + test + + + + diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java new file mode 100644 index 00000000..84ef41c8 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java @@ -0,0 +1,31 @@ +package org.spring.framework.kubernetes.loadbalancer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +@RestController +public class SimpleLoadBalancerApp { + + public static void main(String[] args) { + SpringApplication.run(SimpleLoadBalancerApp.class, args); + } + + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplateBuilder().build(); + } + + @GetMapping("/greeting") + public String greeting() { + return "greeting"; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java new file mode 100644 index 00000000..e9533cb8 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java @@ -0,0 +1,71 @@ +package org.springframework.kubernetes.loadbalancer; + +import java.util.List; + +import io.fabric8.kubernetes.api.model.Endpoints; +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, + properties = {"spring.cloud.kubernetes.discovery.all-namespaces=true"}) +@RunWith(SpringRunner.class) +public class LoadBalancerAllNamespacesTest { + + @Autowired + RestTemplate restTemplate; + @ClassRule + public static KubernetesServer server = new KubernetesServer(true, true); + + private static KubernetesClient client; + + @BeforeClass + public static void setup() { + client = server.getClient(); + + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); + } + + @Test + public void testLoadBalancerDifferentNamespace() { + createTestData("service-b", "b"); + String response = restTemplate.getForObject("http://service-b/greeting", String.class); + Assertions.assertNotNull(response); + Assertions.assertEquals("greeting", response); + } + + private void createTestData(String name, String namespace) { + client.services().inNamespace(namespace).createNew() + .withNewMetadata().withName(name).withNamespace(namespace).endMetadata() + .withSpec(new ServiceSpecBuilder() + .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) + .build()) + .done(); + client.endpoints().inNamespace(namespace).createNew() + .withNewMetadata().withName("service-a").withNamespace(namespace).endMetadata() + .addNewSubset() + .addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort() + .endSubset() + .done(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java new file mode 100644 index 00000000..09f24730 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java @@ -0,0 +1,74 @@ +package org.springframework.kubernetes.loadbalancer; + +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@RunWith(SpringRunner.class) +public class LoadBalancerTest { + + @Autowired + RestTemplate restTemplate; + @ClassRule + public static KubernetesServer server = new KubernetesServer(true, true); + + private static KubernetesClient client; + + @BeforeClass + public static void setup() { + client = server.getClient(); + + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); + } + + @Test + public void testLoadBalancerSameNamespace() { + createTestData("service-a", "test"); + String response = restTemplate.getForObject("http://service-a/greeting", String.class); + Assertions.assertNotNull(response); + Assertions.assertEquals("greeting", response); + } + + @Test + public void testLoadBalancerDifferentNamespace() { + createTestData("service-b", "b"); + Assertions.assertThrows(IllegalStateException.class, () -> restTemplate + .getForObject("http://service-b/greeting", String.class)); + } + + private void createTestData(String name, String namespace) { + client.services().inNamespace(namespace).createNew() + .withNewMetadata().withName(name).endMetadata() + .withSpec(new ServiceSpecBuilder() + .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) + .build()) + .done(); + client.endpoints().inNamespace(namespace).createNew() + .withNewMetadata().withName("service-a").endMetadata() + .addNewSubset() + .addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort() + .endSubset() + .done(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index c666a61e..fcbd148b 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -133,6 +133,7 @@ simple-configmap discovery + load-balancer diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index b0d46cb5..fd9567f0 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -46,6 +46,11 @@ spring-cloud-kubernetes-discovery + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + From 5b0c945ba537524b08ce5e6c5e4a7c330db6b1a1 Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 9 Jun 2020 11:07:59 +0200 Subject: [PATCH 02/24] #516 Resolving errors from checkstyle rules --- .../load-balancer/pom.xml | 2 +- .../loadbalancer/SimpleLoadBalancerApp.java | 18 +++++- .../LoadBalancerAllNamespacesTest.java | 57 ++++++++++++------- .../loadbalancer/LoadBalancerTest.java | 55 +++++++++++------- 4 files changed, 88 insertions(+), 44 deletions(-) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/{spring/framework => springframework/cloud}/kubernetes/loadbalancer/SimpleLoadBalancerApp.java (55%) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/{ => cloud}/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java (51%) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/{ => cloud}/kubernetes/loadbalancer/LoadBalancerTest.java (54%) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml index 4f69d13b..eb47231f 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -9,6 +9,7 @@ 4.0.0 + Spring Cloud Kubernetes :: Integration Tests :: Load Balancer load-balancer @@ -28,7 +29,6 @@ io.fabric8 kubernetes-server-mock - 4.10.2 test diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java similarity index 55% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java index 84ef41c8..0f91abd6 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java @@ -1,4 +1,20 @@ -package org.spring.framework.kubernetes.loadbalancer; +/* + * 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.loadbalancer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java similarity index 51% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java index e9533cb8..646c77c7 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java @@ -1,8 +1,21 @@ -package org.springframework.kubernetes.loadbalancer; +/* + * 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. + */ -import java.util.List; +package org.springframework.cloud.kubernetes.loadbalancer; -import io.fabric8.kubernetes.api.model.Endpoints; import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; @@ -13,20 +26,20 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, - properties = {"spring.cloud.kubernetes.discovery.all-namespaces=true"}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, + properties = { "spring.cloud.kubernetes.discovery.all-namespaces=true" }) @RunWith(SpringRunner.class) public class LoadBalancerAllNamespacesTest { @Autowired RestTemplate restTemplate; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -36,10 +49,12 @@ public class LoadBalancerAllNamespacesTest { public static void setup() { client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @@ -47,25 +62,23 @@ public class LoadBalancerAllNamespacesTest { @Test public void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); - String response = restTemplate.getForObject("http://service-b/greeting", String.class); + String response = restTemplate.getForObject("http://service-b/greeting", + String.class); Assertions.assertNotNull(response); Assertions.assertEquals("greeting", response); } private void createTestData(String name, String namespace) { - client.services().inNamespace(namespace).createNew() - .withNewMetadata().withName(name).withNamespace(namespace).endMetadata() - .withSpec(new ServiceSpecBuilder() - .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) - .build()) - .done(); - client.endpoints().inNamespace(namespace).createNew() - .withNewMetadata().withName("service-a").withNamespace(namespace).endMetadata() - .addNewSubset() - .addNewAddress().withIp("localhost").endAddress() - .addNewPort().withName("http").withPort(8080).endPort() - .endSubset() - .done(); + client.services().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).withNamespace(namespace).endMetadata() + .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() + .withProtocol("TCP").withPort(8080).build()).build()) + .done(); + client.endpoints().inNamespace(namespace).createNew().withNewMetadata() + .withName("service-a").withNamespace(namespace).endMetadata() + .addNewSubset().addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort().endSubset() + .done(); } } diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java similarity index 54% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java index 09f24730..036e69a0 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java @@ -1,4 +1,20 @@ -package org.springframework.kubernetes.loadbalancer; +/* + * 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.loadbalancer; import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; @@ -10,19 +26,19 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @RunWith(SpringRunner.class) public class LoadBalancerTest { @Autowired RestTemplate restTemplate; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -32,10 +48,12 @@ public class LoadBalancerTest { public static void setup() { client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @@ -43,7 +61,8 @@ public class LoadBalancerTest { @Test public void testLoadBalancerSameNamespace() { createTestData("service-a", "test"); - String response = restTemplate.getForObject("http://service-a/greeting", String.class); + String response = restTemplate.getForObject("http://service-a/greeting", + String.class); Assertions.assertNotNull(response); Assertions.assertEquals("greeting", response); } @@ -52,23 +71,19 @@ public class LoadBalancerTest { public void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); Assertions.assertThrows(IllegalStateException.class, () -> restTemplate - .getForObject("http://service-b/greeting", String.class)); + .getForObject("http://service-b/greeting", String.class)); } private void createTestData(String name, String namespace) { - client.services().inNamespace(namespace).createNew() - .withNewMetadata().withName(name).endMetadata() - .withSpec(new ServiceSpecBuilder() - .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) - .build()) - .done(); - client.endpoints().inNamespace(namespace).createNew() - .withNewMetadata().withName("service-a").endMetadata() - .addNewSubset() - .addNewAddress().withIp("localhost").endAddress() - .addNewPort().withName("http").withPort(8080).endPort() - .endSubset() - .done(); + client.services().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).endMetadata() + .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() + .withProtocol("TCP").withPort(8080).build()).build()) + .done(); + client.endpoints().inNamespace(namespace).createNew().withNewMetadata() + .withName("service-a").endMetadata().addNewSubset().addNewAddress() + .withIp("localhost").endAddress().addNewPort().withName("http") + .withPort(8080).endPort().endSubset().done(); } } From aa1f9a292c933dbc42ed4ddcccb74f120a4032eb Mon Sep 17 00:00:00 2001 From: piomin Date: Sun, 7 Jun 2020 23:14:33 +0200 Subject: [PATCH 03/24] #516 Adding spring-cloud-starter-loadbalancer to spring-cloud-starter-kubernetes-all and provide integration tests inside module spring-cloud-kubernetes-integration-tests --- .../load-balancer/pom.xml | 36 +++++++++ .../loadbalancer/SimpleLoadBalancerApp.java | 31 ++++++++ .../LoadBalancerAllNamespacesTest.java | 71 ++++++++++++++++++ .../loadbalancer/LoadBalancerTest.java | 74 +++++++++++++++++++ .../pom.xml | 1 + spring-cloud-starter-kubernetes-all/pom.xml | 5 ++ 6 files changed, 218 insertions(+) create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml new file mode 100644 index 00000000..4f69d13b --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -0,0 +1,36 @@ + + + + spring-cloud-kubernetes-integration-tests + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + + load-balancer + + + + org.springframework.cloud + spring-cloud-starter-kubernetes-all + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + io.fabric8 + kubernetes-server-mock + 4.10.2 + test + + + + diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java new file mode 100644 index 00000000..84ef41c8 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java @@ -0,0 +1,31 @@ +package org.spring.framework.kubernetes.loadbalancer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +@RestController +public class SimpleLoadBalancerApp { + + public static void main(String[] args) { + SpringApplication.run(SimpleLoadBalancerApp.class, args); + } + + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplateBuilder().build(); + } + + @GetMapping("/greeting") + public String greeting() { + return "greeting"; + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java new file mode 100644 index 00000000..e9533cb8 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java @@ -0,0 +1,71 @@ +package org.springframework.kubernetes.loadbalancer; + +import java.util.List; + +import io.fabric8.kubernetes.api.model.Endpoints; +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, + properties = {"spring.cloud.kubernetes.discovery.all-namespaces=true"}) +@RunWith(SpringRunner.class) +public class LoadBalancerAllNamespacesTest { + + @Autowired + RestTemplate restTemplate; + @ClassRule + public static KubernetesServer server = new KubernetesServer(true, true); + + private static KubernetesClient client; + + @BeforeClass + public static void setup() { + client = server.getClient(); + + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); + } + + @Test + public void testLoadBalancerDifferentNamespace() { + createTestData("service-b", "b"); + String response = restTemplate.getForObject("http://service-b/greeting", String.class); + Assertions.assertNotNull(response); + Assertions.assertEquals("greeting", response); + } + + private void createTestData(String name, String namespace) { + client.services().inNamespace(namespace).createNew() + .withNewMetadata().withName(name).withNamespace(namespace).endMetadata() + .withSpec(new ServiceSpecBuilder() + .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) + .build()) + .done(); + client.endpoints().inNamespace(namespace).createNew() + .withNewMetadata().withName("service-a").withNamespace(namespace).endMetadata() + .addNewSubset() + .addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort() + .endSubset() + .done(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java new file mode 100644 index 00000000..09f24730 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java @@ -0,0 +1,74 @@ +package org.springframework.kubernetes.loadbalancer; + +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@RunWith(SpringRunner.class) +public class LoadBalancerTest { + + @Autowired + RestTemplate restTemplate; + @ClassRule + public static KubernetesServer server = new KubernetesServer(true, true); + + private static KubernetesClient client; + + @BeforeClass + public static void setup() { + client = server.getClient(); + + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); + } + + @Test + public void testLoadBalancerSameNamespace() { + createTestData("service-a", "test"); + String response = restTemplate.getForObject("http://service-a/greeting", String.class); + Assertions.assertNotNull(response); + Assertions.assertEquals("greeting", response); + } + + @Test + public void testLoadBalancerDifferentNamespace() { + createTestData("service-b", "b"); + Assertions.assertThrows(IllegalStateException.class, () -> restTemplate + .getForObject("http://service-b/greeting", String.class)); + } + + private void createTestData(String name, String namespace) { + client.services().inNamespace(namespace).createNew() + .withNewMetadata().withName(name).endMetadata() + .withSpec(new ServiceSpecBuilder() + .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) + .build()) + .done(); + client.endpoints().inNamespace(namespace).createNew() + .withNewMetadata().withName("service-a").endMetadata() + .addNewSubset() + .addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort() + .endSubset() + .done(); + } + +} diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml index c666a61e..fcbd148b 100644 --- a/spring-cloud-kubernetes-integration-tests/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/pom.xml @@ -133,6 +133,7 @@ simple-configmap discovery + load-balancer diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index b0d46cb5..fd9567f0 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -46,6 +46,11 @@ spring-cloud-kubernetes-discovery + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + From 285d13e9242c88571ae5e10bb9e15aa2277b3aaa Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 9 Jun 2020 11:07:59 +0200 Subject: [PATCH 04/24] #516 Resolving errors from checkstyle rules --- .../load-balancer/pom.xml | 2 +- .../loadbalancer/SimpleLoadBalancerApp.java | 18 +++++- .../LoadBalancerAllNamespacesTest.java | 57 ++++++++++++------- .../loadbalancer/LoadBalancerTest.java | 55 +++++++++++------- 4 files changed, 88 insertions(+), 44 deletions(-) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/{spring/framework => springframework/cloud}/kubernetes/loadbalancer/SimpleLoadBalancerApp.java (55%) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/{ => cloud}/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java (51%) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/{ => cloud}/kubernetes/loadbalancer/LoadBalancerTest.java (54%) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml index 4f69d13b..eb47231f 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -9,6 +9,7 @@ 4.0.0 + Spring Cloud Kubernetes :: Integration Tests :: Load Balancer load-balancer @@ -28,7 +29,6 @@ io.fabric8 kubernetes-server-mock - 4.10.2 test diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java similarity index 55% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java index 84ef41c8..0f91abd6 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/SimpleLoadBalancerApp.java @@ -1,4 +1,20 @@ -package org.spring.framework.kubernetes.loadbalancer; +/* + * 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.loadbalancer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java similarity index 51% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java index e9533cb8..646c77c7 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java @@ -1,8 +1,21 @@ -package org.springframework.kubernetes.loadbalancer; +/* + * 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. + */ -import java.util.List; +package org.springframework.cloud.kubernetes.loadbalancer; -import io.fabric8.kubernetes.api.model.Endpoints; import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; @@ -13,20 +26,20 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, - properties = {"spring.cloud.kubernetes.discovery.all-namespaces=true"}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, + properties = { "spring.cloud.kubernetes.discovery.all-namespaces=true" }) @RunWith(SpringRunner.class) public class LoadBalancerAllNamespacesTest { @Autowired RestTemplate restTemplate; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -36,10 +49,12 @@ public class LoadBalancerAllNamespacesTest { public static void setup() { client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @@ -47,25 +62,23 @@ public class LoadBalancerAllNamespacesTest { @Test public void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); - String response = restTemplate.getForObject("http://service-b/greeting", String.class); + String response = restTemplate.getForObject("http://service-b/greeting", + String.class); Assertions.assertNotNull(response); Assertions.assertEquals("greeting", response); } private void createTestData(String name, String namespace) { - client.services().inNamespace(namespace).createNew() - .withNewMetadata().withName(name).withNamespace(namespace).endMetadata() - .withSpec(new ServiceSpecBuilder() - .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) - .build()) - .done(); - client.endpoints().inNamespace(namespace).createNew() - .withNewMetadata().withName("service-a").withNamespace(namespace).endMetadata() - .addNewSubset() - .addNewAddress().withIp("localhost").endAddress() - .addNewPort().withName("http").withPort(8080).endPort() - .endSubset() - .done(); + client.services().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).withNamespace(namespace).endMetadata() + .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() + .withProtocol("TCP").withPort(8080).build()).build()) + .done(); + client.endpoints().inNamespace(namespace).createNew().withNewMetadata() + .withName("service-a").withNamespace(namespace).endMetadata() + .addNewSubset().addNewAddress().withIp("localhost").endAddress() + .addNewPort().withName("http").withPort(8080).endPort().endSubset() + .done(); } } diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java similarity index 54% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java index 09f24730..036e69a0 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java @@ -1,4 +1,20 @@ -package org.springframework.kubernetes.loadbalancer; +/* + * 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.loadbalancer; import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; @@ -10,19 +26,19 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; -import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @RunWith(SpringRunner.class) public class LoadBalancerTest { @Autowired RestTemplate restTemplate; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -32,10 +48,12 @@ public class LoadBalancerTest { public static void setup() { client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); - System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @@ -43,7 +61,8 @@ public class LoadBalancerTest { @Test public void testLoadBalancerSameNamespace() { createTestData("service-a", "test"); - String response = restTemplate.getForObject("http://service-a/greeting", String.class); + String response = restTemplate.getForObject("http://service-a/greeting", + String.class); Assertions.assertNotNull(response); Assertions.assertEquals("greeting", response); } @@ -52,23 +71,19 @@ public class LoadBalancerTest { public void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); Assertions.assertThrows(IllegalStateException.class, () -> restTemplate - .getForObject("http://service-b/greeting", String.class)); + .getForObject("http://service-b/greeting", String.class)); } private void createTestData(String name, String namespace) { - client.services().inNamespace(namespace).createNew() - .withNewMetadata().withName(name).endMetadata() - .withSpec(new ServiceSpecBuilder() - .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build()) - .build()) - .done(); - client.endpoints().inNamespace(namespace).createNew() - .withNewMetadata().withName("service-a").endMetadata() - .addNewSubset() - .addNewAddress().withIp("localhost").endAddress() - .addNewPort().withName("http").withPort(8080).endPort() - .endSubset() - .done(); + client.services().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).endMetadata() + .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() + .withProtocol("TCP").withPort(8080).build()).build()) + .done(); + client.endpoints().inNamespace(namespace).createNew().withNewMetadata() + .withName("service-a").endMetadata().addNewSubset().addNewAddress() + .withIp("localhost").endAddress().addNewPort().withName("http") + .withPort(8080).endPort().endSubset().done(); } } From 3732c0df4f480acf22c7d2d60c4364936c37c62f Mon Sep 17 00:00:00 2001 From: piomin Date: Fri, 26 Jun 2020 14:23:03 +0200 Subject: [PATCH 05/24] #562 Adding module spring-cloud-kubernetes-loadbalancer with implementation for service mode --- pom.xml | 1 + spring-cloud-kubernetes-loadbalancer/pom.xml | 45 ++++++ .../KubernetesClientConfiguration.java | 40 +++++ ...bernetesLoadBalancerAutoConfiguration.java | 42 ++++++ .../KubernetesLoadBalancerMode.java | 33 +++++ .../KubernetesLoadBalancerProperties.java | 112 ++++++++++++++ .../KubernetesServiceInstance.java | 84 +++++++++++ .../KubernetesServiceInstanceMapper.java | 140 ++++++++++++++++++ .../KubernetesServicesListSupplier.java | 69 +++++++++ .../main/resources/META-INF/spring.factories | 2 + 10 files changed, 568 insertions(+) create mode 100644 spring-cloud-kubernetes-loadbalancer/pom.xml create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java create mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/resources/META-INF/spring.factories diff --git a/pom.xml b/pom.xml index 9f326c33..4ec0d59d 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,7 @@ spring-cloud-kubernetes-istio spring-cloud-kubernetes-integration-tests docs + spring-cloud-kubernetes-loadbalancer diff --git a/spring-cloud-kubernetes-loadbalancer/pom.xml b/spring-cloud-kubernetes-loadbalancer/pom.xml new file mode 100644 index 00000000..93514763 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/pom.xml @@ -0,0 +1,45 @@ + + + + spring-cloud-kubernetes + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-kubernetes-loadbalancer + Spring Cloud Kubernetes :: Load Balancer + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + org.springframework.cloud + spring-cloud-kubernetes-discovery + + + commons-lang + commons-lang + 2.6 + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java new file mode 100644 index 00000000..dddc13f4 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java @@ -0,0 +1,40 @@ +/* + * 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.loadbalancer; + +import io.fabric8.kubernetes.client.KubernetesClient; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; + +/** + * Kubernetes load balancer client properties. + * + * @author Piotr Minkowski + */ +public class KubernetesClientConfiguration { + + @Bean + @ConditionalOnProperty(name = "spring.cloud.kubernetes.loadbalancer.mode", + havingValue = "SERVICE") + KubernetesServicesListSupplier kubernetesServicesListSupplier(Environment environment, + KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper) { + return new KubernetesServicesListSupplier(environment, kubernetesClient, mapper); + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java new file mode 100644 index 00000000..5d388db9 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -0,0 +1,42 @@ +/* + * 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.loadbalancer; + +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Piotr Minkowski + */ +@Configuration +@LoadBalancerClients(defaultConfiguration = KubernetesClientConfiguration.class) +public class KubernetesLoadBalancerAutoConfiguration { + + @Bean + KubernetesLoadBalancerProperties properties() { + return new KubernetesLoadBalancerProperties(); + } + + @Bean + KubernetesServiceInstanceMapper mapper(KubernetesLoadBalancerProperties properties, + KubernetesDiscoveryProperties discoveryProperties) { + return new KubernetesServiceInstanceMapper(properties, discoveryProperties); + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java new file mode 100644 index 00000000..41eb66c4 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java @@ -0,0 +1,33 @@ +/* + * 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.loadbalancer; + +/** + * @author Piotr Minkowski + */ +public enum KubernetesLoadBalancerMode { + + /** + * using pod ip and port. + */ + POD, + /** + * using kubernetes service name and port. + */ + SERVICE + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java new file mode 100644 index 00000000..88e27152 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java @@ -0,0 +1,112 @@ +/* + * 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.loadbalancer; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Piotr Minkowski + */ +@ConfigurationProperties(prefix = "spring.cloud.kubernetes.loadbalancer") +public class KubernetesLoadBalancerProperties { + + /** + * Ribbon enabled,default true. + */ + private Boolean enabled = true; + + /** + * {@link KubernetesLoadBalancerMode} setting ribbon server list with ip of pod or + * service name. default value is POD. + */ + private KubernetesLoadBalancerMode mode = KubernetesLoadBalancerMode.POD; + + /** + * cluster domain. + */ + private String clusterDomain = "cluster.local"; + + /** + * service port name. + */ + private String portName = "http"; + + /** + * Get cluster domain. + * @return the cluster domain + */ + public String getClusterDomain() { + return clusterDomain; + } + + /** + * Sets cluster domain. + * @param clusterDomain the cluster domain + */ + public void setClusterDomain(String clusterDomain) { + this.clusterDomain = clusterDomain; + } + + /** + * Gets mode. + * @return the mode + */ + public KubernetesLoadBalancerMode getMode() { + return mode; + } + + /** + * Sets mode. + * @param mode the mode + */ + public void setMode(KubernetesLoadBalancerMode mode) { + this.mode = mode; + } + + /** + * Gets enabled. + * @return the enabled + */ + public Boolean getEnabled() { + return enabled; + } + + /** + * Sets enabled. + * @param enabled the enabled + */ + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + /** + * Gets portName. + * @return portName port name + */ + public String getPortName() { + return portName; + } + + /** + * Sets portName. + * @param portName port name + */ + public void setPortName(String portName) { + this.portName = portName; + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java new file mode 100644 index 00000000..dcf71944 --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java @@ -0,0 +1,84 @@ +/* + * 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.loadbalancer; + +import java.net.URI; +import java.util.Map; + +import org.springframework.cloud.client.ServiceInstance; + +/** + * @author Piotr Minkowski + */ +public class KubernetesServiceInstance implements ServiceInstance { + + private String serviceId; + + private String instanceId; + + private int port; + + private boolean secure; + + private String host; + + private URI uri; + + private Map metadata; + + KubernetesServiceInstance(String serviceId, String instanceId, int port, + boolean secure, String host, URI uri, Map metadata) { + this.serviceId = serviceId; + this.instanceId = instanceId; + this.port = port; + this.secure = secure; + this.host = host; + this.uri = uri; + this.metadata = metadata; + } + + @Override + public String getServiceId() { + return serviceId; + } + + @Override + public String getHost() { + return host; + } + + @Override + public int getPort() { + return port; + } + + @Override + public boolean isSecure() { + return secure; + } + + @Override + public URI getUri() { + return uri; + } + + @Override + public Map getMetadata() { + return metadata; + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java new file mode 100644 index 00000000..a54baf5f --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java @@ -0,0 +1,140 @@ +/* + * 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.loadbalancer; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.ServicePort; +import io.fabric8.kubernetes.client.utils.Utils; +import org.apache.commons.lang.StringUtils; + +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; + +/** + * @author Piotr Minkowski + */ +public class KubernetesServiceInstanceMapper { + + private static final String DSL = "//"; + + private static final String COLON = ":"; + + private final KubernetesLoadBalancerProperties properties; + + private final KubernetesDiscoveryProperties discoveryProperties; + + KubernetesServiceInstanceMapper(KubernetesLoadBalancerProperties properties, + KubernetesDiscoveryProperties discoveryProperties) { + this.properties = properties; + this.discoveryProperties = discoveryProperties; + } + + public KubernetesServiceInstance map(Service service) { + final ObjectMeta meta = service.getMetadata(); + final List ports = service.getSpec().getPorts(); + ServicePort port = null; + if (ports.size() == 1) { + port = ports.get(0); + } + else if (ports.size() > 1 + && Utils.isNotNullOrEmpty(this.properties.getPortName())) { + Optional optPort = ports.stream() + .filter(it -> properties.getPortName().endsWith(it.getName())) + .findAny(); + if (optPort.isPresent()) { + port = optPort.get(); + } + } + if (port == null) { + return null; + } + final String host = createHost(service); + final boolean secure = isSecure(service, port); + return new KubernetesServiceInstance(meta.getName(), meta.getUid(), + port.getPort(), secure, host, + createUri(secure ? "https" : "http", host, port.getPort()), + getServiceMetadata(service)); + } + + private Map getServiceMetadata(Service service) { + final Map serviceMetadata = new HashMap<>(); + KubernetesDiscoveryProperties.Metadata metadataProps = this.discoveryProperties + .getMetadata(); + if (metadataProps.isAddLabels()) { + Map labelMetadata = getMapWithPrefixedKeys( + service.getMetadata().getLabels(), metadataProps.getLabelsPrefix()); + serviceMetadata.putAll(labelMetadata); + } + if (metadataProps.isAddAnnotations()) { + Map annotationMetadata = getMapWithPrefixedKeys( + service.getMetadata().getAnnotations(), + metadataProps.getAnnotationsPrefix()); + serviceMetadata.putAll(annotationMetadata); + } + + return serviceMetadata; + } + + private Map getMapWithPrefixedKeys(Map map, + String prefix) { + if (map == null) { + return new HashMap<>(); + } + if (!org.springframework.util.StringUtils.hasText(prefix)) { + return map; + } + final Map result = new HashMap<>(); + map.forEach((k, v) -> result.put(prefix + k, v)); + return result; + } + + private boolean isSecure(Service service, ServicePort port) { + final String securedLabelValue = service.getMetadata().getLabels() + .getOrDefault("secured", "false"); + if (securedLabelValue.equals("true")) { + return true; + } + final String securedAnnotationValue = service.getMetadata().getAnnotations() + .getOrDefault("secured", "false"); + if (securedAnnotationValue.equals("true")) { + return true; + } + return (port.getName() != null && port.getName().endsWith("https")) + || port.getPort().toString().endsWith("443"); + } + + private String createHost(Service service) { + return String.format("%s.%s.svc.%s", service.getMetadata().getName(), + StringUtils.isNotBlank(service.getMetadata().getNamespace()) + ? service.getMetadata().getNamespace() : "default", + properties.getClusterDomain()); + } + + private URI createUri(String scheme, String host, int port) { + StringBuilder sb = new StringBuilder(); + sb.append(scheme).append(COLON).append(DSL).append(host).append(COLON) + .append(port); + return URI.create(sb.toString()); + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java new file mode 100644 index 00000000..51fe8fbc --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -0,0 +1,69 @@ +/* + * 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.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.client.KubernetesClient; +import org.apache.commons.lang.StringUtils; +import reactor.core.publisher.Flux; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; +import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; +import org.springframework.core.env.Environment; + +/** + * @author Piotr Minkowski + */ +public class KubernetesServicesListSupplier implements ServiceInstanceListSupplier { + + private Environment environment; + + private KubernetesClient kubernetesClient; + + private KubernetesServiceInstanceMapper mapper; + + KubernetesServicesListSupplier(Environment environment, + KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper) { + this.environment = environment; + this.kubernetesClient = kubernetesClient; + this.mapper = mapper; + } + + @Override + public String getServiceId() { + return environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); + } + + @Override + public Flux> get() { + List result = new ArrayList<>(); + Service service = StringUtils.isNotBlank(this.kubernetesClient.getNamespace()) + ? this.kubernetesClient + .services().inNamespace(this.kubernetesClient.getNamespace()) + .withName(this.getServiceId()).get() + : this.kubernetesClient.services().withName(this.getServiceId()).get(); + if (service != null) { + result.add(mapper.map(service)); + } + return Flux.just(result); + } + +} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-loadbalancer/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..4a43c68f --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.kubernetes.loadbalancer.KubernetesLoadBalancerAutoConfiguration From fa17d99a45157b04798954c80a4ba0244b47af4d Mon Sep 17 00:00:00 2001 From: piomin Date: Fri, 26 Jun 2020 15:31:01 +0200 Subject: [PATCH 06/24] #562 Changing tests into random server ports --- .../loadbalancer/LoadBalancerAllNamespacesTest.java | 12 ++++++++---- .../kubernetes/loadbalancer/LoadBalancerTest.java | 10 +++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java index 646c77c7..e4f69bd7 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java @@ -29,10 +29,11 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.kubernetes.discovery.all-namespaces=true" }) @RunWith(SpringRunner.class) public class LoadBalancerAllNamespacesTest { @@ -40,6 +41,9 @@ public class LoadBalancerAllNamespacesTest { @Autowired RestTemplate restTemplate; + @LocalServerPort + int randomServerPort; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -72,13 +76,13 @@ public class LoadBalancerAllNamespacesTest { client.services().inNamespace(namespace).createNew().withNewMetadata() .withName(name).withNamespace(namespace).endMetadata() .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() - .withProtocol("TCP").withPort(8080).build()).build()) + .withProtocol("TCP").withPort(randomServerPort).build()).build()) .done(); client.endpoints().inNamespace(namespace).createNew().withNewMetadata() .withName("service-a").withNamespace(namespace).endMetadata() .addNewSubset().addNewAddress().withIp("localhost").endAddress() - .addNewPort().withName("http").withPort(8080).endPort().endSubset() - .done(); + .addNewPort().withName("http").withPort(randomServerPort).endPort() + .endSubset().done(); } } diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java index 036e69a0..1d34c2f3 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java @@ -29,16 +29,20 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @RunWith(SpringRunner.class) public class LoadBalancerTest { @Autowired RestTemplate restTemplate; + @LocalServerPort + int randomServerPort; + @ClassRule public static KubernetesServer server = new KubernetesServer(true, true); @@ -78,12 +82,12 @@ public class LoadBalancerTest { client.services().inNamespace(namespace).createNew().withNewMetadata() .withName(name).endMetadata() .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() - .withProtocol("TCP").withPort(8080).build()).build()) + .withProtocol("TCP").withPort(randomServerPort).build()).build()) .done(); client.endpoints().inNamespace(namespace).createNew().withNewMetadata() .withName("service-a").endMetadata().addNewSubset().addNewAddress() .withIp("localhost").endAddress().addNewPort().withName("http") - .withPort(8080).endPort().endSubset().done(); + .withPort(randomServerPort).endPort().endSubset().done(); } } From 259ed6d0b728e8ea376c11d00afae43143fe8ec7 Mon Sep 17 00:00:00 2001 From: piomin Date: Wed, 1 Jul 2020 09:51:23 +0200 Subject: [PATCH 07/24] #562 Refactoring --- spring-cloud-kubernetes-loadbalancer/pom.xml | 2 +- .../loadbalancer/KubernetesLoadBalancerAutoConfiguration.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-loadbalancer/pom.xml b/spring-cloud-kubernetes-loadbalancer/pom.xml index 93514763..42515da1 100644 --- a/spring-cloud-kubernetes-loadbalancer/pom.xml +++ b/spring-cloud-kubernetes-loadbalancer/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - spring-cloud-kubernetes org.springframework.cloud + spring-cloud-kubernetes 2.0.0-SNAPSHOT 4.0.0 diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java index 5d388db9..b698bf8c 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.loadbalancer; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; import org.springframework.context.annotation.Bean; @@ -25,6 +26,7 @@ import org.springframework.context.annotation.Configuration; * @author Piotr Minkowski */ @Configuration +@EnableConfigurationProperties @LoadBalancerClients(defaultConfiguration = KubernetesClientConfiguration.class) public class KubernetesLoadBalancerAutoConfiguration { From 7f31a7739c92e90520a0b42b01035cc6bbd72bf7 Mon Sep 17 00:00:00 2001 From: piomin Date: Wed, 1 Jul 2020 16:39:17 +0200 Subject: [PATCH 08/24] #562 Adding @EnableConfigurationProperties + fixing test error --- .../KubernetesServiceInstance.java | 5 + .../KubernetesServiceInstanceMapperTest.java | 128 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java index dcf71944..f1315277 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java @@ -56,6 +56,11 @@ public class KubernetesServiceInstance implements ServiceInstance { return serviceId; } + @Override + public String getInstanceId() { + return instanceId; + } + @Override public String getHost() { return host; diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java new file mode 100644 index 00000000..a696fcfa --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java @@ -0,0 +1,128 @@ +/* + * 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.loadbalancer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.api.model.ServicePort; +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; + +public class KubernetesServiceInstanceMapperTest { + + @Test + void testMapperSimple() { + KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); + KubernetesDiscoveryProperties discoveryProperties = + new KubernetesDiscoveryProperties(); + Service service = buildService("test", "abc", 8080, null, new HashMap<>()); + KubernetesServiceInstance instance = + new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + Assertions.assertNotNull(instance); + Assertions.assertEquals("test", instance.getServiceId()); + Assertions.assertEquals("abc", instance.getInstanceId()); + } + + @Test + void testMapperMultiplePorts() { + KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); + properties.setPortName("http"); + KubernetesDiscoveryProperties discoveryProperties = + new KubernetesDiscoveryProperties(); + List ports = new ArrayList<>(); + ports.add(new ServicePortBuilder() + .withPort(8080) + .withName("web") + .build()); + ports.add(new ServicePortBuilder() + .withPort(9000) + .withName("http") + .build()); + Service service = buildService("test", "abc", ports, new HashMap<>()); + KubernetesServiceInstance instance = + new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + Assertions.assertNotNull(instance); + Assertions.assertEquals("test", instance.getServiceId()); + Assertions.assertEquals("abc", instance.getInstanceId()); + Assertions.assertEquals(9000, instance.getPort()); + } + + @Test + void testMapperSecure() { + KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); + KubernetesDiscoveryProperties discoveryProperties = + new KubernetesDiscoveryProperties(); + Service service = buildService("test", "abc", 443, null, new HashMap<>()); + KubernetesServiceInstance instance = + new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + Assertions.assertNotNull(instance); + Assertions.assertEquals("test", instance.getServiceId()); + Assertions.assertEquals("abc", instance.getInstanceId()); + Assertions.assertTrue(instance.isSecure()); + } + + @Test + void testMapperSecureWithLabels() { + KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); + KubernetesDiscoveryProperties discoveryProperties = + new KubernetesDiscoveryProperties(); + HashMap labels = new HashMap<>(); + labels.put("secured", "true"); + labels.put("label1", "123"); + Service service = buildService("test", "abc", 8080, null, labels); + KubernetesServiceInstance instance = + new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + Assertions.assertNotNull(instance); + Assertions.assertEquals("test", instance.getServiceId()); + Assertions.assertEquals("abc", instance.getInstanceId()); + Assertions.assertTrue(instance.isSecure()); + Assertions.assertEquals(2, instance.getMetadata().keySet().size()); + } + + + private Service buildService(String name, String uid, List ports, Map labels) { + return new ServiceBuilder() + .withNewMetadata() + .withName(name) + .withNewUid(uid) + .addToLabels(labels) + .addToAnnotations(new HashMap<>(0)) + .endMetadata() + .withNewSpec() + .addAllToPorts(ports) + .endSpec() + .build(); + } + + private Service buildService(String name, String uid, int port, String portName, Map labels) { + ServicePort servicePort = new ServicePortBuilder() + .withPort(port) + .withName(portName) + .build(); + return buildService(name, uid, Collections.singletonList(servicePort), labels); + } + +} From 694f89add9d4344514fa4d3702624280d2be2e21 Mon Sep 17 00:00:00 2001 From: piomin Date: Fri, 3 Jul 2020 15:23:05 +0200 Subject: [PATCH 09/24] #562 Adding all namespaces handling + tests --- spring-cloud-kubernetes-loadbalancer/pom.xml | 5 + .../KubernetesClientConfiguration.java | 7 +- .../KubernetesServiceInstance.java | 3 + .../KubernetesServicesListSupplier.java | 29 +++-- .../KubernetesServiceInstanceMapperTest.java | 67 ++++------- .../KubernetesServiceListSupplierTest.java | 113 ++++++++++++++++++ 6 files changed, 171 insertions(+), 53 deletions(-) create mode 100644 spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java diff --git a/spring-cloud-kubernetes-loadbalancer/pom.xml b/spring-cloud-kubernetes-loadbalancer/pom.xml index 42515da1..d564c118 100644 --- a/spring-cloud-kubernetes-loadbalancer/pom.xml +++ b/spring-cloud-kubernetes-loadbalancer/pom.xml @@ -41,5 +41,10 @@ spring-boot-starter-test test + + io.fabric8 + kubernetes-server-mock + test + diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java index dddc13f4..c16c9fe8 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java @@ -19,6 +19,7 @@ package org.springframework.cloud.kubernetes.loadbalancer; import io.fabric8.kubernetes.client.KubernetesClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; @@ -33,8 +34,10 @@ public class KubernetesClientConfiguration { @ConditionalOnProperty(name = "spring.cloud.kubernetes.loadbalancer.mode", havingValue = "SERVICE") KubernetesServicesListSupplier kubernetesServicesListSupplier(Environment environment, - KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper) { - return new KubernetesServicesListSupplier(environment, kubernetesClient, mapper); + KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper, + KubernetesDiscoveryProperties discoveryProperties) { + return new KubernetesServicesListSupplier(environment, kubernetesClient, mapper, + discoveryProperties); } } diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java index f1315277..8967e072 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java @@ -40,6 +40,9 @@ public class KubernetesServiceInstance implements ServiceInstance { private Map metadata; + KubernetesServiceInstance() { + } + KubernetesServiceInstance(String serviceId, String instanceId, int port, boolean secure, String host, URI uri, Map metadata) { this.serviceId = serviceId; diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java index 51fe8fbc..29d61bfa 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -25,6 +25,7 @@ import org.apache.commons.lang.StringUtils; import reactor.core.publisher.Flux; import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.core.env.Environment; @@ -38,12 +39,16 @@ public class KubernetesServicesListSupplier implements ServiceInstanceListSuppli private KubernetesClient kubernetesClient; + private KubernetesDiscoveryProperties discoveryProperties; + private KubernetesServiceInstanceMapper mapper; KubernetesServicesListSupplier(Environment environment, - KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper) { + KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper, + KubernetesDiscoveryProperties discoveryProperties) { this.environment = environment; this.kubernetesClient = kubernetesClient; + this.discoveryProperties = discoveryProperties; this.mapper = mapper; } @@ -55,13 +60,21 @@ public class KubernetesServicesListSupplier implements ServiceInstanceListSuppli @Override public Flux> get() { List result = new ArrayList<>(); - Service service = StringUtils.isNotBlank(this.kubernetesClient.getNamespace()) - ? this.kubernetesClient - .services().inNamespace(this.kubernetesClient.getNamespace()) - .withName(this.getServiceId()).get() - : this.kubernetesClient.services().withName(this.getServiceId()).get(); - if (service != null) { - result.add(mapper.map(service)); + if (discoveryProperties.isAllNamespaces()) { + List services = this.kubernetesClient.services().inAnyNamespace() + .withField("metadata.name", this.getServiceId()).list().getItems(); + services.forEach(service -> result.add(mapper.map(service))); + } + else { + Service service = StringUtils.isNotBlank(this.kubernetesClient.getNamespace()) + ? this.kubernetesClient.services() + .inNamespace(this.kubernetesClient.getNamespace()) + .withName(this.getServiceId()).get() + : this.kubernetesClient.services().withName(this.getServiceId()) + .get(); + if (service != null) { + result.add(mapper.map(service)); + } } return Flux.just(result); } diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java index a696fcfa..2d5d5fc2 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java @@ -34,13 +34,12 @@ import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryPropert public class KubernetesServiceInstanceMapperTest { @Test - void testMapperSimple() { + public void testMapperSimple() { KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); - KubernetesDiscoveryProperties discoveryProperties = - new KubernetesDiscoveryProperties(); + KubernetesDiscoveryProperties discoveryProperties = new KubernetesDiscoveryProperties(); Service service = buildService("test", "abc", 8080, null, new HashMap<>()); - KubernetesServiceInstance instance = - new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + KubernetesServiceInstance instance = new KubernetesServiceInstanceMapper( + properties, discoveryProperties).map(service); Assertions.assertNotNull(instance); Assertions.assertEquals("test", instance.getServiceId()); Assertions.assertEquals("abc", instance.getInstanceId()); @@ -50,20 +49,13 @@ public class KubernetesServiceInstanceMapperTest { void testMapperMultiplePorts() { KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); properties.setPortName("http"); - KubernetesDiscoveryProperties discoveryProperties = - new KubernetesDiscoveryProperties(); + KubernetesDiscoveryProperties discoveryProperties = new KubernetesDiscoveryProperties(); List ports = new ArrayList<>(); - ports.add(new ServicePortBuilder() - .withPort(8080) - .withName("web") - .build()); - ports.add(new ServicePortBuilder() - .withPort(9000) - .withName("http") - .build()); + ports.add(new ServicePortBuilder().withPort(8080).withName("web").build()); + ports.add(new ServicePortBuilder().withPort(9000).withName("http").build()); Service service = buildService("test", "abc", ports, new HashMap<>()); - KubernetesServiceInstance instance = - new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + KubernetesServiceInstance instance = new KubernetesServiceInstanceMapper( + properties, discoveryProperties).map(service); Assertions.assertNotNull(instance); Assertions.assertEquals("test", instance.getServiceId()); Assertions.assertEquals("abc", instance.getInstanceId()); @@ -73,11 +65,10 @@ public class KubernetesServiceInstanceMapperTest { @Test void testMapperSecure() { KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); - KubernetesDiscoveryProperties discoveryProperties = - new KubernetesDiscoveryProperties(); + KubernetesDiscoveryProperties discoveryProperties = new KubernetesDiscoveryProperties(); Service service = buildService("test", "abc", 443, null, new HashMap<>()); - KubernetesServiceInstance instance = - new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + KubernetesServiceInstance instance = new KubernetesServiceInstanceMapper( + properties, discoveryProperties).map(service); Assertions.assertNotNull(instance); Assertions.assertEquals("test", instance.getServiceId()); Assertions.assertEquals("abc", instance.getInstanceId()); @@ -87,14 +78,13 @@ public class KubernetesServiceInstanceMapperTest { @Test void testMapperSecureWithLabels() { KubernetesLoadBalancerProperties properties = new KubernetesLoadBalancerProperties(); - KubernetesDiscoveryProperties discoveryProperties = - new KubernetesDiscoveryProperties(); + KubernetesDiscoveryProperties discoveryProperties = new KubernetesDiscoveryProperties(); HashMap labels = new HashMap<>(); labels.put("secured", "true"); labels.put("label1", "123"); Service service = buildService("test", "abc", 8080, null, labels); - KubernetesServiceInstance instance = - new KubernetesServiceInstanceMapper(properties, discoveryProperties).map(service); + KubernetesServiceInstance instance = new KubernetesServiceInstanceMapper( + properties, discoveryProperties).map(service); Assertions.assertNotNull(instance); Assertions.assertEquals("test", instance.getServiceId()); Assertions.assertEquals("abc", instance.getInstanceId()); @@ -102,26 +92,17 @@ public class KubernetesServiceInstanceMapperTest { Assertions.assertEquals(2, instance.getMetadata().keySet().size()); } - - private Service buildService(String name, String uid, List ports, Map labels) { - return new ServiceBuilder() - .withNewMetadata() - .withName(name) - .withNewUid(uid) - .addToLabels(labels) - .addToAnnotations(new HashMap<>(0)) - .endMetadata() - .withNewSpec() - .addAllToPorts(ports) - .endSpec() - .build(); + private Service buildService(String name, String uid, List ports, + Map labels) { + return new ServiceBuilder().withNewMetadata().withName(name).withNewUid(uid) + .addToLabels(labels).addToAnnotations(new HashMap<>(0)).endMetadata() + .withNewSpec().addAllToPorts(ports).endSpec().build(); } - private Service buildService(String name, String uid, int port, String portName, Map labels) { - ServicePort servicePort = new ServicePortBuilder() - .withPort(port) - .withName(portName) - .build(); + private Service buildService(String name, String uid, int port, String portName, + Map labels) { + ServicePort servicePort = new ServicePortBuilder().withPort(port) + .withName(portName).build(); return buildService(name, uid, Collections.singletonList(servicePort), labels); } diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java new file mode 100644 index 00000000..542fe17a --- /dev/null +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java @@ -0,0 +1,113 @@ +/* + * 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.loadbalancer; + +import java.util.List; + +import io.fabric8.kubernetes.api.model.DoneableService; +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.api.model.ServiceList; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.Watch; +import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.FilterWatchListMultiDeletable; +import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; +import io.fabric8.kubernetes.client.dsl.ServiceResource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +import org.springframework.core.env.Environment; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class KubernetesServiceListSupplierTest { + + @Mock + Environment environment; + + @Mock + KubernetesServiceInstanceMapper mapper; + + @Mock + KubernetesClient client; + + @Mock + MixedOperation> serviceOperation; + + @Mock + NonNamespaceOperation> namespaceOperation; + + @Mock + ServiceResource serviceResource; + + @Mock + FilterWatchListMultiDeletable> multiDeletable; + + @Test + void testPositiveMatch() { + when(environment.getProperty("loadbalancer.client.name")) + .thenReturn("test-service"); + when(mapper.map(any(Service.class))).thenReturn(new KubernetesServiceInstance()); + when(this.client.getNamespace()).thenReturn("test"); + when(this.client.services()).thenReturn(this.serviceOperation); + when(this.serviceOperation.inNamespace("test")).thenReturn(namespaceOperation); + when(this.namespaceOperation.withName("test-service")) + .thenReturn(this.serviceResource); + when(this.serviceResource.get()).thenReturn(buildService("test-service", 8080)); + KubernetesServicesListSupplier supplier = new KubernetesServicesListSupplier( + environment, client, mapper, new KubernetesDiscoveryProperties()); + List instances = supplier.get().blockFirst(); + assert instances != null; + Assertions.assertEquals(1, instances.size()); + } + + @Test + void testPositiveMatchAllNamespaces() { + when(environment.getProperty("loadbalancer.client.name")) + .thenReturn("test-service"); + when(mapper.map(any(Service.class))).thenReturn(new KubernetesServiceInstance()); + when(this.client.services()).thenReturn(this.serviceOperation); + when(this.serviceOperation.inAnyNamespace()).thenReturn(this.multiDeletable); + when(this.multiDeletable.withField("metadata.name", "test-service")) + .thenReturn(this.multiDeletable); + ServiceList serviceList = new ServiceList(); + serviceList.getItems().add(buildService("test-service", 8080)); + when(this.multiDeletable.list()).thenReturn(serviceList); + KubernetesDiscoveryProperties discoveryProperties = new KubernetesDiscoveryProperties(); + discoveryProperties.setAllNamespaces(true); + KubernetesServicesListSupplier supplier = new KubernetesServicesListSupplier( + environment, client, mapper, discoveryProperties); + List instances = supplier.get().blockFirst(); + assert instances != null; + Assertions.assertEquals(1, instances.size()); + } + + private Service buildService(String name, int port) { + return new ServiceBuilder().withNewMetadata().withName(name).endMetadata() + .withNewSpec().addNewPort().withPort(8080).endPort().endSpec().build(); + } + +} From d837efea6a08f594ea7d621bfb76e9a2b7f20b20 Mon Sep 17 00:00:00 2001 From: piomin Date: Fri, 17 Jul 2020 00:50:59 +0200 Subject: [PATCH 10/24] #562 Removing unnecessary @Bean + changing KubernetesServiceInstance implementation --- .../discovery/KubernetesDiscoveryClient.java | 3 +- .../discovery/KubernetesServiceInstance.java | 59 ++++++------ .../KubernetesServiceInstanceTests.java | 3 +- ...bernetesLoadBalancerAutoConfiguration.java | 5 - .../KubernetesServiceInstance.java | 92 ------------------- .../KubernetesServiceInstanceMapper.java | 7 +- .../KubernetesServiceInstanceMapperTest.java | 1 + .../KubernetesServiceListSupplierTest.java | 1 + 8 files changed, 42 insertions(+), 129 deletions(-) delete mode 100644 spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java 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..7d0f6792 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 @@ -160,7 +160,8 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { EndpointPort endpointPort = findEndpointPort(s); instances.add(new KubernetesServiceInstance(instanceId, serviceId, - endpointAddress, endpointPort, endpointMetadata, + endpointAddress.getIp(), endpointPort.getPort(), + endpointMetadata, this.isServicePortSecureResolver .resolve(new DefaultIsServicePortSecureResolver.Input( endpointPort.getPort(), diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java index 9c1a6180..a394f181 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java @@ -19,9 +19,6 @@ package org.springframework.cloud.kubernetes.discovery; import java.net.URI; import java.util.Map; -import io.fabric8.kubernetes.api.model.EndpointAddress; -import io.fabric8.kubernetes.api.model.EndpointPort; - import org.springframework.cloud.client.ServiceInstance; /** @@ -37,43 +34,49 @@ public class KubernetesServiceInstance implements ServiceInstance { private static final String DSL = "//"; - private static final String COLN = ":"; + private static final String COLON = ":"; - private final String instanceId; + private String instanceId; - private final String serviceId; + private String serviceId; - private final EndpointAddress endpointAddress; + private String host; - private final EndpointPort endpointPort; + private int port; - private final Boolean secure; + private URI uri; - private final Map metadata; + private Boolean secure; + + private Map metadata; /** * @param serviceId the id of the service. - * @param endpointAddress the address where the service instance can be found. - * @param endpointPort the port on which the service is running. + * @param host the address where the service instance can be found. + * @param port the port on which the service is running. * @param metadata a map containing metadata. * @param secure indicates whether or not the connection needs to be secure. * @deprecated - use other constructor */ @Deprecated - public KubernetesServiceInstance(String serviceId, EndpointAddress endpointAddress, - EndpointPort endpointPort, Map metadata, Boolean secure) { - this(null, serviceId, endpointAddress, endpointPort, metadata, secure); + public KubernetesServiceInstance(String serviceId, String host, int port, + Map metadata, Boolean secure) { + this(null, serviceId, host, port, metadata, secure); } - public KubernetesServiceInstance(String instanceId, String serviceId, - EndpointAddress endpointAddress, EndpointPort endpointPort, - Map metadata, Boolean secure) { + public KubernetesServiceInstance() { + + } + + public KubernetesServiceInstance(String instanceId, String serviceId, String host, + int port, Map metadata, Boolean secure) { this.instanceId = instanceId; this.serviceId = serviceId; - this.endpointAddress = endpointAddress; - this.endpointPort = endpointPort; + this.host = host; + this.port = port; this.metadata = metadata; this.secure = secure; + this.uri = createUri(secure ? HTTPS_PREFIX : HTTP_PREFIX, host, port); } @Override @@ -88,12 +91,12 @@ public class KubernetesServiceInstance implements ServiceInstance { @Override public String getHost() { - return this.endpointAddress.getIp(); + return this.host; } @Override public int getPort() { - return this.endpointPort.getPort(); + return this.port; } @Override @@ -103,10 +106,7 @@ public class KubernetesServiceInstance implements ServiceInstance { @Override public URI getUri() { - StringBuilder sb = new StringBuilder(); - sb.append(getScheme()).append(COLN).append(DSL).append(getHost()).append(COLN) - .append(getPort()); - return URI.create(sb.toString()); + return uri; } public Map getMetadata() { @@ -118,4 +118,11 @@ public class KubernetesServiceInstance implements ServiceInstance { return isSecure() ? HTTPS_PREFIX : HTTP_PREFIX; } + private URI createUri(String scheme, String host, int port) { + StringBuilder sb = new StringBuilder(); + sb.append(scheme).append(COLON).append(DSL).append(host).append(COLON) + .append(port); + return URI.create(sb.toString()); + } + } diff --git a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstanceTests.java b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstanceTests.java index eb3738e5..8cf648c6 100644 --- a/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstanceTests.java +++ b/spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstanceTests.java @@ -37,7 +37,8 @@ public class KubernetesServiceInstanceTests { EndpointPort port = new EndpointPort(); port.setPort(8080); KubernetesServiceInstance instance = new KubernetesServiceInstance("123", - "myservice", address, port, Collections.emptyMap(), secure); + "myservice", address.getIp(), port.getPort(), Collections.emptyMap(), + secure); assertThat(instance.getInstanceId()).isEqualTo("123"); assertThat(instance.getServiceId()).isEqualTo("myservice"); diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java index b698bf8c..227d4f63 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -30,11 +30,6 @@ import org.springframework.context.annotation.Configuration; @LoadBalancerClients(defaultConfiguration = KubernetesClientConfiguration.class) public class KubernetesLoadBalancerAutoConfiguration { - @Bean - KubernetesLoadBalancerProperties properties() { - return new KubernetesLoadBalancerProperties(); - } - @Bean KubernetesServiceInstanceMapper mapper(KubernetesLoadBalancerProperties properties, KubernetesDiscoveryProperties discoveryProperties) { diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java deleted file mode 100644 index 8967e072..00000000 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstance.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2013-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.loadbalancer; - -import java.net.URI; -import java.util.Map; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * @author Piotr Minkowski - */ -public class KubernetesServiceInstance implements ServiceInstance { - - private String serviceId; - - private String instanceId; - - private int port; - - private boolean secure; - - private String host; - - private URI uri; - - private Map metadata; - - KubernetesServiceInstance() { - } - - KubernetesServiceInstance(String serviceId, String instanceId, int port, - boolean secure, String host, URI uri, Map metadata) { - this.serviceId = serviceId; - this.instanceId = instanceId; - this.port = port; - this.secure = secure; - this.host = host; - this.uri = uri; - this.metadata = metadata; - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public String getInstanceId() { - return instanceId; - } - - @Override - public String getHost() { - return host; - } - - @Override - public int getPort() { - return port; - } - - @Override - public boolean isSecure() { - return secure; - } - - @Override - public URI getUri() { - return uri; - } - - @Override - public Map getMetadata() { - return metadata; - } - -} diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java index a54baf5f..cff0b9bc 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java @@ -29,6 +29,7 @@ import io.fabric8.kubernetes.client.utils.Utils; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; /** * @author Piotr Minkowski @@ -70,10 +71,8 @@ public class KubernetesServiceInstanceMapper { } final String host = createHost(service); final boolean secure = isSecure(service, port); - return new KubernetesServiceInstance(meta.getName(), meta.getUid(), - port.getPort(), secure, host, - createUri(secure ? "https" : "http", host, port.getPort()), - getServiceMetadata(service)); + return new KubernetesServiceInstance(meta.getUid(), meta.getName(), host, + port.getPort(), getServiceMetadata(service), secure); } private Map getServiceMetadata(Service service) { diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java index 2d5d5fc2..098a2a9f 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; public class KubernetesServiceInstanceMapperTest { diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java index 542fe17a..c0447026 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java @@ -37,6 +37,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; import org.springframework.core.env.Environment; import static org.mockito.ArgumentMatchers.any; From b76de6a69a9fd6e3758931ae23dd66eb3045ed17 Mon Sep 17 00:00:00 2001 From: piomin Date: Thu, 20 Aug 2020 13:35:55 +0200 Subject: [PATCH 11/24] #562 Review --- .../discovery/KubernetesServiceInstance.java | 26 ++++++------------- ...va => LoadBalancerAllNamespacesTests.java} | 2 +- ...lancerTest.java => LoadBalancerTests.java} | 2 +- .../KubernetesLoadBalancerProperties.java | 6 ++--- .../KubernetesServiceInstanceMapper.java | 8 ------ .../KubernetesServicesListSupplier.java | 8 +++--- ...KubernetesServiceInstanceMapperTests.java} | 2 +- ...> KubernetesServiceListSupplierTests.java} | 8 +++--- 8 files changed, 23 insertions(+), 39 deletions(-) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/{LoadBalancerAllNamespacesTest.java => LoadBalancerAllNamespacesTests.java} (98%) rename spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/{LoadBalancerTest.java => LoadBalancerTests.java} (99%) rename spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/{KubernetesServiceInstanceMapperTest.java => KubernetesServiceInstanceMapperTests.java} (98%) rename spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/{KubernetesServiceListSupplierTest.java => KubernetesServiceListSupplierTests.java} (94%) diff --git a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java index a394f181..d11ad1c9 100644 --- a/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java +++ b/spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesServiceInstance.java @@ -36,38 +36,28 @@ public class KubernetesServiceInstance implements ServiceInstance { private static final String COLON = ":"; - private String instanceId; + private final String instanceId; - private String serviceId; + private final String serviceId; - private String host; + private final String host; - private int port; + private final int port; - private URI uri; + private final URI uri; - private Boolean secure; + private final Boolean secure; - private Map metadata; + private final Map metadata; /** + * @param instanceId the id of the instance. * @param serviceId the id of the service. * @param host the address where the service instance can be found. * @param port the port on which the service is running. * @param metadata a map containing metadata. * @param secure indicates whether or not the connection needs to be secure. - * @deprecated - use other constructor */ - @Deprecated - public KubernetesServiceInstance(String serviceId, String host, int port, - Map metadata, Boolean secure) { - this(null, serviceId, host, port, metadata, secure); - } - - public KubernetesServiceInstance() { - - } - public KubernetesServiceInstance(String instanceId, String serviceId, String host, int port, Map metadata, Boolean secure) { this.instanceId = instanceId; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java similarity index 98% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java index e4f69bd7..804c91a2 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java @@ -36,7 +36,7 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.kubernetes.discovery.all-namespaces=true" }) @RunWith(SpringRunner.class) -public class LoadBalancerAllNamespacesTest { +public class LoadBalancerAllNamespacesTests { @Autowired RestTemplate restTemplate; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java similarity index 99% rename from spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java rename to spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java index 1d34c2f3..bc757212 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTest.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java @@ -35,7 +35,7 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @RunWith(SpringRunner.class) -public class LoadBalancerTest { +public class LoadBalancerTests { @Autowired RestTemplate restTemplate; diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java index 88e27152..f2d44086 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java @@ -25,13 +25,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties; public class KubernetesLoadBalancerProperties { /** - * Ribbon enabled,default true. + * Load balancer enabled,default true. */ private Boolean enabled = true; /** - * {@link KubernetesLoadBalancerMode} setting ribbon server list with ip of pod or - * service name. default value is POD. + * {@link KubernetesLoadBalancerMode} setting load balancer server list with ip of pod + * or service name. default value is POD. */ private KubernetesLoadBalancerMode mode = KubernetesLoadBalancerMode.POD; diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java index cff0b9bc..2ad20252 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java @@ -16,7 +16,6 @@ package org.springframework.cloud.kubernetes.loadbalancer; -import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -129,11 +128,4 @@ public class KubernetesServiceInstanceMapper { properties.getClusterDomain()); } - private URI createUri(String scheme, String host, int port) { - StringBuilder sb = new StringBuilder(); - sb.append(scheme).append(COLON).append(DSL).append(host).append(COLON) - .append(port); - return URI.create(sb.toString()); - } - } diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java index 29d61bfa..bf807394 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -35,13 +35,13 @@ import org.springframework.core.env.Environment; */ public class KubernetesServicesListSupplier implements ServiceInstanceListSupplier { - private Environment environment; + private final Environment environment; - private KubernetesClient kubernetesClient; + private final KubernetesClient kubernetesClient; - private KubernetesDiscoveryProperties discoveryProperties; + private final KubernetesDiscoveryProperties discoveryProperties; - private KubernetesServiceInstanceMapper mapper; + private final KubernetesServiceInstanceMapper mapper; KubernetesServicesListSupplier(Environment environment, KubernetesClient kubernetesClient, KubernetesServiceInstanceMapper mapper, diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java similarity index 98% rename from spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java rename to spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java index 098a2a9f..fe5de07a 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTest.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; -public class KubernetesServiceInstanceMapperTest { +public class KubernetesServiceInstanceMapperTests { @Test public void testMapperSimple() { diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java similarity index 94% rename from spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java rename to spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java index c0447026..a7059876 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTest.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java @@ -44,7 +44,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) -public class KubernetesServiceListSupplierTest { +public class KubernetesServiceListSupplierTests { @Mock Environment environment; @@ -71,7 +71,8 @@ public class KubernetesServiceListSupplierTest { void testPositiveMatch() { when(environment.getProperty("loadbalancer.client.name")) .thenReturn("test-service"); - when(mapper.map(any(Service.class))).thenReturn(new KubernetesServiceInstance()); + when(mapper.map(any(Service.class))) + .thenReturn(new KubernetesServiceInstance("", "", "", 0, null, false)); when(this.client.getNamespace()).thenReturn("test"); when(this.client.services()).thenReturn(this.serviceOperation); when(this.serviceOperation.inNamespace("test")).thenReturn(namespaceOperation); @@ -89,7 +90,8 @@ public class KubernetesServiceListSupplierTest { void testPositiveMatchAllNamespaces() { when(environment.getProperty("loadbalancer.client.name")) .thenReturn("test-service"); - when(mapper.map(any(Service.class))).thenReturn(new KubernetesServiceInstance()); + when(mapper.map(any(Service.class))) + .thenReturn(new KubernetesServiceInstance("", "", "", 0, null, false)); when(this.client.services()).thenReturn(this.serviceOperation); when(this.serviceOperation.inAnyNamespace()).thenReturn(this.multiDeletable); when(this.multiDeletable.withField("metadata.name", "test-service")) From 25709769cea51b0073f4b217ff9ac346ad0c69df Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 12:06:25 +0200 Subject: [PATCH 12/24] #562 Refactoring --- pom.xml | 1 + ...bernetesLoadBalancerAutoConfiguration.java | 8 +++--- ...netesLoadBalancerClientConfiguration.java} | 2 +- .../KubernetesServiceInstanceMapper.java | 4 --- .../KubernetesServicesListSupplier.java | 2 +- .../KubernetesServiceListSupplierTests.java | 2 +- spring-cloud-starter-kubernetes-all/pom.xml | 2 +- .../pom.xml | 26 +++++++++++++++++++ 8 files changed, 36 insertions(+), 11 deletions(-) rename spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/{KubernetesClientConfiguration.java => KubernetesLoadBalancerClientConfiguration.java} (96%) create mode 100644 spring-cloud-starter-kubernetes-loadbalancer/pom.xml diff --git a/pom.xml b/pom.xml index 4ec0d59d..9acd9f4b 100644 --- a/pom.xml +++ b/pom.xml @@ -97,6 +97,7 @@ spring-cloud-kubernetes-integration-tests docs spring-cloud-kubernetes-loadbalancer + spring-cloud-starter-kubernetes-loadbalancer diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java index 227d4f63..e1732219 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.loadbalancer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; @@ -25,9 +26,10 @@ import org.springframework.context.annotation.Configuration; /** * @author Piotr Minkowski */ -@Configuration -@EnableConfigurationProperties -@LoadBalancerClients(defaultConfiguration = KubernetesClientConfiguration.class) +@Configuration(proxyBeanMethods = false) +@EnableConfigurationProperties(KubernetesLoadBalancerProperties.class) +@ConditionalOnProperty("spring.cloud.kubernetes.loadbalancer.enabled") +@LoadBalancerClients(defaultConfiguration = KubernetesLoadBalancerClientConfiguration.class) public class KubernetesLoadBalancerAutoConfiguration { @Bean diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java similarity index 96% rename from spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java rename to spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java index c16c9fe8..adfb8730 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesClientConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java @@ -28,7 +28,7 @@ import org.springframework.core.env.Environment; * * @author Piotr Minkowski */ -public class KubernetesClientConfiguration { +public class KubernetesLoadBalancerClientConfiguration { @Bean @ConditionalOnProperty(name = "spring.cloud.kubernetes.loadbalancer.mode", diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java index 2ad20252..c4826323 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java @@ -35,10 +35,6 @@ import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; */ public class KubernetesServiceInstanceMapper { - private static final String DSL = "//"; - - private static final String COLON = ":"; - private final KubernetesLoadBalancerProperties properties; private final KubernetesDiscoveryProperties discoveryProperties; diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java index bf807394..463fc9ad 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -76,7 +76,7 @@ public class KubernetesServicesListSupplier implements ServiceInstanceListSuppli result.add(mapper.map(service)); } } - return Flux.just(result); + return Flux.defer(() -> Flux.just(result)); } } diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java index a7059876..b0ed844c 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java @@ -110,7 +110,7 @@ public class KubernetesServiceListSupplierTests { private Service buildService(String name, int port) { return new ServiceBuilder().withNewMetadata().withName(name).endMetadata() - .withNewSpec().addNewPort().withPort(8080).endPort().endSpec().build(); + .withNewSpec().addNewPort().withPort(port).endPort().endSpec().build(); } } diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml index fd9567f0..a3f3fc73 100644 --- a/spring-cloud-starter-kubernetes-all/pom.xml +++ b/spring-cloud-starter-kubernetes-all/pom.xml @@ -48,7 +48,7 @@ org.springframework.cloud - spring-cloud-starter-loadbalancer + spring-cloud-kubernetes-loadbalancer diff --git a/spring-cloud-starter-kubernetes-loadbalancer/pom.xml b/spring-cloud-starter-kubernetes-loadbalancer/pom.xml new file mode 100644 index 00000000..93c561ca --- /dev/null +++ b/spring-cloud-starter-kubernetes-loadbalancer/pom.xml @@ -0,0 +1,26 @@ + + + + spring-cloud-kubernetes + org.springframework.cloud + 2.0.0-SNAPSHOT + + 4.0.0 + + spring-cloud-starter-kubernetes-loadbalancer + Spring Cloud Kubernetes :: Starter :: LoadBalancer + + + + org.springframework.cloud + spring-cloud-kubernetes-core + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + From cd24b5e0c275efff69b6d02a55c758937027077c Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 12:09:37 +0200 Subject: [PATCH 13/24] #562 Refactoring --- .../loadbalancer/KubernetesLoadBalancerAutoConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java index e1732219..5fd8e7d9 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -29,7 +29,8 @@ import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(KubernetesLoadBalancerProperties.class) @ConditionalOnProperty("spring.cloud.kubernetes.loadbalancer.enabled") -@LoadBalancerClients(defaultConfiguration = KubernetesLoadBalancerClientConfiguration.class) +@LoadBalancerClients( + defaultConfiguration = KubernetesLoadBalancerClientConfiguration.class) public class KubernetesLoadBalancerAutoConfiguration { @Bean From 7adfad8ef499c5518509ce244685ae1654ebdcab Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 13:49:50 +0200 Subject: [PATCH 14/24] #562 Adding dependencies to loadbalancer module --- spring-cloud-kubernetes-dependencies/pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 333188b1..3ed5384a 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -86,6 +86,12 @@ ${project.version} + + org.springframework.cloud + spring-cloud-kubernetes-loadbalancer + ${project.version} + + org.springframework.cloud @@ -99,6 +105,12 @@ ${project.version} + + org.springframework.cloud + spring-cloud-starter-kubernetes-loadbalancer + ${project.version} + + org.springframework.cloud spring-cloud-starter-kubernetes-all From d5592f9f9c55622a8f7e7a8fe109281a0918ecd4 Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 13:59:08 +0200 Subject: [PATCH 15/24] #962 Fixing tests dependent to KubernetesServiceInstance --- .../HttpBasedConfigurationWatchChangeDetectorTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 index 3636bbca..cd42b5b8 100644 --- 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 @@ -99,7 +99,7 @@ public class HttpBasedConfigurationWatchChangeDetectorTests { fooEndpointPort.setPort(wireMockRule.port()); List instances = new ArrayList<>(); KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( - "foo", "foo", fooEndpointAddress, fooEndpointPort, new HashMap<>(), + "foo", "foo", fooEndpointAddress.getIp(), fooEndpointPort.getPort(), new HashMap<>(), false); instances.add(fooServiceInstance); when(reactiveDiscoveryClient.getInstances(eq("foo"))) @@ -185,7 +185,7 @@ public class HttpBasedConfigurationWatchChangeDetectorTests { fooEndpointPort.setPort(wireMockRule.port()); List instances = new ArrayList<>(); KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( - "foo", "foo", fooEndpointAddress, fooEndpointPort, metadata, false); + "foo", "foo", fooEndpointAddress.getIp(), fooEndpointPort.getPort(), metadata, false); instances.add(fooServiceInstance); when(reactiveDiscoveryClient.getInstances(eq("foo"))) .thenReturn(Flux.fromIterable(instances)); @@ -211,7 +211,7 @@ public class HttpBasedConfigurationWatchChangeDetectorTests { fooEndpointPort.setPort(wireMockRule.port()); List instances = new ArrayList<>(); KubernetesServiceInstance fooServiceInstance = new KubernetesServiceInstance( - "foo", "foo", fooEndpointAddress, fooEndpointPort, metadata, false); + "foo", "foo", fooEndpointAddress.getIp(), fooEndpointPort.getPort(), metadata, false); instances.add(fooServiceInstance); when(reactiveDiscoveryClient.getInstances(eq("foo"))) .thenReturn(Flux.fromIterable(instances)); From 89fbff829a4cdf44ead36ad2e375f0d3698a8cc7 Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 14:57:43 +0200 Subject: [PATCH 16/24] #962 Fixing errors + migrate to integration test to JUnit5 --- .../load-balancer/pom.xml | 2 +- .../LoadBalancerAllNamespacesTests.java | 25 +++++++------------ .../loadbalancer/LoadBalancerTests.java | 21 ++++++---------- .../pom.xml | 4 +++ 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml index eb47231f..99462d93 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -15,7 +15,7 @@ org.springframework.cloud - spring-cloud-starter-kubernetes-all + spring-cloud-starter-kubernetes-loadbalancer org.springframework.boot diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java index 804c91a2..0911f9ac 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java @@ -20,22 +20,20 @@ import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import org.junit.jupiter.api.Assertions; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestTemplate; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "spring.cloud.kubernetes.discovery.all-namespaces=true" }) -@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@TestPropertySource(properties = "spring.cloud.kubernetes.discovery.all-namespaces=true") +@EnableKubernetesMockClient(https = true, crud = true) public class LoadBalancerAllNamespacesTests { @Autowired @@ -44,15 +42,10 @@ public class LoadBalancerAllNamespacesTests { @LocalServerPort int randomServerPort; - @ClassRule - public static KubernetesServer server = new KubernetesServer(true, true); + static KubernetesClient client; - private static KubernetesClient client; - - @BeforeClass + @BeforeAll public static void setup() { - client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java index bc757212..743b5911 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java @@ -20,21 +20,18 @@ import io.fabric8.kubernetes.api.model.ServicePortBuilder; import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import org.junit.jupiter.api.Assertions; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@RunWith(SpringRunner.class) +@EnableKubernetesMockClient(https = true, crud = true) public class LoadBalancerTests { @Autowired @@ -43,15 +40,13 @@ public class LoadBalancerTests { @LocalServerPort int randomServerPort; - @ClassRule - public static KubernetesServer server = new KubernetesServer(true, true); + // @ClassRule + // public static KubernetesServer server = new KubernetesServer(true, true); - private static KubernetesClient client; + static KubernetesClient client; - @BeforeClass + @BeforeAll public static void setup() { - client = server.getClient(); - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); diff --git a/spring-cloud-starter-kubernetes-loadbalancer/pom.xml b/spring-cloud-starter-kubernetes-loadbalancer/pom.xml index 93c561ca..0fb03d3b 100644 --- a/spring-cloud-starter-kubernetes-loadbalancer/pom.xml +++ b/spring-cloud-starter-kubernetes-loadbalancer/pom.xml @@ -17,6 +17,10 @@ org.springframework.cloud spring-cloud-kubernetes-core + + org.springframework.cloud + spring-cloud-kubernetes-loadbalancer + org.springframework.cloud spring-cloud-starter-loadbalancer From 7bfaff6dcf97fb2954583ab328c6eb66561a5747 Mon Sep 17 00:00:00 2001 From: piomin Date: Mon, 24 Aug 2020 17:39:38 +0200 Subject: [PATCH 17/24] #562 Adding integration test for SERVICE mode --- .../load-balancer/pom.xml | 12 +++ .../LoadBalancerWithServiceTests.java | 89 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml index 99462d93..218b288f 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -31,6 +31,18 @@ kubernetes-server-mock test + + io.specto + hoverfly-java-junit5 + 0.13.0 + test + + + io.specto + hoverfly-java + 0.13.0 + test + diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java new file mode 100644 index 00000000..3430a7db --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -0,0 +1,89 @@ +package org.springframework.cloud.kubernetes.loadbalancer; + +import java.util.HashMap; + +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.specto.hoverfly.junit.core.Hoverfly; +import io.specto.hoverfly.junit.core.model.RequestFieldMatcher; +import io.specto.hoverfly.junit5.HoverflyExtension; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.web.client.RestTemplate; + +import static io.specto.hoverfly.junit.core.SimulationSource.dsl; +import static io.specto.hoverfly.junit.dsl.HoverflyDsl.service; +import static io.specto.hoverfly.junit.dsl.HttpBodyConverter.json; +import static io.specto.hoverfly.junit.dsl.ResponseCreators.success; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@TestPropertySource(properties = { + "spring.cloud.kubernetes.loadbalancer.mode=SERVICE", + "spring.cloud.kubernetes.loadbalancer.enabled=true" +}) +@EnableKubernetesMockClient +@ExtendWith(HoverflyExtension.class) +public class LoadBalancerWithServiceTests { + + @Autowired + RestTemplate restTemplate; + + static KubernetesClient client; + + @BeforeAll + public static void setup() { + System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, + client.getConfiguration().getMasterUrl()); + System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); + System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, + "false"); + System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); + } + + @Test + public void testLoadBalancerInServiceMode(Hoverfly hoverfly) { + hoverfly.simulate( + dsl(service("http://service-a.test.svc.cluster.local:8080") + .get("/greeting") + .willReturn(success().body("greeting"))), + dsl(service(RequestFieldMatcher.newRegexMatcher("(kubernetes.docker.internal).*")) + .post("/api/v1/namespaces/test/services").anyBody() + .willReturn(success() + .body(json(buildService("service-a", 8080, "test")))) + .get("/api/v1/namespaces/test/services/service-a") + .willReturn(success() + .body(json(buildService("service-a", 8080, "test")))))); + String response = restTemplate.getForObject("http://service-a/greeting", + String.class); + Assertions.assertNotNull(response); + Assertions.assertEquals("greeting", response); + } + + private Service buildService(String name, int port, String namespace) { + return new ServiceBuilder() + .withNewMetadata() + .withName(name) + .withNamespace(namespace) + .withLabels(new HashMap<>()) + .withAnnotations(new HashMap<>()) + .endMetadata() + .withNewSpec() + .addNewPort() + .withPort(port) + .endPort() + .endSpec() + .build(); + } + +} From 5d047a759157f98aeffda73e719862ff4124ad54 Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 25 Aug 2020 14:52:47 +0200 Subject: [PATCH 18/24] #562 Adding docs, javadoc + removed unused code --- docs/src/main/asciidoc/load-balancer.adoc | 28 +++++++++++++++++++ .../LoadBalancerAllNamespacesTests.java | 2 +- .../loadbalancer/LoadBalancerTests.java | 5 +--- ...bernetesLoadBalancerAutoConfiguration.java | 2 ++ ...rnetesLoadBalancerClientConfiguration.java | 2 +- .../KubernetesLoadBalancerMode.java | 2 ++ .../KubernetesLoadBalancerProperties.java | 2 ++ .../KubernetesServiceInstanceMapper.java | 2 ++ .../KubernetesServicesListSupplier.java | 3 ++ 9 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 docs/src/main/asciidoc/load-balancer.adoc diff --git a/docs/src/main/asciidoc/load-balancer.adoc b/docs/src/main/asciidoc/load-balancer.adoc new file mode 100644 index 00000000..bdb4813c --- /dev/null +++ b/docs/src/main/asciidoc/load-balancer.adoc @@ -0,0 +1,28 @@ +== LoadBalancer for Kubernetes +This project includes Spring Cloud Load Balancer for load balancing based on Kubernetes Endpoints and provides implementation of load balancer based on Kubernetes Service. +To include it to your project add the following dependency. +==== +[source,xml] +---- + + org.springframework.cloud + spring-cloud-starter-kubernetes-loadbalancer + +---- +==== + +To enable load balancing based on Kubernetes Service name use the following property. Then load balancer would try to call application using address, for example `service-a.default.svc.cluster.local` +==== +[source] +---- +spring.cloud.kubernetes.loadbalancer.mode=SERVICE +---- +==== + +To enabled load balancing across all namespaces use the following property. Property from `spring-cloud-kubernetes-discovery` module is respected. +==== +[source] +---- +spring.cloud.kubernetes.discovery.all-namespaces=true +---- +==== diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java index 0911f9ac..aeb17ada 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java @@ -33,7 +33,7 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = "spring.cloud.kubernetes.discovery.all-namespaces=true") -@EnableKubernetesMockClient(https = true, crud = true) +@EnableKubernetesMockClient(crud = true) public class LoadBalancerAllNamespacesTests { @Autowired diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java index 743b5911..0607ad50 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java @@ -31,7 +31,7 @@ import org.springframework.boot.web.server.LocalServerPort; import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableKubernetesMockClient(https = true, crud = true) +@EnableKubernetesMockClient(crud = true) public class LoadBalancerTests { @Autowired @@ -40,9 +40,6 @@ public class LoadBalancerTests { @LocalServerPort int randomServerPort; - // @ClassRule - // public static KubernetesServer server = new KubernetesServer(true, true); - static KubernetesClient client; @BeforeAll diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java index 5fd8e7d9..417861dc 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerAutoConfiguration.java @@ -24,6 +24,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** + * Kubernetes load balancer auto-configuration. + * * @author Piotr Minkowski */ @Configuration(proxyBeanMethods = false) diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java index adfb8730..4201f4c8 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerClientConfiguration.java @@ -24,7 +24,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; /** - * Kubernetes load balancer client properties. + * Kubernetes load balancer client configuration. * * @author Piotr Minkowski */ diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java index 41eb66c4..eaff0c08 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerMode.java @@ -17,6 +17,8 @@ package org.springframework.cloud.kubernetes.loadbalancer; /** + * Kubernetes load balancer mode enum. + * * @author Piotr Minkowski */ public enum KubernetesLoadBalancerMode { diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java index f2d44086..1e9a3a15 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesLoadBalancerProperties.java @@ -19,6 +19,8 @@ package org.springframework.cloud.kubernetes.loadbalancer; import org.springframework.boot.context.properties.ConfigurationProperties; /** + * Kubernetes load balancer client properties. + * * @author Piotr Minkowski */ @ConfigurationProperties(prefix = "spring.cloud.kubernetes.loadbalancer") diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java index c4826323..cfe7bcef 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapper.java @@ -31,6 +31,8 @@ import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryPropert import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; /** + * Class for mapping Kubernetes Service object into {@link KubernetesServiceInstance}. + * * @author Piotr Minkowski */ public class KubernetesServiceInstanceMapper { diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java index 463fc9ad..19ac28ad 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -31,6 +31,9 @@ import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.core.env.Environment; /** + * Implementation of {@link ServiceInstanceListSupplier} for load balancer + * in SERVICE mode + * * @author Piotr Minkowski */ public class KubernetesServicesListSupplier implements ServiceInstanceListSupplier { From f0297f5a600cc00aa1a1c3e2ea458936ea5f038b Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 25 Aug 2020 16:26:25 +0200 Subject: [PATCH 19/24] #562 Adding docs, javadoc + removed unused code --- .../loadbalancer/KubernetesServicesListSupplier.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java index 19ac28ad..63447b91 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java +++ b/spring-cloud-kubernetes-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServicesListSupplier.java @@ -31,8 +31,8 @@ import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.core.env.Environment; /** - * Implementation of {@link ServiceInstanceListSupplier} for load balancer - * in SERVICE mode + * Implementation of {@link ServiceInstanceListSupplier} for load balancer in SERVICE + * mode. * * @author Piotr Minkowski */ From 0d6ded52d75c575f19663eea2c362e771a2e9698 Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 25 Aug 2020 22:43:17 +0200 Subject: [PATCH 20/24] #562 Adding integration test for SERVICE mode + fixing ascii docs --- .../asciidoc/spring-cloud-kubernetes.adoc | 2 + spring-cloud-kubernetes-dependencies/pom.xml | 13 ++++ .../load-balancer/pom.xml | 2 - .../LoadBalancerAllNamespacesTests.java | 4 +- .../loadbalancer/LoadBalancerTests.java | 6 +- .../LoadBalancerWithServiceTests.java | 69 ++++++++++--------- 6 files changed, 57 insertions(+), 39 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc b/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc index 83839184..994b8eaf 100644 --- a/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc +++ b/docs/src/main/asciidoc/spring-cloud-kubernetes.adoc @@ -22,6 +22,8 @@ include::pod-health-indicator.adoc[] include::leader-election.adoc[] +include::load-balancer.adoc[] + include::security-service-accounts.adoc[] include::service-registry.adoc[] diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 3ed5384a..6262bc1f 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -34,6 +34,7 @@ 1.4.0.Final 1.15.2 + 0.13.0 4.10.3 1.1.1 0.1.2 @@ -142,6 +143,18 @@ ${arquillian-cube.version} test + + io.specto + hoverfly-java-junit5 + ${hoverfly.version} + test + + + io.specto + hoverfly-java + ${hoverfly.version} + test + io.fabric8 diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml index 218b288f..a89caea8 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml @@ -34,13 +34,11 @@ io.specto hoverfly-java-junit5 - 0.13.0 test io.specto hoverfly-java - 0.13.0 test diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java index aeb17ada..2988f47f 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java @@ -45,7 +45,7 @@ public class LoadBalancerAllNamespacesTests { static KubernetesClient client; @BeforeAll - public static void setup() { + static void setup() { System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); @@ -57,7 +57,7 @@ public class LoadBalancerAllNamespacesTests { } @Test - public void testLoadBalancerDifferentNamespace() { + void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); String response = restTemplate.getForObject("http://service-b/greeting", String.class); diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java index 0607ad50..8500cdab 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java @@ -43,7 +43,7 @@ public class LoadBalancerTests { static KubernetesClient client; @BeforeAll - public static void setup() { + static void setup() { System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); @@ -55,7 +55,7 @@ public class LoadBalancerTests { } @Test - public void testLoadBalancerSameNamespace() { + void testLoadBalancerSameNamespace() { createTestData("service-a", "test"); String response = restTemplate.getForObject("http://service-a/greeting", String.class); @@ -64,7 +64,7 @@ public class LoadBalancerTests { } @Test - public void testLoadBalancerDifferentNamespace() { + void testLoadBalancerDifferentNamespace() { createTestData("service-b", "b"); Assertions.assertThrows(IllegalStateException.class, () -> restTemplate .getForObject("http://service-b/greeting", String.class)); diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java index 3430a7db..ae1634fb 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -1,3 +1,19 @@ +/* + * 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.loadbalancer; import java.util.HashMap; @@ -26,10 +42,8 @@ import static io.specto.hoverfly.junit.dsl.HttpBodyConverter.json; import static io.specto.hoverfly.junit.dsl.ResponseCreators.success; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@TestPropertySource(properties = { - "spring.cloud.kubernetes.loadbalancer.mode=SERVICE", - "spring.cloud.kubernetes.loadbalancer.enabled=true" -}) +@TestPropertySource(properties = { "spring.cloud.kubernetes.loadbalancer.mode=SERVICE", + "spring.cloud.kubernetes.loadbalancer.enabled=true" }) @EnableKubernetesMockClient @ExtendWith(HoverflyExtension.class) public class LoadBalancerWithServiceTests { @@ -40,50 +54,41 @@ public class LoadBalancerWithServiceTests { static KubernetesClient client; @BeforeAll - public static void setup() { + static void setup() { System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, - client.getConfiguration().getMasterUrl()); + client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, - "false"); + "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); } @Test - public void testLoadBalancerInServiceMode(Hoverfly hoverfly) { + void testLoadBalancerInServiceMode(Hoverfly hoverfly) { hoverfly.simulate( - dsl(service("http://service-a.test.svc.cluster.local:8080") - .get("/greeting") - .willReturn(success().body("greeting"))), - dsl(service(RequestFieldMatcher.newRegexMatcher("(kubernetes.docker.internal).*")) - .post("/api/v1/namespaces/test/services").anyBody() - .willReturn(success() - .body(json(buildService("service-a", 8080, "test")))) - .get("/api/v1/namespaces/test/services/service-a") - .willReturn(success() - .body(json(buildService("service-a", 8080, "test")))))); + dsl(service("http://service-a.test.svc.cluster.local:8080") + .get("/greeting").willReturn(success().body("greeting"))), + dsl(service(RequestFieldMatcher + .newRegexMatcher("(kubernetes.docker.internal).*")) + .post("/api/v1/namespaces/test/services").anyBody() + .willReturn(success().body( + json(buildService("service-a", 8080, "test")))) + .get("/api/v1/namespaces/test/services/service-a") + .willReturn(success().body( + json(buildService("service-a", 8080, "test")))))); String response = restTemplate.getForObject("http://service-a/greeting", - String.class); + String.class); Assertions.assertNotNull(response); Assertions.assertEquals("greeting", response); } private Service buildService(String name, int port, String namespace) { - return new ServiceBuilder() - .withNewMetadata() - .withName(name) - .withNamespace(namespace) - .withLabels(new HashMap<>()) - .withAnnotations(new HashMap<>()) - .endMetadata() - .withNewSpec() - .addNewPort() - .withPort(port) - .endPort() - .endSpec() - .build(); + return new ServiceBuilder().withNewMetadata().withName(name) + .withNamespace(namespace).withLabels(new HashMap<>()) + .withAnnotations(new HashMap<>()).endMetadata().withNewSpec().addNewPort() + .withPort(port).endPort().endSpec().build(); } } From b6f7da17d3948735c451dedf721235825dbef1df Mon Sep 17 00:00:00 2001 From: piomin Date: Tue, 25 Aug 2020 23:12:04 +0200 Subject: [PATCH 21/24] #562 Fixing integration tests for SERVICE mode --- .../loadbalancer/LoadBalancerWithServiceTests.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java index ae1634fb..a117fdb4 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -20,6 +20,8 @@ import java.util.HashMap; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.api.model.ServicePortBuilder; +import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; @@ -78,6 +80,7 @@ public class LoadBalancerWithServiceTests { .get("/api/v1/namespaces/test/services/service-a") .willReturn(success().body( json(buildService("service-a", 8080, "test")))))); + createTestData("service-a", 8080, "test"); String response = restTemplate.getForObject("http://service-a/greeting", String.class); Assertions.assertNotNull(response); @@ -91,4 +94,12 @@ public class LoadBalancerWithServiceTests { .withPort(port).endPort().endSpec().build(); } + private void createTestData(String name, int port, String namespace) { + client.services().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).endMetadata() + .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() + .withProtocol("TCP").withPort(port).build()).build()) + .done(); + } + } From 517dd046ca625509dca7a21c6d03b6808930ca4e Mon Sep 17 00:00:00 2001 From: piomin Date: Wed, 26 Aug 2020 00:14:45 +0200 Subject: [PATCH 22/24] #562 Fix errors + logging --- .../LoadBalancerWithServiceTests.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java index a117fdb4..24f9cb94 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -26,12 +26,13 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.specto.hoverfly.junit.core.Hoverfly; -import io.specto.hoverfly.junit.core.model.RequestFieldMatcher; import io.specto.hoverfly.junit5.HoverflyExtension; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -50,6 +51,8 @@ import static io.specto.hoverfly.junit.dsl.ResponseCreators.success; @ExtendWith(HoverflyExtension.class) public class LoadBalancerWithServiceTests { + private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalancerWithServiceTests.class); + @Autowired RestTemplate restTemplate; @@ -59,6 +62,7 @@ public class LoadBalancerWithServiceTests { static void setup() { System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl()); + LOGGER.info("Master URL: {}", client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, @@ -72,15 +76,16 @@ public class LoadBalancerWithServiceTests { hoverfly.simulate( dsl(service("http://service-a.test.svc.cluster.local:8080") .get("/greeting").willReturn(success().body("greeting"))), - dsl(service(RequestFieldMatcher - .newRegexMatcher("(kubernetes.docker.internal).*")) - .post("/api/v1/namespaces/test/services").anyBody() - .willReturn(success().body( - json(buildService("service-a", 8080, "test")))) + dsl(service(client.getConfiguration().getMasterUrl() + .replace("/", "") + .replace("https:", "")) +// .post("/api/v1/namespaces/test/services").anyBody() +// .willReturn(success().body( +// json(buildService("service-a", 8080, "test")))) .get("/api/v1/namespaces/test/services/service-a") .willReturn(success().body( json(buildService("service-a", 8080, "test")))))); - createTestData("service-a", 8080, "test"); +// createTestData("service-a", 8080, "test"); String response = restTemplate.getForObject("http://service-a/greeting", String.class); Assertions.assertNotNull(response); @@ -100,6 +105,10 @@ public class LoadBalancerWithServiceTests { .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() .withProtocol("TCP").withPort(port).build()).build()) .done(); + client.endpoints().inNamespace(namespace).createNew().withNewMetadata() + .withName(name).endMetadata().addNewSubset().addNewAddress() + .withIp("localhost").endAddress().addNewPort().withName("http") + .withPort(port).endPort().endSubset().done(); } } From be1d60d0645feea51c59ce154291fe42c22e8e7c Mon Sep 17 00:00:00 2001 From: piomin Date: Wed, 26 Aug 2020 00:35:46 +0200 Subject: [PATCH 23/24] #562 Fixing integration test for SERVICE mode --- .../LoadBalancerWithServiceTests.java | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java index 24f9cb94..1c662a30 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -20,11 +20,8 @@ import java.util.HashMap; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; -import io.fabric8.kubernetes.api.model.ServicePortBuilder; -import io.fabric8.kubernetes.api.model.ServiceSpecBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.specto.hoverfly.junit.core.Hoverfly; import io.specto.hoverfly.junit5.HoverflyExtension; import org.junit.jupiter.api.Assertions; @@ -47,7 +44,6 @@ import static io.specto.hoverfly.junit.dsl.ResponseCreators.success; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = { "spring.cloud.kubernetes.loadbalancer.mode=SERVICE", "spring.cloud.kubernetes.loadbalancer.enabled=true" }) -@EnableKubernetesMockClient @ExtendWith(HoverflyExtension.class) public class LoadBalancerWithServiceTests { @@ -55,14 +51,11 @@ public class LoadBalancerWithServiceTests { @Autowired RestTemplate restTemplate; - - static KubernetesClient client; + @Autowired + KubernetesClient client; @BeforeAll static void setup() { - System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, - client.getConfiguration().getMasterUrl()); - LOGGER.info("Master URL: {}", client.getConfiguration().getMasterUrl()); System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, @@ -73,19 +66,16 @@ public class LoadBalancerWithServiceTests { @Test void testLoadBalancerInServiceMode(Hoverfly hoverfly) { + LOGGER.info("Master URL: {}", client.getConfiguration().getMasterUrl()); hoverfly.simulate( dsl(service("http://service-a.test.svc.cluster.local:8080") .get("/greeting").willReturn(success().body("greeting"))), dsl(service(client.getConfiguration().getMasterUrl() .replace("/", "") .replace("https:", "")) -// .post("/api/v1/namespaces/test/services").anyBody() -// .willReturn(success().body( -// json(buildService("service-a", 8080, "test")))) .get("/api/v1/namespaces/test/services/service-a") .willReturn(success().body( json(buildService("service-a", 8080, "test")))))); -// createTestData("service-a", 8080, "test"); String response = restTemplate.getForObject("http://service-a/greeting", String.class); Assertions.assertNotNull(response); @@ -99,16 +89,4 @@ public class LoadBalancerWithServiceTests { .withPort(port).endPort().endSpec().build(); } - private void createTestData(String name, int port, String namespace) { - client.services().inNamespace(namespace).createNew().withNewMetadata() - .withName(name).endMetadata() - .withSpec(new ServiceSpecBuilder().withPorts(new ServicePortBuilder() - .withProtocol("TCP").withPort(port).build()).build()) - .done(); - client.endpoints().inNamespace(namespace).createNew().withNewMetadata() - .withName(name).endMetadata().addNewSubset().addNewAddress() - .withIp("localhost").endAddress().addNewPort().withName("http") - .withPort(port).endPort().endSubset().done(); - } - } From 32c23ff0ae9262272a3110b0934d0b7799a3761c Mon Sep 17 00:00:00 2001 From: piomin Date: Wed, 26 Aug 2020 12:28:36 +0200 Subject: [PATCH 24/24] #562 Fixing test class names --- .../kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java | 2 +- .../cloud/kubernetes/loadbalancer/LoadBalancerTests.java | 2 +- .../kubernetes/loadbalancer/LoadBalancerWithServiceTests.java | 2 +- .../loadbalancer/KubernetesServiceInstanceMapperTests.java | 2 +- .../loadbalancer/KubernetesServiceListSupplierTests.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java index 2988f47f..29e87c79 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerAllNamespacesTests.java @@ -34,7 +34,7 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource(properties = "spring.cloud.kubernetes.discovery.all-namespaces=true") @EnableKubernetesMockClient(crud = true) -public class LoadBalancerAllNamespacesTests { +class LoadBalancerAllNamespacesTests { @Autowired RestTemplate restTemplate; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java index 8500cdab..41b01f68 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerTests.java @@ -32,7 +32,7 @@ import org.springframework.web.client.RestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableKubernetesMockClient(crud = true) -public class LoadBalancerTests { +class LoadBalancerTests { @Autowired RestTemplate restTemplate; diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java index 1c662a30..f11c1291 100644 --- a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java +++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/LoadBalancerWithServiceTests.java @@ -45,7 +45,7 @@ import static io.specto.hoverfly.junit.dsl.ResponseCreators.success; @TestPropertySource(properties = { "spring.cloud.kubernetes.loadbalancer.mode=SERVICE", "spring.cloud.kubernetes.loadbalancer.enabled=true" }) @ExtendWith(HoverflyExtension.class) -public class LoadBalancerWithServiceTests { +class LoadBalancerWithServiceTests { private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalancerWithServiceTests.class); diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java index fe5de07a..c49d5187 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceInstanceMapperTests.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; -public class KubernetesServiceInstanceMapperTests { +class KubernetesServiceInstanceMapperTests { @Test public void testMapperSimple() { diff --git a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java index b0ed844c..9dd9c0ad 100644 --- a/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java +++ b/spring-cloud-kubernetes-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/loadbalancer/KubernetesServiceListSupplierTests.java @@ -44,7 +44,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) -public class KubernetesServiceListSupplierTests { +class KubernetesServiceListSupplierTests { @Mock Environment environment;