Skip to content

Commit f08d0a5

Browse files
authored
Move endpoints ports to commons (#1395)
1 parent c3d859f commit f08d0a5

File tree

9 files changed

+494
-390
lines changed

9 files changed

+494
-390
lines changed

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/DiscoveryClientUtils.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,21 @@
1717
package org.springframework.cloud.kubernetes.commons.discovery;
1818

1919
import java.util.HashMap;
20+
import java.util.LinkedHashMap;
2021
import java.util.Map;
22+
import java.util.Optional;
23+
import java.util.stream.Collectors;
2124

2225
import org.apache.commons.logging.LogFactory;
2326

2427
import org.springframework.core.log.LogAccessor;
28+
import org.springframework.util.StringUtils;
2529

2630
import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.keysWithPrefix;
31+
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.HTTP;
32+
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.HTTPS;
2733
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.NAMESPACE_METADATA_KEY;
34+
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.PRIMARY_PORT_NAME_LABEL_KEY;
2835
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.SERVICE_TYPE;
2936

3037
/**
@@ -77,4 +84,95 @@ public static Map<String, String> serviceMetadata(String serviceId, Map<String,
7784
return serviceMetadata;
7885
}
7986

87+
public static ServicePortNameAndNumber endpointsPort(LinkedHashMap<String, Integer> endpointsPorts,
88+
String serviceId, KubernetesDiscoveryProperties properties, Map<String, String> serviceLabels) {
89+
90+
if (endpointsPorts.size() == 0) {
91+
LOG.debug(() -> "no ports found for service : " + serviceId + ", will return zero");
92+
return new ServicePortNameAndNumber(0, "http");
93+
}
94+
95+
if (endpointsPorts.size() == 1) {
96+
Map.Entry<String, Integer> single = endpointsPorts.entrySet().iterator().next();
97+
LOG.debug(() -> "endpoint ports has a single entry, using port : " + single.getValue());
98+
return new ServicePortNameAndNumber(single.getValue(), single.getKey());
99+
}
100+
101+
else {
102+
103+
Optional<ServicePortNameAndNumber> portData;
104+
String primaryPortName = primaryPortName(properties, serviceLabels, serviceId);
105+
106+
Map<String, Integer> existingPorts = endpointsPorts.entrySet().stream()
107+
.filter(entry -> StringUtils.hasText(entry.getKey()))
108+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
109+
110+
portData = fromMap(existingPorts, primaryPortName, "found primary-port-name (with value: '"
111+
+ primaryPortName + "') via properties or service labels to match port");
112+
if (portData.isPresent()) {
113+
return portData.get();
114+
}
115+
116+
portData = fromMap(existingPorts, HTTPS, "found primary-port-name via 'https' to match port");
117+
if (portData.isPresent()) {
118+
return portData.get();
119+
}
120+
121+
portData = fromMap(existingPorts, HTTP, "found primary-port-name via 'http' to match port");
122+
if (portData.isPresent()) {
123+
return portData.get();
124+
}
125+
126+
logWarnings();
127+
Map.Entry<String, Integer> first = endpointsPorts.entrySet().iterator().next();
128+
return new ServicePortNameAndNumber(first.getValue(), first.getKey());
129+
130+
}
131+
}
132+
133+
/**
134+
* take primary-port-name from service label "PRIMARY_PORT_NAME_LABEL_KEY" if it
135+
* exists, otherwise from KubernetesDiscoveryProperties if it exists, otherwise null.
136+
*/
137+
static String primaryPortName(KubernetesDiscoveryProperties properties, Map<String, String> serviceLabels,
138+
String serviceId) {
139+
String primaryPortNameFromProperties = properties.primaryPortName();
140+
141+
// the value from labels takes precedence over the one from properties
142+
String primaryPortName = Optional
143+
.ofNullable(Optional.ofNullable(serviceLabels).orElse(Map.of()).get(PRIMARY_PORT_NAME_LABEL_KEY))
144+
.orElse(primaryPortNameFromProperties);
145+
146+
if (primaryPortName == null) {
147+
LOG.debug(
148+
() -> "did not find a primary-port-name in neither properties nor service labels for service with ID : "
149+
+ serviceId);
150+
return null;
151+
}
152+
153+
LOG.debug(() -> "will use primaryPortName : " + primaryPortName + " for service with ID = " + serviceId);
154+
return primaryPortName;
155+
}
156+
157+
private static Optional<ServicePortNameAndNumber> fromMap(Map<String, Integer> existingPorts, String key,
158+
String message) {
159+
Integer fromPrimaryPortName = existingPorts.get(key);
160+
if (fromPrimaryPortName == null) {
161+
LOG.debug(() -> "not " + message);
162+
return Optional.empty();
163+
}
164+
else {
165+
LOG.debug(() -> message + " : " + fromPrimaryPortName);
166+
return Optional.of(new ServicePortNameAndNumber(fromPrimaryPortName, key));
167+
}
168+
}
169+
170+
private static void logWarnings() {
171+
LOG.warn(() -> """
172+
Make sure that either the primary-port-name label has been added to the service,
173+
or spring.cloud.kubernetes.discovery.primary-port-name has been configured.
174+
Alternatively name the primary port 'https' or 'http'
175+
An incorrect configuration may result in non-deterministic behaviour.""");
176+
}
177+
80178
}

spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8ServicePortData.java renamed to spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/ServicePortNameAndNumber.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2019-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,10 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.cloud.kubernetes.fabric8.discovery;
17+
package org.springframework.cloud.kubernetes.commons.discovery;
1818

1919
/**
2020
* @author wind57
2121
*/
22-
record Fabric8ServicePortData(int portNumber, String portName) {
22+
public record ServicePortNameAndNumber(int portNumber, String portName) {
2323
}

0 commit comments

Comments
 (0)