diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java index ccfc54cd7..b83c70b85 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClient.java @@ -77,7 +77,8 @@ private void addInstancesToList(List instances, String serviceI Response> services = this.client.getHealthServices(serviceId, request); for (HealthService service : services.getValue()) { - instances.add(new ConsulServiceInstance(service, serviceId)); + instances + .add(new ConsulServiceInstance(service, serviceId, this.properties.isMergeTagsEnabled())); } } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java index bdb3092c0..1a5e8f8dd 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryProperties.java @@ -205,6 +205,12 @@ public class ConsulDiscoveryProperties { */ private int order = 0; + /** + * Enable merge consul tag data with metadata to create service instance (defaults + * to false). + */ + private boolean mergeTagsEnabled = false; + @SuppressWarnings("unused") private ConsulDiscoveryProperties() { this.managementTags.add(MANAGEMENT); @@ -580,6 +586,14 @@ public void setManagementEnableTagOverride(Boolean managementEnableTagOverride) this.managementEnableTagOverride = managementEnableTagOverride; } + public boolean isMergeTagsEnabled() { + return this.mergeTagsEnabled; + } + + public void setMergeTagsEnabled(boolean mergeTagsEnabled) { + this.mergeTagsEnabled = mergeTagsEnabled; + } + @Override public String toString() { return new ToStringCreator(this).append("aclToken", this.aclToken) @@ -591,6 +605,7 @@ public String toString() { .append("enabled", this.enabled).append("enableTagOverride", this.enableTagOverride) .append("failFast", this.failFast).append("hostInfo", this.hostInfo) .append("healthCheckCriticalTimeout", this.healthCheckCriticalTimeout) + .append("mergeTagsEnabled", this.mergeTagsEnabled) .append("healthCheckHeaders", this.healthCheckHeaders) .append("healthCheckInterval", this.healthCheckInterval).append("healthCheckPath", this.healthCheckPath) .append("healthCheckTimeout", this.healthCheckTimeout) diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServiceInstance.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServiceInstance.java index 240422c80..186618a2b 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServiceInstance.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServiceInstance.java @@ -16,6 +16,7 @@ package org.springframework.cloud.consul.discovery; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -25,6 +26,7 @@ import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.core.style.ToStringCreator; +import org.springframework.util.StringUtils; import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findHost; @@ -32,16 +34,21 @@ public class ConsulServiceInstance extends DefaultServiceInstance { private HealthService healthService; - public ConsulServiceInstance(HealthService healthService, String serviceId) { + public ConsulServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure, + Map metadata, List tags) { + this(instanceId, serviceId, host, port, secure, metadata, tags, false); + } + + public ConsulServiceInstance(HealthService healthService, String serviceId, boolean mergeTags) { this(healthService.getService().getId(), serviceId, findHost(healthService), - healthService.getService().getPort(), getSecure(healthService), getMetadata(healthService), - healthService.getService().getTags()); + healthService.getService().getPort(), getSecure(healthService), getMetadata(healthService), + healthService.getService().getTags(), mergeTags); this.healthService = healthService; } public ConsulServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure, - Map metadata, List tags) { - super(instanceId, serviceId, host, port, secure, metadata); + Map metadata, List tags, boolean mergeTags) { + super(instanceId, serviceId, host, port, secure, mergeTags ? mergeTags(metadata, tags) : metadata); } public ConsulServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure) { @@ -51,6 +58,39 @@ public ConsulServiceInstance(String instanceId, String serviceId, String host, i public ConsulServiceInstance() { } + private static Map mergeTags(Map metadata, List tags) { + Map result = new LinkedHashMap<>(); + + if (metadata != null) { + result.putAll(metadata); + } + + if (tags == null || tags.isEmpty()) { + return result; + } + + for (String tag : tags) { + String[] parts = StringUtils.delimitedListToStringArray(tag, "="); + + switch (parts.length) { + case 0: + break; + case 1: + result.put(parts[0], parts[0]); + break; + case 2: + result.put(parts[0], parts[1]); + break; + default: + String[] end = Arrays.copyOfRange(parts, 1, parts.length); + result.put(parts[0], StringUtils.arrayToDelimitedString(end, "=")); + break; + } + } + + return result; + } + private static Map getMetadata(HealthService healthService) { Map metadata = healthService.getService().getMeta(); if (metadata == null) { @@ -77,8 +117,8 @@ public void setHealthService(HealthService healthService) { } public List getTags() { - if (healthService != null) { - return healthService.getService().getTags(); + if (this.healthService != null) { + return this.healthService.getService().getTags(); } return Collections.emptyList(); } diff --git a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/reactive/ConsulReactiveDiscoveryClient.java b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/reactive/ConsulReactiveDiscoveryClient.java index 5a4ff0a2e..81f5bc360 100644 --- a/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/reactive/ConsulReactiveDiscoveryClient.java +++ b/spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/reactive/ConsulReactiveDiscoveryClient.java @@ -65,7 +65,8 @@ public Flux getInstances(String serviceId) { return Flux.defer(() -> { List instances = new ArrayList<>(); for (HealthService healthService : getHealthServices(serviceId)) { - instances.add(new ConsulServiceInstance(healthService, serviceId)); + instances.add(new ConsulServiceInstance(healthService, serviceId, + this.properties.isMergeTagsEnabled())); } return Flux.fromIterable(instances); }).onErrorResume(exception -> {