Merge branch '3.0.x'
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.discovery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Use for discovery service implementation.
|
||||
* @author wind57
|
||||
*/
|
||||
public record Service(String name, List<DefaultKubernetesServiceInstance> serviceInstances) {
|
||||
}
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.discoveryserver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.client.discovery.reactive.KubernetesInformerReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.Service;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -41,8 +41,10 @@ public class DiscoveryServerController {
|
||||
|
||||
@GetMapping("/apps")
|
||||
public Flux<Service> apps() {
|
||||
return reactiveDiscoveryClient.getServices().flatMap(service -> reactiveDiscoveryClient.getInstances(service)
|
||||
.collectList().flatMap(serviceInstances -> Mono.just(new Service(service, serviceInstances))));
|
||||
return reactiveDiscoveryClient.getServices()
|
||||
.flatMap(service -> reactiveDiscoveryClient.getInstances(service).collectList()
|
||||
.flatMap(serviceInstances -> Mono.just(new Service(service,
|
||||
serviceInstances.stream().map(x -> (DefaultKubernetesServiceInstance) x).toList()))));
|
||||
}
|
||||
|
||||
@GetMapping("/apps/{name}")
|
||||
@@ -56,8 +58,4 @@ public class DiscoveryServerController {
|
||||
.filter(serviceInstance -> serviceInstance.getInstanceId().equals(instanceId)).singleOrEmpty();
|
||||
}
|
||||
|
||||
record Service(String name, List<ServiceInstance> serviceInstances) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import reactor.test.StepVerifier;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.client.discovery.reactive.KubernetesInformerReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.Service;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -40,26 +40,26 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
class DiscoveryServerControllerTests {
|
||||
|
||||
private static final KubernetesServiceInstance SERVICE_A_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
private static final DefaultKubernetesServiceInstance SERVICE_A_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
"serviceAInstance1", "serviceAInstance1", "2.2.2.2", 8080, Map.of(), false, "namespace1", null);
|
||||
|
||||
private static final KubernetesServiceInstance SERVICE_A_INSTANCE_2 = new DefaultKubernetesServiceInstance(
|
||||
private static final DefaultKubernetesServiceInstance SERVICE_A_INSTANCE_2 = new DefaultKubernetesServiceInstance(
|
||||
"serviceAInstance2", "serviceAInstance2", "2.2.2.2", 8080, Map.of(), false, "namespace1", null);
|
||||
|
||||
private static final KubernetesServiceInstance SERVICE_A_INSTANCE_3 = new DefaultKubernetesServiceInstance(
|
||||
private static final DefaultKubernetesServiceInstance SERVICE_A_INSTANCE_3 = new DefaultKubernetesServiceInstance(
|
||||
"serviceAInstance3", "serviceAInstance3", "2.2.2.2", 8080, Map.of(), false, "namespace2", null);
|
||||
|
||||
private static final KubernetesServiceInstance SERVICE_B_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
private static final DefaultKubernetesServiceInstance SERVICE_B_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
"serviceBInstance1", "serviceBInstance1", "2.2.2.2", 8080, Map.of(), false, "namespace1", null);
|
||||
|
||||
private static final KubernetesServiceInstance SERVICE_C_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
private static final DefaultKubernetesServiceInstance SERVICE_C_INSTANCE_1 = new DefaultKubernetesServiceInstance(
|
||||
"serviceCInstance1", "serviceCInstance1", "2.2.2.2", 8080, Map.of(), false, "namespace2", null);
|
||||
|
||||
private static DiscoveryServerController.Service serviceA;
|
||||
private static Service serviceA;
|
||||
|
||||
private static DiscoveryServerController.Service serviceB;
|
||||
private static Service serviceB;
|
||||
|
||||
private static DiscoveryServerController.Service serviceC;
|
||||
private static Service serviceC;
|
||||
|
||||
private static KubernetesInformerReactiveDiscoveryClient discoveryClient;
|
||||
|
||||
@@ -67,17 +67,17 @@ class DiscoveryServerControllerTests {
|
||||
static void beforeAll() {
|
||||
Flux<String> services = Flux.just("serviceA", "serviceB", "serviceC");
|
||||
|
||||
List<ServiceInstance> serviceAInstanceList = new ArrayList<>();
|
||||
List<DefaultKubernetesServiceInstance> serviceAInstanceList = new ArrayList<>();
|
||||
serviceAInstanceList.add(SERVICE_A_INSTANCE_1);
|
||||
serviceAInstanceList.add(SERVICE_A_INSTANCE_2);
|
||||
serviceAInstanceList.add(SERVICE_A_INSTANCE_3);
|
||||
|
||||
Flux<ServiceInstance> serviceAInstances = Flux.fromIterable(serviceAInstanceList);
|
||||
|
||||
List<ServiceInstance> serviceBInstanceList = Collections.singletonList(SERVICE_B_INSTANCE_1);
|
||||
List<DefaultKubernetesServiceInstance> serviceBInstanceList = Collections.singletonList(SERVICE_B_INSTANCE_1);
|
||||
Flux<ServiceInstance> serviceBInstances = Flux.fromIterable(serviceBInstanceList);
|
||||
|
||||
List<ServiceInstance> serviceCInstanceList = Collections.singletonList(SERVICE_C_INSTANCE_1);
|
||||
List<DefaultKubernetesServiceInstance> serviceCInstanceList = Collections.singletonList(SERVICE_C_INSTANCE_1);
|
||||
Flux<ServiceInstance> serviceCInstances = Flux.fromIterable(serviceCInstanceList);
|
||||
|
||||
discoveryClient = mock(KubernetesInformerReactiveDiscoveryClient.class);
|
||||
@@ -87,9 +87,9 @@ class DiscoveryServerControllerTests {
|
||||
when(discoveryClient.getInstances(eq("serviceC"))).thenReturn(serviceCInstances);
|
||||
when(discoveryClient.getInstances(eq("serviceD"))).thenReturn(Flux.empty());
|
||||
|
||||
serviceA = new DiscoveryServerController.Service("serviceA", serviceAInstanceList);
|
||||
serviceB = new DiscoveryServerController.Service("serviceB", serviceBInstanceList);
|
||||
serviceC = new DiscoveryServerController.Service("serviceC", serviceCInstanceList);
|
||||
serviceA = new Service("serviceA", serviceAInstanceList);
|
||||
serviceB = new Service("serviceB", serviceBInstanceList);
|
||||
serviceC = new Service("serviceC", serviceCInstanceList);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -68,8 +70,9 @@ public class KubernetesDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
KubernetesServiceInstance[] responseBody = rest
|
||||
.getForEntity(discoveryServerUrl + "/apps/" + serviceId, KubernetesServiceInstance[].class).getBody();
|
||||
DefaultKubernetesServiceInstance[] responseBody = rest
|
||||
.getForEntity(discoveryServerUrl + "/apps/" + serviceId, DefaultKubernetesServiceInstance[].class)
|
||||
.getBody();
|
||||
if (responseBody != null && responseBody.length > 0) {
|
||||
return Arrays.stream(responseBody).filter(this::matchNamespaces).collect(Collectors.toList());
|
||||
}
|
||||
@@ -80,18 +83,18 @@ public class KubernetesDiscoveryClient implements DiscoveryClient {
|
||||
public List<String> getServices() {
|
||||
Service[] services = rest.getForEntity(discoveryServerUrl + "/apps", Service[].class).getBody();
|
||||
if (services != null && services.length > 0) {
|
||||
return Arrays.stream(services).filter(this::matchNamespaces).map(Service::getName).toList();
|
||||
return Arrays.stream(services).filter(this::matchNamespaces).map(Service::name).toList();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private boolean matchNamespaces(KubernetesServiceInstance kubernetesServiceInstance) {
|
||||
private boolean matchNamespaces(DefaultKubernetesServiceInstance kubernetesServiceInstance) {
|
||||
return emptyNamespaces || namespaces.contains(kubernetesServiceInstance.getNamespace());
|
||||
}
|
||||
|
||||
private boolean matchNamespaces(Service service) {
|
||||
return service.getServiceInstances().isEmpty()
|
||||
|| service.getServiceInstances().stream().anyMatch(this::matchNamespaces);
|
||||
return service.serviceInstances().isEmpty()
|
||||
|| service.serviceInstances().stream().anyMatch(this::matchNamespaces);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ import reactor.core.publisher.Flux;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@@ -57,14 +59,14 @@ public class KubernetesReactiveDiscoveryClient implements ReactiveDiscoveryClien
|
||||
@Cacheable("serviceinstances")
|
||||
public Flux<ServiceInstance> getInstances(String serviceId) {
|
||||
return webClient.get().uri("/apps/" + serviceId)
|
||||
.exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(KubernetesServiceInstance.class));
|
||||
.exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(DefaultKubernetesServiceInstance.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("services")
|
||||
public Flux<String> getServices() {
|
||||
return webClient.get().uri("/apps").exchangeToFlux(
|
||||
clientResponse -> clientResponse.bodyToFlux(Service.class).map(service -> service.getName()));
|
||||
return webClient.get().uri("/apps")
|
||||
.exchangeToFlux(clientResponse -> clientResponse.bodyToFlux(Service.class).map(Service::name));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class KubernetesServiceInstance implements ServiceInstance {
|
||||
|
||||
private String instanceId;
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class Service {
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.discovery;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -33,6 +32,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -133,9 +133,8 @@ class KubernetesDiscoveryClientTests {
|
||||
metadata.put("spring", "true");
|
||||
metadata.put("http", "8080");
|
||||
metadata.put("k8s", "true");
|
||||
assertThat(discoveryClient.getInstances("test-svc-3"))
|
||||
.contains(new KubernetesServiceInstance("uid2", "test-svc-3", "2.2.2.2", 8080, false,
|
||||
URI.create("http://2.2.2.2:8080"), metadata, "http", "namespace2"));
|
||||
assertThat(discoveryClient.getInstances("test-svc-3")).contains(new DefaultKubernetesServiceInstance("uid2",
|
||||
"test-svc-3", "2.2.2.2", 8080, metadata, false, "namespace2", null, null));
|
||||
assertThat(discoveryClient.getInstances("does-not-exist")).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.discovery;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -27,6 +26,7 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
|
||||
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@@ -127,11 +127,11 @@ class KubernetesReactiveDiscoveryClientTests {
|
||||
metadata.put("spring", "true");
|
||||
metadata.put("http", "8080");
|
||||
metadata.put("k8s", "true");
|
||||
|
||||
StepVerifier.create(discoveryClient.getInstances("test-svc-3"))
|
||||
.expectNext(new KubernetesServiceInstance("uid2", "test-svc-3", "2.2.2.2", 8080, false,
|
||||
URI.create("http://2.2.2.2:8080"), metadata, "http", "namespace1"))
|
||||
.expectNext(new DefaultKubernetesServiceInstance("uid2", "test-svc-3", "2.2.2.2", 8080, metadata, false,
|
||||
"namespace1", null, null))
|
||||
.verifyComplete();
|
||||
StepVerifier.create(discoveryClient.getInstances("test-svc-3")).expectNextCount(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user