Update Eureka to 1.2.5-rc.1
Remove Servo from EurekaHealthIndicator. Remove custom DataCenterInfo. EurekaInstanceConfig.SID is now used as eureka id. EurekaInstanceConfigBean.getSID falls back to metadataMap.instanceId for backwards compatibility.
This commit is contained in:
committed by
Spencer Gibb
parent
ded968ad58
commit
8f9acab3bd
2
pom.xml
2
pom.xml
@@ -26,7 +26,7 @@
|
||||
<spring-cloud-stream.version>1.0.0.BUILD-SNAPSHOT</spring-cloud-stream.version>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<archaius.version>0.6.5</archaius.version>
|
||||
<eureka.version>1.2.0</eureka.version>
|
||||
<eureka.version>1.2.5-rc.1</eureka.version>
|
||||
<feign.version>8.10.0</feign.version>
|
||||
<hystrix.version>1.4.15</hystrix.version>
|
||||
<ribbon.version>2.1.0</ribbon.version>
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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
|
||||
*
|
||||
* http://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.netflix.eureka;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.appinfo.LeaseInfo;
|
||||
import com.netflix.discovery.converters.EurekaJacksonCodec;
|
||||
import com.netflix.discovery.converters.StringCache;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DataCenterAwareJacksonCodec extends EurekaJacksonCodec {
|
||||
private static final Version VERSION = new Version(1, 1, 0, null);
|
||||
|
||||
@SneakyThrows
|
||||
public DataCenterAwareJacksonCodec() {
|
||||
super();
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
SimpleModule module = new SimpleModule("eureka1.x", VERSION);
|
||||
module.addSerializer(DataCenterInfo.class, new DataCenterInfoSerializer());
|
||||
module.addSerializer(InstanceInfo.class, new DCAwareInstanceInfoSerializer());
|
||||
module.addSerializer(Application.class, new ApplicationSerializer());
|
||||
module.addSerializer(Applications.class, new ApplicationsSerializer(getVersionDeltaKey(), getAppHashCodeKey()));
|
||||
|
||||
module.addDeserializer(DataCenterInfo.class, new DataCenterInfoDeserializer(getCache()));
|
||||
module.addDeserializer(LeaseInfo.class, new LeaseInfoDeserializer());
|
||||
module.addDeserializer(InstanceInfo.class, new DCAwareInstanceInfoDeserializer(getCache()));
|
||||
module.addDeserializer(Application.class, new ApplicationDeserializer(mapper, getCache()));
|
||||
module.addDeserializer(Applications.class, new ApplicationsDeserializer(mapper, getVersionDeltaKey(), getAppHashCodeKey()));
|
||||
|
||||
mapper.registerModule(module);
|
||||
|
||||
Map<Class<?>, ObjectReader> readers = getField("objectReaderByClass");
|
||||
readers.put(InstanceInfo.class, mapper.reader().withType(InstanceInfo.class).withRootName("instance"));
|
||||
readers.put(Application.class, mapper.reader().withType(Application.class).withRootName("application"));
|
||||
readers.put(Applications.class, mapper.reader().withType(Applications.class).withRootName("applications"));
|
||||
|
||||
Map<Class<?>, ObjectWriter> writers = getField("objectWriterByClass");
|
||||
writers.put(InstanceInfo.class, mapper.writer().withType(InstanceInfo.class).withRootName("instance"));
|
||||
writers.put(Application.class, mapper.writer().withType(Application.class).withRootName("application"));
|
||||
writers.put(Applications.class, mapper.writer().withType(Applications.class).withRootName("applications"));
|
||||
|
||||
Field field = ReflectionUtils.findField(EurekaJacksonCodec.class, "mapper");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
field.set(this, mapper);
|
||||
}
|
||||
|
||||
private <T> T getField(String name) throws IllegalAccessException {
|
||||
Field field = ReflectionUtils.findField(EurekaJacksonCodec.class, name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return (T) field.get(this);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void init() {
|
||||
if (!(EurekaJacksonCodec.getInstance() instanceof DataCenterAwareJacksonCodec)) {
|
||||
INSTANCE = new DataCenterAwareJacksonCodec();
|
||||
}
|
||||
}
|
||||
|
||||
@CommonsLog
|
||||
private static class DCAwareInstanceInfoSerializer extends
|
||||
InstanceInfoSerializer {
|
||||
|
||||
@Override
|
||||
public void serialize(InstanceInfo info, JsonGenerator jgen,
|
||||
SerializerProvider provider) throws IOException {
|
||||
String instanceId = info.getMetadata().get("instanceId");
|
||||
DataCenterInfo dataCenter = info.getDataCenterInfo();
|
||||
if (instanceId != null
|
||||
&& DataCenterInfo.Name.Amazon != dataCenter.getName()) {
|
||||
String old = info.getId();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
}
|
||||
|
||||
super.serialize(info, jgen, provider);
|
||||
}
|
||||
}
|
||||
|
||||
private class DCAwareInstanceInfoDeserializer extends InstanceInfoDeserializer {
|
||||
private DCAwareInstanceInfoDeserializer(StringCache cache) {
|
||||
super(getMapper(), cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceInfo deserialize(JsonParser jp, DeserializationContext context)
|
||||
throws IOException {
|
||||
InstanceInfo info = super.deserialize(jp, context);
|
||||
String instanceId = info.getMetadata().get("instanceId");
|
||||
DataCenterInfo dataCenter = info.getDataCenterInfo();
|
||||
if (instanceId != null && DataCenterInfo.Name.Amazon != dataCenter.getName()) {
|
||||
String old = info.getId();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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
|
||||
*
|
||||
* http://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.netflix.eureka;
|
||||
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.DataCenterInfo.Name;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.converters.Converters.ApplicationsConverter;
|
||||
import com.netflix.discovery.converters.Converters.InstanceInfoConverter;
|
||||
import com.netflix.discovery.converters.StringCache;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.thoughtworks.xstream.MarshallingStrategy;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.ConverterLookup;
|
||||
import com.thoughtworks.xstream.converters.DataHolder;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
||||
import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
import com.thoughtworks.xstream.mapper.Mapper;
|
||||
|
||||
/**
|
||||
* A special purpose wrapper for an XStream TreeMarshallingStrategy that is aware of the
|
||||
* {@link InstanceInfo} type and can create a more useful {@link DataCenterInfo} for it
|
||||
* after unmarshalling. If the InstanceInfo has a metadataMap containing an
|
||||
* <code>instanceId</code>, and the DataCenterInfo is not already an AmazonInfo, then the
|
||||
* instanceId is used to create an identifier, but appending it to the existing one. This
|
||||
* is useful when not running Eureka in bare EC2 VMs, so the EC2 metadata is not available
|
||||
* for uniquely identifying the InstanceInfo (the default is to just use the hostname, but
|
||||
* that isn't very useful when sitting behind a proxy).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
|
||||
private TreeMarshallingStrategy delegate = new TreeMarshallingStrategy();
|
||||
|
||||
public DataCenterAwareMarshallingStrategy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(Object root, HierarchicalStreamReader reader,
|
||||
DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) {
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup);
|
||||
return this.delegate.unmarshal(root, reader, dataHolder, wrapped, mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(HierarchicalStreamWriter writer, Object obj,
|
||||
ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder) {
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup);
|
||||
this.delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
|
||||
}
|
||||
|
||||
private static class DataCenterAwareConverterLookup implements ConverterLookup {
|
||||
|
||||
private ConverterLookup delegate;
|
||||
|
||||
public DataCenterAwareConverterLookup(ConverterLookup delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter lookupConverterForType(@SuppressWarnings("rawtypes") Class type) {
|
||||
Converter converter = this.delegate.lookupConverterForType(type);
|
||||
if (InstanceInfo.class == type) {
|
||||
return new DataCenterAwareConverter();
|
||||
}
|
||||
else if (Applications.class == type) {
|
||||
return new ApplicationsConverter();
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataCenterAwareConverter extends InstanceInfoConverter {
|
||||
|
||||
public DataCenterAwareConverter() {
|
||||
super(new StringCache());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(Object source, HierarchicalStreamWriter writer,
|
||||
MarshallingContext context) {
|
||||
InstanceInfo info = (InstanceInfo) source;
|
||||
String instanceId = info.getMetadata().get("instanceId");
|
||||
DataCenterInfo dataCenter = info.getDataCenterInfo();
|
||||
if (instanceId != null && Name.Amazon != dataCenter.getName()) {
|
||||
String old = info.getId();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
source = info;
|
||||
}
|
||||
super.marshal(source, writer, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(HierarchicalStreamReader reader,
|
||||
UnmarshallingContext context) {
|
||||
Object obj = super.unmarshal(reader, context);
|
||||
InstanceInfo info = (InstanceInfo) obj;
|
||||
String instanceId = info.getMetadata().get("instanceId");
|
||||
DataCenterInfo dataCenter = info.getDataCenterInfo();
|
||||
if (instanceId != null && Name.Amazon != dataCenter.getName()) {
|
||||
String old = info.getId();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
obj = info;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
@@ -52,8 +50,6 @@ import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.converters.JsonXStream;
|
||||
import com.netflix.discovery.converters.XmlXStream;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@@ -72,15 +68,6 @@ public class EurekaClientAutoConfiguration {
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
int nonSecurePort;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
DataCenterAwareJacksonCodec.init();
|
||||
XmlXStream.getInstance()
|
||||
.setMarshallingStrategy(new DataCenterAwareMarshallingStrategy());
|
||||
JsonXStream.getInstance()
|
||||
.setMarshallingStrategy(new DataCenterAwareMarshallingStrategy());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
|
||||
public EurekaClientConfigBean eurekaClientConfigBean() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import lombok.Data;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import com.netflix.appinfo.EurekaAccept;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
/**
|
||||
@@ -90,7 +91,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private Map<String, String> serviceUrl = new HashMap<String, String>();
|
||||
private Map<String, String> serviceUrl = new HashMap<>();
|
||||
{
|
||||
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
}
|
||||
@@ -123,6 +124,12 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private boolean onDemandUpdateStatusChange = true;
|
||||
|
||||
private String encoderName;
|
||||
|
||||
private String decoderName;
|
||||
|
||||
private String clientDataAccept = EurekaAccept.full.name();
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return this.gZipContent;
|
||||
@@ -199,4 +206,5 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
public boolean shouldOnDemandUpdateStatusChange() {
|
||||
return this.onDemandUpdateStatusChange;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -26,8 +24,6 @@ import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.health.HealthAggregator;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
|
||||
import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -182,19 +178,12 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
@ConditionalOnBean(MetricReader.class)
|
||||
protected static class EurekaHealthIndicatorConfiguration {
|
||||
|
||||
@Autowired
|
||||
private List<MetricReader> metricReaders = Collections.emptyList();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EurekaHealthIndicator eurekaHealthIndicator(EurekaClient eurekaClient,
|
||||
EurekaInstanceConfig config) {
|
||||
CompositeMetricReader metrics = new CompositeMetricReader(
|
||||
this.metricReaders.toArray(new MetricReader[0]));
|
||||
return new EurekaHealthIndicator(eurekaClient, metrics, config);
|
||||
EurekaInstanceConfig instanceConfig, EurekaClientConfig clientConfig) {
|
||||
return new EurekaHealthIndicator(eurekaClient, instanceConfig, clientConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
|
||||
@@ -39,18 +39,16 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
|
||||
private final EurekaClient eurekaClient;
|
||||
|
||||
private final MetricReader metrics;
|
||||
|
||||
private final EurekaInstanceConfig instanceConfig;
|
||||
|
||||
private int failCount = 0;
|
||||
private final EurekaClientConfig clientConfig;
|
||||
|
||||
public EurekaHealthIndicator(EurekaClient eurekaClient, MetricReader metrics,
|
||||
EurekaInstanceConfig instanceConfig) {
|
||||
public EurekaHealthIndicator(EurekaClient eurekaClient,
|
||||
EurekaInstanceConfig instanceConfig, EurekaClientConfig clientConfig) {
|
||||
super();
|
||||
this.eurekaClient = eurekaClient;
|
||||
this.metrics = metrics;
|
||||
this.instanceConfig = instanceConfig;
|
||||
this.clientConfig = clientConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,24 +65,28 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
}
|
||||
|
||||
private Status getStatus(Builder builder) {
|
||||
Status status = new Status(this.eurekaClient.getInstanceRemoteStatus().toString(),
|
||||
Status status = new Status(
|
||||
this.eurekaClient.getInstanceRemoteStatus().toString(),
|
||||
"Remote status from Eureka server");
|
||||
@SuppressWarnings("unchecked")
|
||||
Metric<Number> value = (Metric<Number>) this.metrics
|
||||
.findOne("counter.servo.discoveryclient_failed");
|
||||
if (value != null) {
|
||||
int renewalPeriod = this.instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int latest = value.getValue().intValue();
|
||||
builder.withDetail("failCount", latest);
|
||||
builder.withDetail("renewalPeriod", renewalPeriod);
|
||||
if (this.failCount < latest) {
|
||||
status = new Status("UP", "Eureka discovery client is reporting failures");
|
||||
this.failCount = latest;
|
||||
|
||||
if (eurekaClient instanceof DiscoveryClient && clientConfig.shouldFetchRegistry()) {
|
||||
DiscoveryClient discoveryClient = (DiscoveryClient) eurekaClient;
|
||||
long lastFetch = discoveryClient.getLastSuccessfulRegistryFetchTimePeriod();
|
||||
|
||||
if (lastFetch < 0) {
|
||||
status = new Status("UP",
|
||||
"Eureka discovery client has not yet successfully connected to a Eureka server");
|
||||
}
|
||||
else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
else if (lastFetch > clientConfig.getRegistryFetchIntervalSeconds() * 2) {
|
||||
status = new Status("UP",
|
||||
"Eureka discovery client is reporting failures to connect to a Eureka server");
|
||||
builder.withDetail("renewalPeriod",
|
||||
instanceConfig.getLeaseRenewalIntervalInSeconds());
|
||||
builder.withDetail("failCount",
|
||||
lastFetch / clientConfig.getRegistryFetchIntervalSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.appinfo.MyDataCenterInfo;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
@@ -38,7 +39,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -76,13 +76,15 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String virtualHostName;
|
||||
|
||||
private String sid;
|
||||
|
||||
private String secureVirtualHostName;
|
||||
|
||||
private String aSGName;
|
||||
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
private DataCenterInfo dataCenterInfo = new MyDataCenterInfo(DataCenterInfo.Name.MyOwn);
|
||||
|
||||
private String ipAddress = this.hostInfo.ipAddress;
|
||||
|
||||
@@ -112,7 +114,15 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
return getHostName(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public String getSID() {
|
||||
if (this.sid == null && this.metadataMap != null) {
|
||||
return this.metadataMap.get("instanceId");
|
||||
}
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecurePortEnabled() {
|
||||
return this.securePortEnabled;
|
||||
}
|
||||
@@ -173,26 +183,4 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
private String ipAddress;
|
||||
private String hostname;
|
||||
}
|
||||
|
||||
private final class IdentifyingDataCenterInfo implements DataCenterInfo,
|
||||
UniqueIdentifier {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Name name = Name.MyOwn;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
String instanceId = EurekaInstanceConfigBean.this.metadataMap
|
||||
.get("instanceId");
|
||||
if (instanceId != null) {
|
||||
String old = getHostname();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
return id;
|
||||
}
|
||||
return getHostname();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -164,6 +164,10 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private boolean enableReplicatedRequestCompression = false;
|
||||
|
||||
private String jsonCodecName;
|
||||
|
||||
private String xmlCodecName;
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableSelfPreservation() {
|
||||
return this.enableSelfPreservation;
|
||||
@@ -215,6 +219,16 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
return this.logIdentityHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJsonCodecName() {
|
||||
return jsonCodecName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getXmlCodecName() {
|
||||
return xmlCodecName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseReadOnlyResponseCache() {
|
||||
return this.useReadOnlyResponseCache;
|
||||
|
||||
@@ -42,6 +42,7 @@ public class InstanceInfoFactory {
|
||||
|
||||
builder.setNamespace(config.getNamespace())
|
||||
.setAppName(config.getAppname())
|
||||
.setSID(config.getSID())
|
||||
.setAppGroupName(config.getAppGroupName())
|
||||
.setDataCenterInfo(config.getDataCenterInfo())
|
||||
.setIPAddr(config.getIpAddress())
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -43,7 +42,8 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.hostName = EurekaInstanceConfigBean.getFirstNonLoopbackAddress().getHostName();
|
||||
this.hostName = EurekaInstanceConfigBean.getFirstNonLoopbackAddress()
|
||||
.getHostName();
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -53,14 +53,6 @@ public class EurekaInstanceConfigBeanTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void idFromInstanceId() throws Exception {
|
||||
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean();
|
||||
instance.getMetadataMap().put("instanceId", "foo");
|
||||
instance.setHostname("bar");
|
||||
assertEquals("bar:foo", ((UniqueIdentifier) instance.getDataCenterInfo()).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicBinding() {
|
||||
addEnvironment(this.context, "eureka.instance.appGroupName=mygroup");
|
||||
@@ -75,6 +67,14 @@ public class EurekaInstanceConfigBeanTests {
|
||||
assertEquals(8888, getInstanceConfig().getNonSecurePort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sid() {
|
||||
addEnvironment(this.context, "eureka.instance.sid:special");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
assertEquals("special", instance.getSID());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialHostName() {
|
||||
addEnvironment(this.context, "eureka.instance.appGroupName=mygroup");
|
||||
@@ -137,16 +137,6 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreferIpAddressInDatacenter() throws Exception {
|
||||
addEnvironment(this.context, "eureka.instance.preferIpAddress:true");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
String id = ((UniqueIdentifier) instance.getDataCenterInfo()).getId();
|
||||
assertTrue("Wrong hostname: " + id, id.equals(instance.getIpAddress()));
|
||||
|
||||
}
|
||||
|
||||
private void setupContext() {
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
|
||||
public class InstanceInfoFactoryTests {
|
||||
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@Test
|
||||
public void instanceIdIsHostNameByDefault() {
|
||||
assertEquals(EurekaInstanceConfigBean.getFirstNonLoopbackAddress().getHostName(),
|
||||
setupInstance().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instanceIdIsIpWhenIpPreferred() throws Exception {
|
||||
assertTrue(setupInstance("eureka.instance.preferIpAddress:true").getId().matches(
|
||||
"(\\d+\\.){3}\\d+"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instanceIdIsSidWhenSet() {
|
||||
assertEquals("special", setupInstance("eureka.instance.sid:special").getId());
|
||||
}
|
||||
|
||||
private InstanceInfo setupInstance(String... pairs) {
|
||||
for (String pair : pairs)
|
||||
addEnvironment(this.context, pair);
|
||||
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
EurekaInstanceConfigBean instanceConfig = getInstanceConfig();
|
||||
return new InstanceInfoFactory().create(instanceConfig);
|
||||
}
|
||||
|
||||
private EurekaInstanceConfigBean getInstanceConfig() {
|
||||
return this.context.getBean(EurekaInstanceConfigBean.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(EurekaInstanceConfigBean.class)
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.boot.logging.log4j.Log4JLoggingSystem;
|
||||
import org.springframework.cloud.netflix.eureka.DataCenterAwareJacksonCodec;
|
||||
import org.springframework.cloud.netflix.eureka.DataCenterAwareMarshallingStrategy;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaServerConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.server.advice.LeaseManagerLite;
|
||||
import org.springframework.cloud.netflix.eureka.server.advice.PiggybackMethodInterceptor;
|
||||
@@ -151,11 +149,6 @@ public class EurekaServerInitializerConfiguration
|
||||
EurekaServerConfigurationManager.getInstance()
|
||||
.setConfiguration(
|
||||
EurekaServerInitializerConfiguration.this.eurekaServerConfig);
|
||||
XmlXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy());
|
||||
JsonXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy());
|
||||
DataCenterAwareJacksonCodec.init();
|
||||
EurekaServerInitializerConfiguration.this.applicationContext
|
||||
.publishEvent(new EurekaRegistryAvailableEvent(
|
||||
EurekaServerInitializerConfiguration.this.eurekaServerConfig));
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,14 +32,15 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.netflix.eureka.server.ApplicationContextTests.Application;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
@@ -86,9 +91,13 @@ public class ApplicationContextTests {
|
||||
|
||||
@Test
|
||||
public void adminLoads() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.port + "/context/env", Map.class);
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().exchange("http://localhost:"
|
||||
+ this.port + "/context/env", HttpMethod.GET, new HttpEntity<>(
|
||||
"parameters", headers), Map.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,14 +32,15 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.netflix.eureka.server.ApplicationServletPathTests.Application;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
@@ -97,9 +102,13 @@ public class ApplicationServletPathTests {
|
||||
|
||||
@Test
|
||||
public void adminLoads() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.port + "/servlet/env", Map.class);
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().exchange("http://localhost:"
|
||||
+ this.port + "/servlet/env", HttpMethod.GET, new HttpEntity<>(
|
||||
"parameters", headers), Map.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,15 +33,15 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.netflix.eureka.server.ApplicationTests.Application;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
@@ -66,9 +71,13 @@ public class ApplicationTests {
|
||||
|
||||
@Test
|
||||
public void adminLoads() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().getForEntity(
|
||||
"http://localhost:" + this.port + "/env", Map.class);
|
||||
ResponseEntity<Map> entity = new TestRestTemplate().exchange("http://localhost:"
|
||||
+ this.port + "/env", HttpMethod.GET, new HttpEntity<>("parameters",
|
||||
headers), Map.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
}
|
||||
|
||||
@@ -82,5 +91,4 @@ public class ApplicationTests {
|
||||
assertNotNull(body);
|
||||
assertFalse("basePath contains double slashes", body.contains(basePath + "/"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user