Reinstates ConsulServiceInstance with reference to HealthService.

This allows users to cast to ConsulServiceInstance and get any data they need that isn't exposed thru ServiceInstance interface.

Fixes gh-682
This commit is contained in:
spencergibb
2020-12-20 13:15:24 -05:00
parent 2f7844f41c
commit f69d814315
5 changed files with 110 additions and 42 deletions

View File

@@ -17,7 +17,6 @@
package org.springframework.cloud.consul.discovery;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -27,15 +26,10 @@ import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
import com.ecwid.consul.v1.health.HealthServicesRequest;
import com.ecwid.consul.v1.health.model.HealthService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findHost;
/**
* @author Spencer Gibb
* @author Joe Athman
@@ -44,8 +38,6 @@ import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findH
*/
public class ConsulDiscoveryClient implements DiscoveryClient {
private static final Log log = LogFactory.getLog(ConsulDiscoveryClient.class);
private final ConsulClient client;
private final ConsulDiscoveryProperties properties;
@@ -85,18 +77,7 @@ public class ConsulDiscoveryClient implements DiscoveryClient {
Response<List<HealthService>> services = this.client.getHealthServices(serviceId, request);
for (HealthService service : services.getValue()) {
String host = findHost(service);
Map<String, String> metadata = service.getService().getMeta();
if (metadata == null) {
metadata = new LinkedHashMap<>();
}
boolean secure = false;
if (metadata.containsKey("secure")) {
secure = Boolean.parseBoolean(metadata.get("secure"));
}
instances.add(new DefaultServiceInstance(service.getService().getId(), serviceId, host,
service.getService().getPort(), secure, metadata));
instances.add(new ConsulServiceInstance(service, serviceId));
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2015-2020 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.consul.discovery;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.ecwid.consul.v1.health.model.HealthService;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.core.style.ToStringCreator;
import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findHost;
public class ConsulServiceInstance extends DefaultServiceInstance {
private HealthService healthService;
public ConsulServiceInstance(HealthService healthService, String serviceId) {
this(healthService.getService().getId(), serviceId, findHost(healthService),
healthService.getService().getPort(), getSecure(healthService), getMetadata(healthService), healthService.getService().getTags());
this.healthService = healthService;
}
public ConsulServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure, Map<String, String> metadata, List<String> tags) {
super(instanceId, serviceId, host, port, secure, metadata);
}
public ConsulServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure) {
super(instanceId, serviceId, host, port, secure);
}
public ConsulServiceInstance() {
}
private static Map<String, String> getMetadata(HealthService healthService) {
Map<String, String> metadata = healthService.getService().getMeta();
if (metadata == null) {
metadata = new LinkedHashMap<>();
}
return metadata;
}
private static boolean getSecure(HealthService healthService) {
boolean secure = false;
Map<String, String> metadata = getMetadata(healthService);
if (metadata.containsKey("secure")) {
secure = Boolean.parseBoolean(metadata.get("secure"));
}
return secure;
}
public HealthService getHealthService() {
return this.healthService;
}
public void setHealthService(HealthService healthService) {
this.healthService = healthService;
}
public List<String> getTags() {
if (healthService != null) {
return healthService.getService().getTags();
}
return Collections.emptyList();
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("instanceId", getInstanceId())
.append("serviceId", getServiceId())
.append("host", getHost())
.append("port", getPort())
.append("secure", isSecure())
.append("metadata", getMetadata())
.append("uri", getUri())
.append("healthService", healthService)
.toString();
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.consul.discovery.reactive;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -33,12 +32,10 @@ import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import static org.springframework.cloud.consul.discovery.ConsulServerUtils.findHost;
import org.springframework.cloud.consul.discovery.ConsulServiceInstance;
/**
* Consul version of {@link ReactiveDiscoveryClient}.
@@ -68,7 +65,7 @@ public class ConsulReactiveDiscoveryClient implements ReactiveDiscoveryClient {
return Flux.defer(() -> {
List<ServiceInstance> instances = new ArrayList<>();
for (HealthService healthService : getHealthServices(serviceId)) {
instances.add(mapToServiceInstance(healthService, serviceId));
instances.add(new ConsulServiceInstance(healthService, serviceId));
}
return Flux.fromIterable(instances);
}).onErrorResume(exception -> {
@@ -86,20 +83,6 @@ public class ConsulReactiveDiscoveryClient implements ReactiveDiscoveryClient {
return services == null ? Collections.emptyList() : services.getValue();
}
private ServiceInstance mapToServiceInstance(HealthService service, String serviceId) {
String host = findHost(service);
Map<String, String> metadata = service.getService().getMeta();
if (metadata == null) {
metadata = new LinkedHashMap<>();
}
boolean secure = false;
if (metadata.containsKey("secure")) {
secure = Boolean.parseBoolean(metadata.get("secure"));
}
return new DefaultServiceInstance(service.getService().getId(), serviceId, host, service.getService().getPort(),
secure, metadata);
}
@Override
public Flux<String> getServices() {
return Flux.defer(() -> {

View File

@@ -84,6 +84,10 @@ public class ConsulDiscoveryClientDefaultQueryTagTests {
assertThat(serviceInstance.getPort()).isEqualTo(intgService.getPort());
assertThat(serviceInstance.getServiceId()).isEqualTo(intgService.getName());
assertThat(serviceInstance.getInstanceId()).isEqualTo(intgService.getId());
assertThat(serviceInstance).isInstanceOf(ConsulServiceInstance.class);
ConsulServiceInstance consulInstance = (ConsulServiceInstance) serviceInstance;
assertThat(consulInstance.getTags()).containsOnly("intg");
assertThat(consulInstance.getHealthService()).isNotNull();
}
private NewService serviceForEnvironment(String env, int port) {

View File

@@ -18,11 +18,12 @@ package org.springframework.cloud.consul.discovery.configclient;
import java.util.Arrays;
import com.ecwid.consul.v1.health.model.HealthService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServiceInstance;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -36,8 +37,9 @@ public class TestConsulDiscoveryClientBootstrapConfiguration {
@Bean
public ConsulDiscoveryClient consulDiscoveryClient(ConsulDiscoveryProperties properties) {
ConsulDiscoveryClient client = mock(ConsulDiscoveryClient.class);
ServiceInstance instance = new DefaultServiceInstance("configserver1", "configserver", properties.getHostname(),
ConsulServiceInstance instance = new ConsulServiceInstance("configserver1", "configserver", properties.getHostname(),
properties.getPort(), false);
instance.setHealthService(mock(HealthService.class));
given(client.getInstances("configserver")).willReturn(Arrays.asList(instance));
return client;
}