diff --git a/spring-cloud-kubernetes-client-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapper.java b/spring-cloud-kubernetes-client-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapper.java index 6c30cde8..249739c8 100644 --- a/spring-cloud-kubernetes-client-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-client-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapper.java @@ -40,6 +40,7 @@ import org.springframework.core.log.LogAccessor; import org.springframework.util.StringUtils; import static java.util.Optional.ofNullable; +import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.NON_DETERMINISTIC_PORT_MESSAGE; import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.PORT_NAME_PROPERTY; import static org.springframework.cloud.kubernetes.commons.discovery.ServicePortSecureResolver.Input; @@ -102,9 +103,9 @@ public class KubernetesClientServiceInstanceMapper implements KubernetesServiceI } } else { - LOG.warn(() -> PORT_NAME_PROPERTY + " is not set, as such will not consider service with name : " - + metadata.getName()); - return null; + LOG.warn(() -> PORT_NAME_PROPERTY + " is not set"); + LOG.warn(() -> NON_DETERMINISTIC_PORT_MESSAGE); + port = ports.get(0); } } @@ -135,7 +136,7 @@ public class KubernetesClientServiceInstanceMapper implements KubernetesServiceI private void logWarning(String portNameFromProperties) { LOG.warn(() -> "Did not find a port name that is equal to the value " + portNameFromProperties); - LOG.warn(() -> "Will return 'first' port found, which is non-deterministic"); + LOG.warn(() -> NON_DETERMINISTIC_PORT_MESSAGE); } } diff --git a/spring-cloud-kubernetes-client-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapperTests.java b/spring-cloud-kubernetes-client-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapperTests.java index 885ee7e5..950f3c27 100644 --- a/spring-cloud-kubernetes-client-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapperTests.java +++ b/spring-cloud-kubernetes-client-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/client/loadbalancer/KubernetesClientServiceInstanceMapperTests.java @@ -192,6 +192,25 @@ class KubernetesClientServiceInstanceMapperTests { Assertions.assertTrue(serviceInstance.getPort() == 80 || serviceInstance.getPort() == 443); } + @Test + void multiPortsEmptyPortNameProperty(CapturedOutput output) { + KubernetesLoadBalancerProperties loadBalancerProperties = new KubernetesLoadBalancerProperties(); + loadBalancerProperties.setPortName(""); + KubernetesClientServiceInstanceMapper mapper = new KubernetesClientServiceInstanceMapper(loadBalancerProperties, + KubernetesDiscoveryProperties.DEFAULT); + + Map annotations = Map.of("org.springframework.cloud", "true"); + Map labels = Map.of("beta", "true"); + List servicePorts = List.of(new V1ServicePortBuilder().withName("http-api").withPort(80).build(), + new V1ServicePortBuilder().withName("https").withPort(443).build()); + V1Service service = createService("database", "default", annotations, labels, servicePorts); + KubernetesServiceInstance serviceInstance = mapper.map(service); + Assertions.assertNotNull(serviceInstance); + Assertions.assertTrue(output.getOut().contains("'spring.cloud.kubernetes.loadbalancer.portName' is not set")); + Assertions.assertTrue(output.getOut().contains("Will return 'first' port found, which is non-deterministic")); + Assertions.assertTrue(serviceInstance.getPort() == 80 || serviceInstance.getPort() == 443); + } + private V1Service createService(String name, String namespace, Map annotations, Map labels, List servicePorts) { return new V1ServiceBuilder() diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryConstants.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryConstants.java index 5177b4c2..8ebcd23f 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryConstants.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryConstants.java @@ -103,4 +103,9 @@ public final class KubernetesDiscoveryConstants { */ public static final String PORT_NAME_PROPERTY = "'spring.cloud.kubernetes.loadbalancer.portName'"; + /** + * message for non-deterministic port. + */ + public static final String NON_DETERMINISTIC_PORT_MESSAGE = "Will return 'first' port found, which is non-deterministic"; + } diff --git a/spring-cloud-kubernetes-fabric8-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapper.java b/spring-cloud-kubernetes-fabric8-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapper.java index 6f44a85c..7cccfafc 100644 --- a/spring-cloud-kubernetes-fabric8-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapper.java +++ b/spring-cloud-kubernetes-fabric8-loadbalancer/src/main/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapper.java @@ -39,6 +39,7 @@ import org.springframework.cloud.kubernetes.fabric8.Fabric8Utils; import org.springframework.core.log.LogAccessor; import org.springframework.util.StringUtils; +import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.NON_DETERMINISTIC_PORT_MESSAGE; import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.PORT_NAME_PROPERTY; import static org.springframework.cloud.kubernetes.commons.discovery.ServicePortSecureResolver.Input; @@ -101,9 +102,9 @@ public class Fabric8ServiceInstanceMapper implements KubernetesServiceInstanceMa } } else { - LOG.warn(() -> PORT_NAME_PROPERTY + " is not set, as such will not consider service with name : " - + metadata.getName()); - return null; + LOG.warn(() -> PORT_NAME_PROPERTY + " is not set"); + LOG.warn(() -> NON_DETERMINISTIC_PORT_MESSAGE); + port = ports.get(0); } } @@ -130,7 +131,7 @@ public class Fabric8ServiceInstanceMapper implements KubernetesServiceInstanceMa private void logWarning(String portNameFromProperties) { LOG.warn(() -> "Did not find a port name that is equal to the value " + portNameFromProperties); - LOG.warn(() -> "Will return 'first' port found, which is non-deterministic"); + LOG.warn(() -> NON_DETERMINISTIC_PORT_MESSAGE); } } diff --git a/spring-cloud-kubernetes-fabric8-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapperTests.java b/spring-cloud-kubernetes-fabric8-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapperTests.java index 04ea207d..95c57255 100644 --- a/spring-cloud-kubernetes-fabric8-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapperTests.java +++ b/spring-cloud-kubernetes-fabric8-loadbalancer/src/test/java/org/springframework/cloud/kubernetes/fabric8/loadbalancer/Fabric8ServiceInstanceMapperTests.java @@ -217,7 +217,7 @@ class Fabric8ServiceInstanceMapperTests { /** *
 	 *     service has multiple ServicePorts, and 'spring.cloud.kubernetes.loadbalancer.portName' is empty.
-	 *     in this case, service will be skipped.
+	 *     in this case, a single, 'first', port will be returned.
 	 * 
*/ @Test @@ -234,16 +234,15 @@ class Fabric8ServiceInstanceMapperTests { KubernetesServiceInstance result = new Fabric8ServiceInstanceMapper(loadBalancerProperties, discoveryProperties) .map(service); - Assertions.assertNull(result); - Assertions.assertTrue(output.getOut().contains( - "'spring.cloud.kubernetes.loadbalancer.portName' is not set, as such will not consider service with name : test")); + Assertions.assertNotNull(result); + Assertions.assertTrue(output.getOut().contains("'spring.cloud.kubernetes.loadbalancer.portName' is not set")); + Assertions.assertTrue(output.getOut().contains("Will return 'first' port found, which is non-deterministic")); } /** *
-	 *     service has multiple ServicePorts, and 'spring.cloud.kubernetes.loadbalancer.portName' is empty.
-	 *     in this case, service will be skipped.
+	 *     service has multiple ServicePorts, and 'spring.cloud.kubernetes.loadbalancer.portName' is not empty.
 	 * 
*/ @Test @@ -267,8 +266,8 @@ class Fabric8ServiceInstanceMapperTests { /** *
-	 *     service has multiple ServicePorts, and 'spring.cloud.kubernetes.loadbalancer.portName' is empty.
-	 *     in this case, service will be skipped.
+	 *     service has multiple ServicePorts, and 'spring.cloud.kubernetes.loadbalancer.portName' is not empty.
+	 *     property name also does not match 'potName'
 	 * 
*/ @Test