Skip to content

Commit

Permalink
Support discovery with Kubernetes Client (#2542)
Browse files Browse the repository at this point in the history
  • Loading branch information
hzpz committed Jun 22, 2023
1 parent d78155b commit 22c8279
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.kubernetes.client.discovery.KubernetesInformerDiscoveryClient;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
import org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
Expand Down Expand Up @@ -87,8 +88,9 @@ public static class KubernetesConverterConfiguration {

@Bean
@ConfigurationProperties(prefix = "spring.boot.admin.discovery.converter")
public KubernetesServiceInstanceConverter serviceInstanceConverter() {
return new KubernetesServiceInstanceConverter();
public KubernetesServiceInstanceConverter serviceInstanceConverter(
KubernetesDiscoveryProperties discoveryProperties) {
return new KubernetesServiceInstanceConverter(discoveryProperties);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class DefaultServiceInstanceConverter implements ServiceInstanceConverter
*/
private String healthEndpointPath = "health";

private static @Nullable String getMetadataValue(ServiceInstance instance, String[] keys) {
protected static @Nullable String getMetadataValue(ServiceInstance instance, String... keys) {
Map<String, String> metadata = instance.getMetadata();
for (String key : keys) {
String value = metadata.get(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,31 @@
package de.codecentric.boot.admin.server.cloud.discovery;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;

import static org.springframework.util.StringUtils.hasText;

public class KubernetesServiceInstanceConverter extends DefaultServiceInstanceConverter {

public static final String MANAGEMENT_PORT_NAME = "management";

private final String portsPrefix;

public KubernetesServiceInstanceConverter(KubernetesDiscoveryProperties discoveryProperties) {
if (discoveryProperties.metadata() != null && discoveryProperties.metadata().portsPrefix() != null) {
this.portsPrefix = discoveryProperties.metadata().portsPrefix();
}
else {
this.portsPrefix = "";
}
}

@Override
protected int getManagementPort(ServiceInstance instance) {
String managementPort = instance.getMetadata().get("port.management");
// the DiscoveryClient implementation using Kubernetes Client
// (KubernetesInformerDiscoveryClient) currently ignores
// the portsPrefix from KubernetesDiscoveryProperties
String managementPort = getMetadataValue(instance, portsPrefix + MANAGEMENT_PORT_NAME, MANAGEMENT_PORT_NAME);
if (hasText(managementPort)) {
return Integer.parseInt(managementPort);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.kubernetes.client.discovery.KubernetesInformerDiscoveryClient;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
import org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient;

import de.codecentric.boot.admin.server.cloud.discovery.DefaultServiceInstanceConverter;
Expand Down Expand Up @@ -65,15 +67,16 @@ public void eurekaServiceInstanceConverter() {

@Test
public void officialKubernetesServiceInstanceConverter() {
this.contextRunner
this.contextRunner.withUserConfiguration(KubernetesDiscoveryPropertiesConfiguration.class)
.withBean(KubernetesInformerDiscoveryClient.class, () -> mock(KubernetesInformerDiscoveryClient.class))
.run((context) -> assertThat(context).getBean(ServiceInstanceConverter.class)
.isInstanceOf(KubernetesServiceInstanceConverter.class));
}

@Test
public void fabric8KubernetesServiceInstanceConverter() {
this.contextRunner.withBean(KubernetesDiscoveryClient.class, () -> mock(KubernetesDiscoveryClient.class))
this.contextRunner.withUserConfiguration(KubernetesDiscoveryPropertiesConfiguration.class)
.withBean(KubernetesDiscoveryClient.class, () -> mock(KubernetesDiscoveryClient.class))
.run((context) -> assertThat(context).getBean(ServiceInstanceConverter.class)
.isInstanceOf(KubernetesServiceInstanceConverter.class));
}
Expand All @@ -95,4 +98,9 @@ public Registration convert(ServiceInstance instance) {

}

@EnableConfigurationProperties(KubernetesDiscoveryProperties.class)
public static class KubernetesDiscoveryPropertiesConfiguration {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.junit.jupiter.api.Test;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;

import de.codecentric.boot.admin.server.domain.values.Registration;

Expand All @@ -31,16 +32,34 @@
public class KubernetesServiceInstanceConverterTest {

@Test
public void convert_using_port_mgmt() {
ServiceInstance service = mock(ServiceInstance.class);
when(service.getUri()).thenReturn(URI.create("http://localhost:80"));
when(service.getServiceId()).thenReturn("test");
when(service.getMetadata()).thenReturn(Collections.singletonMap("port.management", "9080"));
void convert_using_port_mgmt() {
KubernetesDiscoveryProperties discoveryProperties = KubernetesDiscoveryProperties.DEFAULT;
ServiceInstance service = mockServiceInstanceWithManagementPort(
discoveryProperties.metadata().portsPrefix() + "management");

Registration registration = new KubernetesServiceInstanceConverter().convert(service);
Registration registration = new KubernetesServiceInstanceConverter(discoveryProperties).convert(service);

assertThat(registration.getManagementUrl()).isEqualTo("http://localhost:9080/actuator");
assertThat(registration.getHealthUrl()).isEqualTo("http://localhost:9080/actuator/health");
}

@Test
void fallback_for_port_mgmt() {
KubernetesDiscoveryProperties discoveryProperties = KubernetesDiscoveryProperties.DEFAULT;
ServiceInstance service = mockServiceInstanceWithManagementPort("management");

Registration registration = new KubernetesServiceInstanceConverter(discoveryProperties).convert(service);

assertThat(registration.getManagementUrl()).isEqualTo("http://localhost:9080/actuator");
assertThat(registration.getHealthUrl()).isEqualTo("http://localhost:9080/actuator/health");
}

private static ServiceInstance mockServiceInstanceWithManagementPort(String managementPortName) {
ServiceInstance service = mock(ServiceInstance.class);
when(service.getUri()).thenReturn(URI.create("http://localhost:80"));
when(service.getServiceId()).thenReturn("test");
when(service.getMetadata()).thenReturn(Collections.singletonMap(managementPortName, "9080"));
return service;
}

}

0 comments on commit 22c8279

Please sign in to comment.