Refactor Metadata to a record (#1092)

This commit is contained in:
erabii
2022-09-29 17:15:02 +03:00
committed by GitHub
parent 60dbf7c305
commit a304c7787e
9 changed files with 129 additions and 162 deletions

View File

@@ -107,19 +107,19 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi
Map<String, String> svcMetadata = new HashMap<>();
if (this.properties.getMetadata() != null) {
if (this.properties.getMetadata().isAddLabels()) {
if (this.properties.getMetadata().addLabels()) {
if (service.getMetadata() != null && service.getMetadata().getLabels() != null) {
String labelPrefix = this.properties.getMetadata().getLabelsPrefix() != null
? this.properties.getMetadata().getLabelsPrefix() : "";
String labelPrefix = this.properties.getMetadata().labelsPrefix() != null
? this.properties.getMetadata().labelsPrefix() : "";
service.getMetadata().getLabels().entrySet().stream()
.filter(e -> e.getKey().startsWith(labelPrefix))
.forEach(e -> svcMetadata.put(e.getKey(), e.getValue()));
}
}
if (this.properties.getMetadata().isAddAnnotations()) {
if (this.properties.getMetadata().addAnnotations()) {
if (service.getMetadata() != null && service.getMetadata().getAnnotations() != null) {
String annotationPrefix = this.properties.getMetadata().getAnnotationsPrefix() != null
? this.properties.getMetadata().getAnnotationsPrefix() : "";
String annotationPrefix = this.properties.getMetadata().annotationsPrefix() != null
? this.properties.getMetadata().annotationsPrefix() : "";
service.getMetadata().getAnnotations().entrySet().stream()
.filter(e -> e.getKey().startsWith(annotationPrefix))
.forEach(e -> svcMetadata.put(e.getKey(), e.getValue()));
@@ -145,7 +145,7 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi
.flatMap(subset -> {
Map<String, String> metadata = new HashMap<>(svcMetadata);
List<V1EndpointPort> endpointPorts = subset.getPorts();
if (this.properties.getMetadata() != null && this.properties.getMetadata().isAddPorts()) {
if (this.properties.getMetadata() != null && this.properties.getMetadata().addPorts()) {
endpointPorts.forEach(p -> metadata.put(p.getName(), Integer.toString(p.getPort())));
}
List<V1EndpointAddress> addresses = subset.getAddresses();

View File

@@ -77,14 +77,14 @@ public class KubernetesClientServiceInstanceMapper implements KubernetesServiceI
private Map<String, String> getServiceMetadata(V1Service service) {
final Map<String, String> serviceMetadata = new HashMap<>();
KubernetesDiscoveryProperties.Metadata metadataProps = this.discoveryProperties.getMetadata();
if (metadataProps.isAddLabels()) {
if (metadataProps.addLabels()) {
Map<String, String> labelMetadata = KubernetesServiceInstanceMapper
.getMapWithPrefixedKeys(service.getMetadata().getLabels(), metadataProps.getLabelsPrefix());
.getMapWithPrefixedKeys(service.getMetadata().getLabels(), metadataProps.labelsPrefix());
serviceMetadata.putAll(labelMetadata);
}
if (metadataProps.isAddAnnotations()) {
Map<String, String> annotationMetadata = KubernetesServiceInstanceMapper.getMapWithPrefixedKeys(
service.getMetadata().getAnnotations(), metadataProps.getAnnotationsPrefix());
if (metadataProps.addAnnotations()) {
Map<String, String> annotationMetadata = KubernetesServiceInstanceMapper
.getMapWithPrefixedKeys(service.getMetadata().getAnnotations(), metadataProps.annotationsPrefix());
serviceMetadata.putAll(annotationMetadata);
}

View File

@@ -24,6 +24,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.core.style.ToStringCreator;
import static org.springframework.cloud.client.discovery.DiscoveryClient.DEFAULT_ORDER;
@@ -175,100 +177,25 @@ public class KubernetesDiscoveryProperties {
}
/**
* Metadata properties.
* @param addLabels include labels as metadata
* @param labelsPrefix prefix for the labels
* @param addAnnotations include annotations as metadata
* @param annotationsPrefix prefix for the annotations
* @param addPorts include ports as metadata
* @param portsPrefix prefix for the ports, by default it is "port."
*/
public static class Metadata {
public record Metadata(@DefaultValue("true") boolean addLabels, String labelsPrefix,
@DefaultValue("true") boolean addAnnotations, String annotationsPrefix,
@DefaultValue("true") boolean addPorts, @DefaultValue("port.") String portsPrefix) {
/**
* When set, the Kubernetes labels of the services will be included as metadata of
* the returned ServiceInstance.
*/
private boolean addLabels = true;
@ConstructorBinding
public Metadata {
/**
* When addLabels is set, then this will be used as a prefix to the key names in
* the metadata map.
*/
private String labelsPrefix;
/**
* When set, the Kubernetes annotations of the services will be included as
* metadata of the returned ServiceInstance.
*/
private boolean addAnnotations = true;
/**
* When addAnnotations is set, then this will be used as a prefix to the key names
* in the metadata map.
*/
private String annotationsPrefix;
/**
* When set, any named Kubernetes service ports will be included as metadata of
* the returned ServiceInstance.
*/
private boolean addPorts = true;
/**
* When addPorts is set, then this will be used as a prefix to the key names in
* the metadata map.
*/
private String portsPrefix = "port.";
public boolean isAddLabels() {
return this.addLabels;
}
public void setAddLabels(boolean addLabels) {
this.addLabels = addLabels;
}
public String getLabelsPrefix() {
return this.labelsPrefix;
}
public void setLabelsPrefix(String labelsPrefix) {
this.labelsPrefix = labelsPrefix;
}
public boolean isAddAnnotations() {
return this.addAnnotations;
}
public void setAddAnnotations(boolean addAnnotations) {
this.addAnnotations = addAnnotations;
}
public String getAnnotationsPrefix() {
return this.annotationsPrefix;
}
public void setAnnotationsPrefix(String annotationsPrefix) {
this.annotationsPrefix = annotationsPrefix;
}
public boolean isAddPorts() {
return this.addPorts;
}
public void setAddPorts(boolean addPorts) {
this.addPorts = addPorts;
}
public String getPortsPrefix() {
return this.portsPrefix;
}
public void setPortsPrefix(String portsPrefix) {
this.portsPrefix = portsPrefix;
}
@Override
public String toString() {
return new ToStringCreator(this).append("addLabels", this.addLabels)
.append("labelsPrefix", this.labelsPrefix).append("addAnnotations", this.addAnnotations)
.append("annotationsPrefix", this.annotationsPrefix).append("addPorts", this.addPorts)
.append("portsPrefix", this.portsPrefix).toString();
// needed in order to get the defaults for some fields
public Metadata() {
this(true, null, true, null, true, "port.");
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2013-2022 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 org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties.Metadata;
/**
* @author wind57
*/
class KubernetesDiscoveryPropertiesMetadataTests {
@Test
void testDefaultConstructor() {
Metadata m = new Metadata();
assertThat(m.addLabels()).isTrue();
assertThat(m.labelsPrefix()).isNull();
assertThat(m.addAnnotations()).isTrue();
assertThat(m.annotationsPrefix()).isNull();
assertThat(m.addPorts()).isTrue();
assertThat(m.portsPrefix()).isEqualTo("port.");
}
@Test
void testSpringBindingFields() {
new ApplicationContextRunner().withUserConfiguration(Config.class)
.withPropertyValues("spring.cloud.kubernetes.discovery.metadata.labelsPrefix=labelsPrefix")
.run(context -> {
KubernetesDiscoveryProperties props = context.getBean(KubernetesDiscoveryProperties.class);
assertThat(props).isNotNull();
assertThat(props.getMetadata().labelsPrefix()).isEqualTo("labelsPrefix");
assertThat(props.getMetadata().addPorts()).isTrue();
assertThat(props.getMetadata().portsPrefix()).isEqualTo("port.");
});
}
@Configuration
@EnableConfigurationProperties(KubernetesDiscoveryProperties.class)
static class Config {
}
}

View File

@@ -147,11 +147,11 @@ public class KubernetesDiscoveryClient implements DiscoveryClient {
// Extend the service metadata map with per-endpoint port information (if
// requested)
Map<String, String> endpointMetadata = new HashMap<>(serviceMetadata);
if (metadataProps.isAddPorts()) {
if (metadataProps.addPorts()) {
Map<String, String> ports = s.getPorts().stream()
.filter(port -> StringUtils.hasText(port.getName()))
.collect(toMap(EndpointPort::getName, port -> Integer.toString(port.getPort())));
Map<String, String> portMetadata = getMapWithPrefixedKeys(ports, metadataProps.getPortsPrefix());
Map<String, String> portMetadata = getMapWithPrefixedKeys(ports, metadataProps.portsPrefix());
if (log.isDebugEnabled()) {
log.debug("Adding port metadata: " + portMetadata);
}
@@ -193,17 +193,17 @@ public class KubernetesDiscoveryClient implements DiscoveryClient {
private Map<String, String> getServiceMetadata(Service service) {
final Map<String, String> serviceMetadata = new HashMap<>();
KubernetesDiscoveryProperties.Metadata metadataProps = this.properties.getMetadata();
if (metadataProps.isAddLabels()) {
if (metadataProps.addLabels()) {
Map<String, String> labelMetadata = getMapWithPrefixedKeys(service.getMetadata().getLabels(),
metadataProps.getLabelsPrefix());
metadataProps.labelsPrefix());
if (log.isDebugEnabled()) {
log.debug("Adding label metadata: " + labelMetadata);
}
serviceMetadata.putAll(labelMetadata);
}
if (metadataProps.isAddAnnotations()) {
if (metadataProps.addAnnotations()) {
Map<String, String> annotationMetadata = getMapWithPrefixedKeys(service.getMetadata().getAnnotations(),
metadataProps.getAnnotationsPrefix());
metadataProps.annotationsPrefix());
if (log.isDebugEnabled()) {
log.debug("Adding annotation metadata: " + annotationMetadata);
}

View File

@@ -54,6 +54,7 @@ import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties.Metadata;
@RunWith(MockitoJUnitRunner.class)
public class KubernetesDiscoveryClientFilterMetadataTest {
@@ -67,9 +68,6 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
@Mock
private ServicePortSecureResolver isServicePortSecureResolver;
@Mock
private KubernetesDiscoveryProperties.Metadata metadata;
@Mock
private MixedOperation<Service, ServiceList, ServiceResource<Service>> serviceOperation;
@@ -92,10 +90,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testAllExtraMetadataDisabled() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(false);
when(this.metadata.isAddAnnotations()).thenReturn(false);
when(this.metadata.isAddPorts()).thenReturn(false);
Metadata metadata = new Metadata(false, null, false, null, false, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -121,10 +117,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testLabelsEnabled() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(true);
when(this.metadata.isAddAnnotations()).thenReturn(false);
when(this.metadata.isAddPorts()).thenReturn(false);
Metadata metadata = new Metadata(true, null, false, null, false, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -151,11 +145,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testLabelsEnabledWithPrefix() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(true);
when(this.metadata.getLabelsPrefix()).thenReturn("l_");
when(this.metadata.isAddAnnotations()).thenReturn(false);
when(this.metadata.isAddPorts()).thenReturn(false);
Metadata metadata = new Metadata(true, "l_", false, null, false, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -182,10 +173,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testAnnotationsEnabled() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(false);
when(this.metadata.isAddAnnotations()).thenReturn(true);
when(this.metadata.isAddPorts()).thenReturn(false);
Metadata metadata = new Metadata(false, null, true, null, false, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -212,11 +201,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testAnnotationsEnabledWithPrefix() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(false);
when(this.metadata.isAddAnnotations()).thenReturn(true);
when(this.metadata.getAnnotationsPrefix()).thenReturn("a_");
when(this.metadata.isAddPorts()).thenReturn(false);
Metadata metadata = new Metadata(false, null, true, "a_", false, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -243,10 +229,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testPortsEnabled() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(false);
when(this.metadata.isAddAnnotations()).thenReturn(false);
when(this.metadata.isAddPorts()).thenReturn(true);
Metadata metadata = new Metadata(false, null, false, null, true, null);
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -273,11 +257,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testPortsEnabledWithPrefix() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(false);
when(this.metadata.isAddAnnotations()).thenReturn(false);
when(this.metadata.isAddPorts()).thenReturn(true);
when(this.metadata.getPortsPrefix()).thenReturn("p_");
Metadata metadata = new Metadata(false, null, false, null, true, "p_");
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{
@@ -304,13 +285,8 @@ public class KubernetesDiscoveryClientFilterMetadataTest {
public void testLabelsAndAnnotationsAndPortsEnabledWithPrefix() {
final String serviceId = "s";
when(this.properties.getMetadata()).thenReturn(this.metadata);
when(this.metadata.isAddLabels()).thenReturn(true);
when(this.metadata.getLabelsPrefix()).thenReturn("l_");
when(this.metadata.isAddAnnotations()).thenReturn(true);
when(this.metadata.getAnnotationsPrefix()).thenReturn("a_");
when(this.metadata.isAddPorts()).thenReturn(true);
when(this.metadata.getPortsPrefix()).thenReturn("p_");
Metadata metadata = new Metadata(true, "l_", true, "a_", true, "p_");
when(this.properties.getMetadata()).thenReturn(metadata);
setupServiceWithLabelsAndAnnotationsAndPorts(serviceId, "ns", new HashMap<String, String>() {
{

View File

@@ -40,6 +40,7 @@ import org.springframework.cloud.kubernetes.commons.discovery.KubernetesServiceI
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties.Metadata;
@ExtendWith(SpringExtension.class)
@EnableKubernetesMockClient(crud = true, https = false)
@@ -81,9 +82,9 @@ public class KubernetesDiscoveryClientTest {
mockClient.services().inNamespace("test").create(service);
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
Metadata metadata = new Metadata(false, null, false, null, true, "port.");
properties.setServiceLabels(labels);
properties.getMetadata().setAddLabels(false);
properties.getMetadata().setAddAnnotations(false);
properties.setMetadata(metadata);
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties,
KubernetesClient::services, new ServicePortSecureResolver(properties));
@@ -167,8 +168,8 @@ public class KubernetesDiscoveryClientTest {
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
properties.setServiceLabels(labels);
properties.getMetadata().setAddAnnotations(false);
properties.getMetadata().setAddLabels(false);
Metadata metadata = new Metadata(false, null, false, null, true, "port.");
properties.setMetadata(metadata);
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient, properties,
KubernetesClient::services, new ServicePortSecureResolver(properties));

View File

@@ -42,6 +42,7 @@ import org.springframework.cloud.kubernetes.fabric8.discovery.support.Kubernetes
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties.Metadata;
/**
* @author Tim Ysewyn
@@ -180,8 +181,8 @@ class KubernetesReactiveDiscoveryClientTests {
.andReturn(200, services.getItems().get(0)).once();
KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
properties.getMetadata().setAddAnnotations(false);
properties.getMetadata().setAddLabels(false);
Metadata metadata = new Metadata(false, null, false, null, true, "port.");
properties.setMetadata(metadata);
ReactiveDiscoveryClient client = new KubernetesReactiveDiscoveryClient(kubernetesClient, properties,
KubernetesClient::services);
Flux<ServiceInstance> instances = client.getInstances("existing-service");
@@ -224,9 +225,8 @@ class KubernetesReactiveDiscoveryClientTests {
.once();
KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
properties.getMetadata().setAnnotationsPrefix("annotation.");
properties.getMetadata().setLabelsPrefix("label.");
properties.getMetadata().setPortsPrefix("port.");
Metadata metadata = new Metadata(true, "label.", true, "annotation.", true, "port.");
properties.setMetadata(metadata);
ReactiveDiscoveryClient client = new KubernetesReactiveDiscoveryClient(kubernetesClient, properties,
KubernetesClient::services);
Flux<ServiceInstance> instances = client.getInstances("existing-service");

View File

@@ -78,14 +78,14 @@ public class Fabric8ServiceInstanceMapper implements KubernetesServiceInstanceMa
private Map<String, String> getServiceMetadata(Service service) {
final Map<String, String> serviceMetadata = new HashMap<>();
KubernetesDiscoveryProperties.Metadata metadataProps = this.discoveryProperties.getMetadata();
if (metadataProps.isAddLabels()) {
if (metadataProps.addLabels()) {
Map<String, String> labelMetadata = KubernetesServiceInstanceMapper
.getMapWithPrefixedKeys(service.getMetadata().getLabels(), metadataProps.getLabelsPrefix());
.getMapWithPrefixedKeys(service.getMetadata().getLabels(), metadataProps.labelsPrefix());
serviceMetadata.putAll(labelMetadata);
}
if (metadataProps.isAddAnnotations()) {
Map<String, String> annotationMetadata = KubernetesServiceInstanceMapper.getMapWithPrefixedKeys(
service.getMetadata().getAnnotations(), metadataProps.getAnnotationsPrefix());
if (metadataProps.addAnnotations()) {
Map<String, String> annotationMetadata = KubernetesServiceInstanceMapper
.getMapWithPrefixedKeys(service.getMetadata().getAnnotations(), metadataProps.annotationsPrefix());
serviceMetadata.putAll(annotationMetadata);
}