diff --git a/README.adoc b/README.adoc index a8d7fe06..67791e11 100644 --- a/README.adoc +++ b/README.adoc @@ -180,6 +180,20 @@ spring.cloud.kubernetes.discovery.include-not-ready-addresses=true NOTE: This might be useful when discovering services for monitoring purposes, and would enable inspecting the `/health` endpoint of not-ready service instances. ==== +If your service exposes multiple ports, you will need to specify which port the `DiscoveryClient` should use. +The `DiscoveryClient` will choose the port using the following logic. + +1. If the service has a label `primary-port-name` it will use the port with the name specified in the label's value. +2. If no label is present, then the port name specified in `spring.cloud.kubernetes.discovery.primary-port-name` will be used. +3. If neither of the above are specified it will use the port named `https`. +4. If none of the above conditions are met it will use the port named `http`. +5. As a last resort it wil pick the first port in the list of ports. + +WARNING: The last option may result in non-deterministic behaviour. +Please make sure to configure your service and/or application accordingly. + +By default all of the ports and their names will be added to the metadata of the `ServiceInstance`. + If, for any reason, you need to disable the `DiscoveryClient`, you can set the following property in `application.properties`: ==== diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClient.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClient.java index 7136a32f..23c4afbc 100644 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClient.java +++ b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClient.java @@ -53,8 +53,11 @@ import org.springframework.util.StringUtils; public class KubernetesInformerDiscoveryClient implements DiscoveryClient, InitializingBean { private static final Log log = LogFactory.getLog(KubernetesInformerDiscoveryClient.class); + private static final String PRIMARY_PORT_NAME_LABEL_KEY = "primary-port-name"; + private static final String HTTPS_PORT_NAME = "https"; + private static final String HTTP_PORT_NAME = "http"; private final SharedInformerFactory sharedInformerFactory; @@ -136,33 +139,32 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi Optional discoveredPrimaryPortName = Optional.empty(); if (service.getMetadata() != null && service.getMetadata().getLabels() != null) { discoveredPrimaryPortName = Optional - .ofNullable(service.getMetadata().getLabels().get(PRIMARY_PORT_NAME_LABEL_KEY)); + .ofNullable(service.getMetadata().getLabels().get(PRIMARY_PORT_NAME_LABEL_KEY)); } final String primaryPortName = discoveredPrimaryPortName.orElse(this.properties.getPrimaryPortName()); - return ep.getSubsets().stream() - .filter(subset -> subset.getPorts() != null && subset.getPorts().size() > 0) // safeguard - .flatMap(subset -> { - Map metadata = new HashMap<>(svcMetadata); - List endpointPorts = subset.getPorts(); - if (this.properties.getMetadata() != null && this.properties.getMetadata().isAddPorts()) { - endpointPorts.forEach(p -> metadata.put(p.getName(), Integer.toString(p.getPort()))); - } - List addresses = subset.getAddresses(); - if (addresses == null) { - addresses = new ArrayList<>(); - } - if (this.properties.isIncludeNotReadyAddresses() - && !CollectionUtils.isEmpty(subset.getNotReadyAddresses())) { - addresses.addAll(subset.getNotReadyAddresses()); - } + return ep.getSubsets().stream().filter(subset -> subset.getPorts() != null && subset.getPorts().size() > 0) // safeguard + .flatMap(subset -> { + Map metadata = new HashMap<>(svcMetadata); + List endpointPorts = subset.getPorts(); + if (this.properties.getMetadata() != null && this.properties.getMetadata().isAddPorts()) { + endpointPorts.forEach(p -> metadata.put(p.getName(), Integer.toString(p.getPort()))); + } + List addresses = subset.getAddresses(); + if (addresses == null) { + addresses = new ArrayList<>(); + } + if (this.properties.isIncludeNotReadyAddresses() + && !CollectionUtils.isEmpty(subset.getNotReadyAddresses())) { + addresses.addAll(subset.getNotReadyAddresses()); + } - final int port = findEndpointPort(endpointPorts, primaryPortName, serviceId); - return addresses.stream() - .map(addr -> new KubernetesServiceInstance( - addr.getTargetRef() != null ? addr.getTargetRef().getUid() : "", serviceId, addr.getIp(), - port, metadata, false)); - }).collect(Collectors.toList()); + final int port = findEndpointPort(endpointPorts, primaryPortName, serviceId); + return addresses.stream() + .map(addr -> new KubernetesServiceInstance( + addr.getTargetRef() != null ? addr.getTargetRef().getUid() : "", serviceId, + addr.getIp(), port, metadata, false)); + }).collect(Collectors.toList()); } private int findEndpointPort(List endpointPorts, String primaryPortName, String serviceId) { @@ -170,22 +172,27 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi return endpointPorts.get(0).getPort(); } else { - Map ports = endpointPorts.stream() - .filter(p -> StringUtils.hasText(p.getName())) - .collect(Collectors.toMap(V1EndpointPort::getName, V1EndpointPort::getPort)); - // This oneliner is looking for a port with a name equal to the primary port name specified in the service label - // or in spring.cloud.kubernetes.discovery.primary-port-name, equal to https, or equal to http. - // In case no port has been found return -1 to log a warning and fall back to the first port in the list. - int discoveredPort = ports.getOrDefault(primaryPortName, ports.getOrDefault(HTTPS_PORT_NAME, ports.getOrDefault(HTTP_PORT_NAME, -1))); + Map ports = endpointPorts.stream().filter(p -> StringUtils.hasText(p.getName())) + .collect(Collectors.toMap(V1EndpointPort::getName, V1EndpointPort::getPort)); + // This oneliner is looking for a port with a name equal to the primary port + // name specified in the service label + // or in spring.cloud.kubernetes.discovery.primary-port-name, equal to https, + // or equal to http. + // In case no port has been found return -1 to log a warning and fall back to + // the first port in the list. + int discoveredPort = ports.getOrDefault(primaryPortName, + ports.getOrDefault(HTTPS_PORT_NAME, ports.getOrDefault(HTTP_PORT_NAME, -1))); if (discoveredPort == -1) { if (StringUtils.hasText(primaryPortName)) { - log.warn("Could not find a port named '" + primaryPortName + "', 'https', or 'http' for service '" + serviceId + "'."); + log.warn("Could not find a port named '" + primaryPortName + "', 'https', or 'http' for service '" + + serviceId + "'."); } else { log.warn("Could not find a port named 'https' or 'http' for service '" + serviceId + "'."); } - log.warn("Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured."); + log.warn( + "Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured."); log.warn("Alternatively name the primary port 'https' or 'http'"); log.warn("An incorrect configuration may result in non-deterministic behaviour."); discoveredPort = endpointPorts.get(0).getPort(); @@ -198,9 +205,8 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi public List getServices() { List services = this.properties.isAllNamespaces() ? this.serviceLister.list() : this.serviceLister.namespace(this.namespace).list(); - return services.stream() - .filter(s -> s.getMetadata() != null) //safeguard - .map(s -> s.getMetadata().getName()).collect(Collectors.toList()); + return services.stream().filter(s -> s.getMetadata() != null) // safeguard + .map(s -> s.getMetadata().getName()).collect(Collectors.toList()); } @Override diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClientTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClientTests.java index 01285502..c6adf384 100644 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClientTests.java +++ b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesInformerDiscoveryClientTests.java @@ -71,26 +71,25 @@ public class KubernetesInformerDiscoveryClientTests { private static final V1Endpoints testEndpointWithoutPorts = new V1Endpoints() .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1")) - .addSubsetsItem(new V1EndpointSubset() - .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); + .addSubsetsItem(new V1EndpointSubset().addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); private static final V1Endpoints testEndpointWithMultiplePorts = new V1Endpoints() .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1")) .addSubsetsItem(new V1EndpointSubset().addPortsItem(new V1EndpointPort().name("http").port(80)) - .addPortsItem(new V1EndpointPort().name("https").port(443)) - .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); + .addPortsItem(new V1EndpointPort().name("https").port(443)) + .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); private static final V1Endpoints testEndpointWithMultiplePortsWithoutHttps = new V1Endpoints() .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1")) .addSubsetsItem(new V1EndpointSubset().addPortsItem(new V1EndpointPort().name("http").port(80)) - .addPortsItem(new V1EndpointPort().name("tcp").port(443)) - .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); + .addPortsItem(new V1EndpointPort().name("tcp").port(443)) + .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); private static final V1Endpoints testEndpointWithMultiplePortsWithoutSupportedPortNames = new V1Endpoints() .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1")) .addSubsetsItem(new V1EndpointSubset().addPortsItem(new V1EndpointPort().name("tcp1").port(80)) - .addPortsItem(new V1EndpointPort().name("tcp2").port(443)) - .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); + .addPortsItem(new V1EndpointPort().name("tcp2").port(443)) + .addAddressesItem(new V1EndpointAddress().ip("1.1.1.1"))); @Test public void testDiscoveryGetServicesAllNamespaceShouldWork() { @@ -182,8 +181,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "2.2.2.2", 8080, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "2.2.2.2", 8080, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); verify(kubernetesDiscoveryProperties, times(1)).isIncludeNotReadyAddresses(); @@ -219,9 +217,8 @@ public class KubernetesInformerDiscoveryClientTests { @Test public void instanceWithMultiplePortsAndPrimaryPortNameConfiguredWithLabelShouldWork() { - Lister serviceLister = setupServiceLister(testService1 - .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1") - .putLabelsItem("primary-port-name", "https"))); + Lister serviceLister = setupServiceLister(testService1.metadata(new V1ObjectMeta().name("test-svc-1") + .namespace("namespace1").putLabelsItem("primary-port-name", "https"))); Lister endpointsLister = setupEndpointsLister(testEndpointWithMultiplePorts); when(kubernetesDiscoveryProperties.isAllNamespaces()).thenReturn(false); @@ -230,8 +227,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); verify(kubernetesDiscoveryProperties, times(1)).isIncludeNotReadyAddresses(); @@ -239,19 +235,18 @@ public class KubernetesInformerDiscoveryClientTests { @Test public void instanceWithMultiplePortsAndMisconfiguredPrimaryPortNameInLabelShouldReturnFirstPortAndLogWarning() { - Lister serviceLister = setupServiceLister(testService1 - .metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1") - .putLabelsItem("primary-port-name", "oops"))); - Lister endpointsLister = setupEndpointsLister(testEndpointWithMultiplePortsWithoutSupportedPortNames); + Lister serviceLister = setupServiceLister(testService1.metadata(new V1ObjectMeta().name("test-svc-1") + .namespace("namespace1").putLabelsItem("primary-port-name", "oops"))); + Lister endpointsLister = setupEndpointsLister( + testEndpointWithMultiplePortsWithoutSupportedPortNames); when(kubernetesDiscoveryProperties.isAllNamespaces()).thenReturn(false); KubernetesInformerDiscoveryClient discoveryClient = new KubernetesInformerDiscoveryClient("namespace1", - sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); + sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); } @@ -268,8 +263,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).isIncludeNotReadyAddresses(); @@ -278,17 +272,17 @@ public class KubernetesInformerDiscoveryClientTests { @Test public void instanceWithMultiplePortsAndMisconfiguredGenericPrimaryPortNameShouldReturnFirstPortAndLogWarning() { Lister serviceLister = setupServiceLister(testService1); - Lister endpointsLister = setupEndpointsLister(testEndpointWithMultiplePortsWithoutSupportedPortNames); + Lister endpointsLister = setupEndpointsLister( + testEndpointWithMultiplePortsWithoutSupportedPortNames); when(kubernetesDiscoveryProperties.isAllNamespaces()).thenReturn(false); when(kubernetesDiscoveryProperties.getPrimaryPortName()).thenReturn("oops"); KubernetesInformerDiscoveryClient discoveryClient = new KubernetesInformerDiscoveryClient("namespace1", - sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); + sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); } @@ -304,8 +298,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 443, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); } @@ -321,8 +314,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); } @@ -330,7 +322,8 @@ public class KubernetesInformerDiscoveryClientTests { @Test public void instanceWithMultiplePortsAndWithoutAnyConfigurationShouldPickTheFirstPort() { Lister serviceLister = setupServiceLister(testService1); - Lister endpointsLister = setupEndpointsLister(testEndpointWithMultiplePortsWithoutSupportedPortNames); + Lister endpointsLister = setupEndpointsLister( + testEndpointWithMultiplePortsWithoutSupportedPortNames); when(kubernetesDiscoveryProperties.isAllNamespaces()).thenReturn(false); @@ -338,8 +331,7 @@ public class KubernetesInformerDiscoveryClientTests { sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties); assertThat(discoveryClient.getInstances("test-svc-1")) - .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, - new HashMap<>(), false)); + .containsOnly(new KubernetesServiceInstance("", "test-svc-1", "1.1.1.1", 80, new HashMap<>(), false)); verify(kubernetesDiscoveryProperties, times(1)).isAllNamespaces(); verify(kubernetesDiscoveryProperties, times(1)).getPrimaryPortName(); } diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java index 52a72725..bc6eb8b0 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java @@ -55,8 +55,11 @@ import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesS public class KubernetesDiscoveryClient implements DiscoveryClient { private static final Log log = LogFactory.getLog(KubernetesDiscoveryClient.class); + private static final String PRIMARY_PORT_NAME_LABEL_KEY = "primary-port-name"; + private static final String HTTPS_PORT_NAME = "https"; + private static final String HTTP_PORT_NAME = "http"; private final KubernetesDiscoveryProperties properties; @@ -107,8 +110,8 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { public List getInstances(String serviceId) { Assert.notNull(serviceId, "[Assertion failed] - the object argument must not be null"); - List subsetsNS = this.getEndPointsList(serviceId).stream() - .map(this::getSubsetsFromEndpoints).collect(Collectors.toList()); + List subsetsNS = this.getEndPointsList(serviceId).stream().map(this::getSubsetsFromEndpoints) + .collect(Collectors.toList()); List instances = new ArrayList<>(); if (!subsetsNS.isEmpty()) { @@ -179,10 +182,10 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { instanceId = endpointAddress.getTargetRef().getUid(); } instances.add(new KubernetesServiceInstance(instanceId, serviceId, endpointAddress.getIp(), - endpointPort, endpointMetadata, - this.servicePortSecureResolver.resolve(new ServicePortSecureResolver.Input( - endpointPort, service.getMetadata().getName(), - service.getMetadata().getLabels(), service.getMetadata().getAnnotations())))); + endpointPort, endpointMetadata, + this.servicePortSecureResolver.resolve(new ServicePortSecureResolver.Input(endpointPort, + service.getMetadata().getName(), service.getMetadata().getLabels(), + service.getMetadata().getAnnotations())))); } } } @@ -219,22 +222,27 @@ public class KubernetesDiscoveryClient implements DiscoveryClient { return endpointPorts.get(0).getPort(); } else { - Map ports = endpointPorts.stream() - .filter(p -> StringUtils.hasText(p.getName())) - .collect(Collectors.toMap(EndpointPort::getName, EndpointPort::getPort)); - // This oneliner is looking for a port with a name equal to the primary port name specified in the service label - // or in spring.cloud.kubernetes.discovery.primary-port-name, equal to https, or equal to http. - // In case no port has been found return -1 to log a warning and fall back to the first port in the list. - int discoveredPort = ports.getOrDefault(primaryPortName, ports.getOrDefault(HTTPS_PORT_NAME, ports.getOrDefault(HTTP_PORT_NAME, -1))); + Map ports = endpointPorts.stream().filter(p -> StringUtils.hasText(p.getName())) + .collect(Collectors.toMap(EndpointPort::getName, EndpointPort::getPort)); + // This oneliner is looking for a port with a name equal to the primary port + // name specified in the service label + // or in spring.cloud.kubernetes.discovery.primary-port-name, equal to https, + // or equal to http. + // In case no port has been found return -1 to log a warning and fall back to + // the first port in the list. + int discoveredPort = ports.getOrDefault(primaryPortName, + ports.getOrDefault(HTTPS_PORT_NAME, ports.getOrDefault(HTTP_PORT_NAME, -1))); if (discoveredPort == -1) { if (StringUtils.hasText(primaryPortName)) { - log.warn("Could not find a port named '" + primaryPortName + "', 'https', or 'http' for service '" + serviceId + "'."); + log.warn("Could not find a port named '" + primaryPortName + "', 'https', or 'http' for service '" + + serviceId + "'."); } else { log.warn("Could not find a port named 'https' or 'http' for service '" + serviceId + "'."); } - log.warn("Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured."); + log.warn( + "Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured."); log.warn("Alternatively name the primary port 'https' or 'http'"); log.warn("An incorrect configuration may result in non-deterministic behaviour."); discoveredPort = endpointPorts.get(0).getPort(); diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientTest.java b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientTest.java index e6d85735..04bc539f 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientTest.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientTest.java @@ -360,7 +360,7 @@ public class KubernetesDiscoveryClientTest { @Test public void instanceWithoutPortsShouldBeSkipped() { Endpoints endPoint = new EndpointsBuilder().withNewMetadata().withName("endpoint1").withNamespace("test") - .withLabels(Collections.emptyMap()).endMetadata().build(); + .withLabels(Collections.emptyMap()).endMetadata().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint); @@ -368,15 +368,13 @@ public class KubernetesDiscoveryClientTest { EndpointsList endpoints = new EndpointsList(); endpoints.setItems(endpointsList); - mockServer.expect().get() - .withPath( - "/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint1") - .andReturn(200, endpoints).once(); + mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint1") + .andReturn(200, endpoints).once(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final KubernetesDiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint1"); @@ -389,9 +387,9 @@ public class KubernetesDiscoveryClientTest { labels.put("primary-port-name", "https"); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint2").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("80").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") - .addNewPort("http", "http", 80, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("80").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") + .addNewPort("http", "http", 80, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -400,23 +398,23 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint2") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint2").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint2").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint2"); assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("80")).hasSize(1).filteredOn(s -> 443 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("80")).hasSize(1).filteredOn(s -> 443 == s.getPort()) + .hasSize(1); } @Test @@ -425,11 +423,10 @@ public class KubernetesDiscoveryClientTest { labels.put("primary-port-name", "oops"); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint3").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("90").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") - .addNewPort("http", "https2", 8443, "TCP") - .addNewPort("http", "http1", 80, "TCP") - .addNewPort("http", "http2", 8080, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("90").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") + .addNewPort("http", "https2", 8443, "TCP").addNewPort("http", "http1", 80, "TCP") + .addNewPort("http", "http2", 8080, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -438,23 +435,23 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint3") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint3").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint3").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint3"); assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("90")).hasSize(1).filteredOn(s -> 443 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("90")).hasSize(1).filteredOn(s -> 443 == s.getPort()) + .hasSize(1); } @Test @@ -462,11 +459,10 @@ public class KubernetesDiscoveryClientTest { Map labels = new HashMap<>(); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint4").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("100").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") - .addNewPort("http", "https2", 8443, "TCP") - .addNewPort("http", "http1", 80, "TCP") - .addNewPort("http", "http2", 8080, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("100").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") + .addNewPort("http", "https2", 8443, "TCP").addNewPort("http", "http1", 80, "TCP") + .addNewPort("http", "http2", 8080, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -475,25 +471,25 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint4") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint4").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint4").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); properties.setPrimaryPortName("oops"); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint4"); assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("100")).hasSize(1).filteredOn(s -> 443 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("100")).hasSize(1).filteredOn(s -> 443 == s.getPort()) + .hasSize(1); } @Test @@ -501,9 +497,9 @@ public class KubernetesDiscoveryClientTest { Map labels = new HashMap<>(); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("110").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") - .addNewPort("http", "http", 80, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("110").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") + .addNewPort("http", "http", 80, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -512,23 +508,23 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint5") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint5").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint5"); assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("110")).hasSize(1).filteredOn(s -> 443 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("110")).hasSize(1).filteredOn(s -> 443 == s.getPort()) + .hasSize(1); } @Test @@ -536,10 +532,9 @@ public class KubernetesDiscoveryClientTest { Map labels = new HashMap<>(); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("120").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") - .addNewPort("http", "https2", 8443, "TCP") - .addNewPort("http", "http", 80, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("120").endTargetRef().endAddress().addNewPort("http", "https1", 443, "TCP") + .addNewPort("http", "https2", 8443, "TCP").addNewPort("http", "http", 80, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -548,23 +543,23 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint5") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint5").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint5"); assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("120")).hasSize(1).filteredOn(s -> 80 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("120")).hasSize(1).filteredOn(s -> 80 == s.getPort()) + .hasSize(1); } @Test @@ -572,9 +567,9 @@ public class KubernetesDiscoveryClientTest { Map labels = new HashMap<>(); Endpoints endPoint1 = new EndpointsBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() - .withUid("130").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") - .addNewPort("http", "http", 80, "TCP").endSubset().build(); + .withLabels(labels).endMetadata().addNewSubset().addNewAddress().withIp("ip1").withNewTargetRef() + .withUid("130").endTargetRef().endAddress().addNewPort("http", "https", 443, "TCP") + .addNewPort("http", "http", 80, "TCP").endSubset().build(); List endpointsList = new ArrayList<>(); endpointsList.add(endPoint1); @@ -583,24 +578,24 @@ public class KubernetesDiscoveryClientTest { endpoints.setItems(endpointsList); mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints?fieldSelector=metadata.name%3Dendpoint5") - .andReturn(200, endpoints).once(); + .andReturn(200, endpoints).once(); Service service = new ServiceBuilder().withNewMetadata().withName("endpoint5").withNamespace("test") - .withLabels(labels).withAnnotations(labels).endMetadata().build(); + .withLabels(labels).withAnnotations(labels).endMetadata().build(); mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint5").andReturn(200, service) - .always(); + .always(); final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(); final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties, - KubernetesClient::services, new ServicePortSecureResolver(properties)); + KubernetesClient::services, new ServicePortSecureResolver(properties)); final List instances = discoveryClient.getInstances("endpoint5"); // We're returning the first discovered port to not change previous behaviour assertThat(instances).hasSize(1).filteredOn(s -> s.getHost().equals("ip1") && s.isSecure()).hasSize(1) - .filteredOn(s -> s.getInstanceId().equals("130")).hasSize(1).filteredOn(s -> 443 == s.getPort()) - .hasSize(1); + .filteredOn(s -> s.getInstanceId().equals("130")).hasSize(1).filteredOn(s -> 443 == s.getPort()) + .hasSize(1); } }