diff --git a/pom.xml b/pom.xml
index 88be448b..7ac1de3b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
1.1.0.BUILD-SNAPSHOT
${basedir}
0.6.5
- 1.1.147
+ 1.2.0
8.6.0
1.4.13
2.0.0
@@ -187,6 +187,11 @@
+
+ com.netflix.governator
+ governator
+ 1.3.3
+
com.netflix.eureka
eureka-core
diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml
index a9d685ef..79f36e92 100644
--- a/spring-cloud-netflix-core/pom.xml
+++ b/spring-cloud-netflix-core/pom.xml
@@ -59,6 +59,12 @@
eureka-client
true
+
+ com.netflix.governator
+ governator
+ 1.3.3
+ true
+
com.netflix.eureka
eureka-core
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfiguration.java
index 362982bd..e8d98693 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfiguration.java
@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.config;
import javax.annotation.PostConstruct;
+import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -25,9 +26,7 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesBindin
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration;
import org.springframework.context.annotation.Configuration;
-import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
-import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.EurekaClientConfig;
/**
@@ -53,17 +52,18 @@ public class DiscoveryClientConfigServiceAutoConfiguration {
@Autowired
private EurekaDiscoveryClientConfiguration lifecycle;
+ @Autowired
+ private EurekaClient eurekaClient;
+
@PostConstruct
public void init() {
this.lifecycle.stop();
rebind(this.clientConfig, "eurekaClientConfig");
rebind(this.instanceConfig, "eurekaInstanceConfig");
- if (DiscoveryManager.getInstance().getDiscoveryClient() != null) {
- DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
- }
- ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
- DiscoveryManager.getInstance().initComponent(this.instanceConfig,
- this.clientConfig);
+ eurekaClient.shutdown();;
+ // FIXME: reinit EurekaClient and ApplicationInfoManager
+ //applicationInfoManager.initComponent(this.instanceConfig);
+ //discoveryManager.initComponent(this.instanceConfig, this.clientConfig);
this.lifecycle.start();
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java
index 5f8a8b53..0d6ed4ab 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java
@@ -34,8 +34,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import com.netflix.appinfo.InstanceInfo;
-import com.netflix.discovery.DiscoveryClient;
-import com.netflix.discovery.DiscoveryManager;
+import com.netflix.discovery.EurekaClient;
/**
* Bootstrap configuration for a config client that wants to lookup the config server via
@@ -43,7 +42,7 @@ import com.netflix.discovery.DiscoveryManager;
*
* @author Dave Syer
*/
-@ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class })
+@ConditionalOnClass({ EurekaClient.class, ConfigServicePropertySourceLocator.class })
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
@Configuration
@EnableDiscoveryClient
@@ -57,6 +56,9 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
@Autowired
private ConfigClientProperties config;
+ @Autowired
+ private EurekaClient eurekaClient;
+
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
@@ -88,9 +90,7 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
private void refresh() {
try {
log.info("Locating configserver via discovery");
- InstanceInfo server = DiscoveryManager
- .getInstance()
- .getDiscoveryClient()
+ InstanceInfo server = eurekaClient
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(),
false);
String url = server.getHomePageUrl();
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java
index 5fe44d69..9fc31d6f 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java
@@ -26,7 +26,7 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
-import com.netflix.discovery.DiscoveryClient;
+import com.netflix.discovery.EurekaClient;
/**
* Extra configuration for config server if it happens to be a Eureka instance.
@@ -35,7 +35,7 @@ import com.netflix.discovery.DiscoveryClient;
*/
@Configuration
@EnableConfigurationProperties
-@ConditionalOnClass({ EurekaInstanceConfigBean.class, DiscoveryClient.class,
+@ConditionalOnClass({ EurekaInstanceConfigBean.class, EurekaClient.class,
ConfigServerProperties.class })
public class EurekaClientConfigServerAutoConfiguration {
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java
new file mode 100644
index 00000000..984c4c58
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util.concurrent.atomic.AtomicLong;
+
+import lombok.extern.apachecommons.CommonsLog;
+
+import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
+import org.springframework.context.ApplicationContext;
+
+import com.netflix.appinfo.ApplicationInfoManager;
+import com.netflix.discovery.DiscoveryClient;
+import com.netflix.discovery.EurekaClientConfig;
+
+/**
+ * @author Spencer Gibb
+ */
+@CommonsLog
+public class CloudEurekaClient extends DiscoveryClient {
+
+ private final AtomicLong cacheRefreshedCount = new AtomicLong(0);
+
+ private ApplicationContext context;
+
+ public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
+ EurekaClientConfig config, ApplicationContext context) {
+ super(applicationInfoManager, config);
+ this.context = context;
+ }
+
+ @Override
+ protected void onCacheRefreshed() {
+ if (this.cacheRefreshedCount != null) { //might be call during construction and won't be inited yet
+ long newCount = this.cacheRefreshedCount.incrementAndGet();
+ log.trace("onCacheRefreshed called with count: " + newCount);
+ this.context.publishEvent(new HeartbeatEvent(this, newCount));
+ }
+ }
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareJacksonCodec.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareJacksonCodec.java
new file mode 100644
index 00000000..ea18e02d
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareJacksonCodec.java
@@ -0,0 +1,144 @@
+/*
+ * 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, 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, 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 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;
+ }
+ }
+
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java
index b6d36b37..49d67d6a 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java
@@ -16,19 +16,12 @@
package org.springframework.cloud.netflix.eureka;
-import lombok.extern.apachecommons.CommonsLog;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
-import org.springframework.context.ApplicationContext;
-
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.DataCenterInfo.Name;
import com.netflix.appinfo.InstanceInfo;
-import com.netflix.appinfo.UniqueIdentifier;
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;
@@ -57,59 +50,29 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
private TreeMarshallingStrategy delegate = new TreeMarshallingStrategy();
- private ApplicationContext context;
-
- public DataCenterAwareMarshallingStrategy(ApplicationContext context) {
- this.context = context;
+ public DataCenterAwareMarshallingStrategy() {
}
@Override
public Object unmarshal(Object root, HierarchicalStreamReader reader,
DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) {
- ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
- this.context);
+ 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.context);
+ ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup);
this.delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
}
- public static class InstanceIdDataCenterInfo implements DataCenterInfo,
- UniqueIdentifier {
-
- private String instanceId;
-
- public InstanceIdDataCenterInfo(String instanceId) {
- this.instanceId = instanceId;
- }
-
- @Override
- public Name getName() {
- return Name.MyOwn;
- }
-
- @Override
- public String getId() {
- return this.instanceId;
- }
-
- }
-
private static class DataCenterAwareConverterLookup implements ConverterLookup {
private ConverterLookup delegate;
- private ApplicationContext context;
-
- public DataCenterAwareConverterLookup(ConverterLookup delegate,
- ApplicationContext context) {
+ public DataCenterAwareConverterLookup(ConverterLookup delegate) {
this.delegate = delegate;
- this.context = context;
}
@Override
@@ -119,57 +82,19 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
return new DataCenterAwareConverter();
}
else if (Applications.class == type) {
- return new PublishingApplicationsConverter(this.context);
+ return new ApplicationsConverter();
}
return converter;
}
}
- private static class PublishingApplicationsConverter extends ApplicationsConverter {
-
- private ApplicationContext context;
-
- public PublishingApplicationsConverter(ApplicationContext context) {
- this.context = context;
- }
-
- @Override
- public Object unmarshal(HierarchicalStreamReader reader,
- UnmarshallingContext unmarshallingContext) {
- Object obj = super.unmarshal(reader, unmarshallingContext);
-
- ProxyFactory factory = new ProxyFactory(obj);
- factory.addAdvice(new SetVersionInterceptor(this.context));
- return factory.getProxy();
- }
- }
-
- @CommonsLog
- private static class SetVersionInterceptor implements MethodInterceptor {
-
- private ApplicationContext context;
-
- public SetVersionInterceptor(ApplicationContext context) {
- this.context = context;
- }
-
- @Override
- public Object invoke(MethodInvocation invocation) throws Throwable {
- Object ret = invocation.proceed();
- if ("setVersion".equals(invocation.getMethod().getName())) {
- Long version = Long.class.cast(invocation.getArguments()[0]);
- log.debug("Applications.setVersion() called with version: " + version);
- this.context.publishEvent(new HeartbeatEvent(invocation
- .getThis(), version));
- }
- return ret;
- }
-
- }
-
private static class DataCenterAwareConverter extends InstanceInfoConverter {
+ public DataCenterAwareConverter() {
+ super(new StringCache());
+ }
+
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java
deleted file mode 100644
index 2e98cc65..00000000
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java
+++ /dev/null
@@ -1,47 +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 org.springframework.beans.factory.annotation.Autowired;
-
-import com.netflix.appinfo.ApplicationInfoManager;
-import com.netflix.appinfo.EurekaInstanceConfig;
-import com.netflix.discovery.DiscoveryManager;
-import com.netflix.discovery.EurekaClientConfig;
-
-/**
- * @author Spencer Gibb
- */
-public class DiscoveryManagerInitializer {
-
- @Autowired
- private EurekaClientConfig clientConfig;
-
- @Autowired
- private EurekaInstanceConfig instanceConfig;
-
- public synchronized void init() {
- if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
- DiscoveryManager.getInstance().initComponent(this.instanceConfig,
- this.clientConfig);
- }
- if (ApplicationInfoManager.getInstance().getInfo() == null) {
- ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
- }
- }
-
-}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
index ea237a38..8dc5e34c 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
@@ -21,7 +21,6 @@ import java.util.concurrent.ConcurrentMap;
import javax.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -40,7 +39,6 @@ import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.discovery.EurekaClientConfig;
-import com.netflix.discovery.converters.JsonXStream;
import com.netflix.discovery.converters.XmlXStream;
/**
@@ -53,9 +51,6 @@ import com.netflix.discovery.converters.XmlXStream;
@AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class)
public class EurekaClientAutoConfiguration implements ApplicationListener {
- @Autowired
- private ApplicationContext applicationContext;
-
private static final ConcurrentMap listenerAdded = new ConcurrentHashMap<>();
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
@@ -63,10 +58,9 @@ public class EurekaClientAutoConfiguration implements ApplicationListener getInstances(String serviceId) {
- List infos = this.discovery.getInstancesByVipAddress(serviceId,
+ List infos = this.eurekaClient.getInstancesByVipAddress(serviceId,
false);
- List instances = new ArrayList();
+ List instances = new ArrayList<>();
for (InstanceInfo info : infos) {
instances.add(new EurekaServiceInstance(info));
}
@@ -130,12 +132,12 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
@Override
public List getServices() {
- Applications applications = this.discovery.getApplications();
+ Applications applications = this.eurekaClient.getApplications();
if (applications == null) {
return Collections.emptyList();
}
List registered = applications.getRegisteredApplications();
- List names = new ArrayList();
+ List names = new ArrayList<>();
for (Application app : registered) {
if (app.getInstances().isEmpty()) {
continue;
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
index e9f232c9..474f48ae 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
@@ -16,7 +16,6 @@
package org.springframework.cloud.netflix.eureka;
-import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -24,6 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PreDestroy;
+import lombok.SneakyThrows;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,19 +43,15 @@ import org.springframework.context.ApplicationListener;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.context.annotation.Scope;
-import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.core.Ordered;
-import org.springframework.util.ReflectionUtils;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.HealthCheckHandler;
+import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
-import com.netflix.discovery.DiscoveryManager;
+import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
-import com.netflix.discovery.shared.EurekaJerseyClient;
/**
* @author Dave Syer
@@ -73,50 +69,18 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
private AtomicInteger port = new AtomicInteger(0);
+ @Autowired
+ private EurekaClientConfig clientConfig;
+
@Autowired
private EurekaInstanceConfigBean instanceConfig;
@Autowired(required = false)
private HealthCheckHandler healthCheckHandler;
- @Autowired
- private DiscoveryManagerInitializer discoveryManagerInitializer;
-
@Autowired
private ApplicationContext context;
- @PreDestroy
- public void close() {
- closeDiscoveryClientJersey();
- log.info("Removing application " + this.instanceConfig.getAppname()
- + " from eureka");
- DiscoveryManager.getInstance().shutdownComponent();
- }
-
- private void closeDiscoveryClientJersey() {
- log.info("Closing DiscoveryClient.jerseyClient");
- Field jerseyClientField = ReflectionUtils.findField(
- com.netflix.discovery.DiscoveryClient.class, "discoveryJerseyClient",
- EurekaJerseyClient.JerseyClient.class);
- if (jerseyClientField != null) {
- try {
- jerseyClientField.setAccessible(true);
- if (DiscoveryManager.getInstance() != null
- && DiscoveryManager.getInstance().getDiscoveryClient() != null) {
- Object obj = jerseyClientField.get(DiscoveryManager.getInstance()
- .getDiscoveryClient());
- if (obj != null) {
- EurekaJerseyClient.JerseyClient jerseyClient = (EurekaJerseyClient.JerseyClient) obj;
- jerseyClient.destroyResources();
- }
- }
- }
- catch (Exception ex) {
- log.error("Error closing DiscoveryClient.jerseyClient", ex);
- }
- }
- }
-
@Override
public void start() {
// only set the port if the nonSecurePort is 0 and this.port != 0
@@ -126,18 +90,16 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
// only initialize if nonSecurePort is greater than 0 and it isn't already running
// because of containerPortInitializer below
if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
- this.discoveryManagerInitializer.init();
log.info("Registering application " + this.instanceConfig.getAppname()
+ " with eureka with status "
+ this.instanceConfig.getInitialStatus());
- ApplicationInfoManager.getInstance().setInstanceStatus(
+ applicationInfoManager().setInstanceStatus(
this.instanceConfig.getInitialStatus());
if (this.healthCheckHandler != null) {
- DiscoveryManager.getInstance().getDiscoveryClient()
- .registerHealthCheck(this.healthCheckHandler);
+ eurekaClient().registerHealthCheck(this.healthCheckHandler);
}
this.context.publishEvent(new InstanceRegisteredEvent<>(this,
this.instanceConfig));
@@ -149,8 +111,8 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
public void stop() {
log.info("Unregistering application " + this.instanceConfig.getAppname()
+ " with eureka with status DOWN");
- if (ApplicationInfoManager.getInstance().getInfo() != null) {
- ApplicationInfoManager.getInstance().setInstanceStatus(
+ if (applicationInfoManager().getInfo() != null) {
+ applicationInfoManager().setInstanceStatus(
InstanceStatus.DOWN);
}
this.running.set(false);
@@ -182,23 +144,23 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
return this.order;
}
- @Configuration
- protected static class DiscoveryManagerInitializerConfiguration {
-
- @Bean
- @ConditionalOnMissingBean(DiscoveryManagerInitializer.class)
- public DiscoveryManagerInitializer discoveryManagerInitializer() {
- return new DiscoveryManagerInitializer();
- }
-
+ @Bean
+ @ConditionalOnMissingBean(EurekaClient.class)
+ @SneakyThrows
+ public EurekaClient eurekaClient() {
+ return new CloudEurekaClient(applicationInfoManager(), clientConfig, context);
}
@Bean
- @Lazy
- @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
- @ConditionalOnMissingBean(com.netflix.discovery.DiscoveryClient.class)
- public com.netflix.discovery.DiscoveryClient eurekaDiscoveryClient() {
- return DiscoveryManager.getInstance().getDiscoveryClient();
+ @ConditionalOnMissingBean(ApplicationInfoManager.class)
+ public ApplicationInfoManager applicationInfoManager() {
+ return new ApplicationInfoManager(instanceConfig, instanceInfo());
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(InstanceInfo.class)
+ public InstanceInfo instanceInfo() {
+ return new InstanceInfoFactory().create(instanceConfig);
}
@Bean
@@ -231,9 +193,10 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
@Bean
@ConditionalOnMissingBean
public EurekaHealthIndicator eurekaHealthIndicator(
- com.netflix.discovery.DiscoveryClient eurekaDiscoveryClient, EurekaInstanceConfig config) {
+EurekaClient eurekaClient,
+ EurekaInstanceConfig config) {
CompositeMetricReader metrics = new CompositeMetricReader(this.metricReaders.toArray(new MetricReader[0]));
- return new EurekaHealthIndicator(eurekaDiscoveryClient, metrics, config);
+ return new EurekaHealthIndicator(eurekaClient, metrics, config);
}
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java
index 33f38dc9..8c389266 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java
@@ -20,6 +20,7 @@ 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;
@@ -28,7 +29,6 @@ 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.shared.Application;
import com.netflix.discovery.shared.Applications;
@@ -37,7 +37,7 @@ import com.netflix.discovery.shared.Applications;
*/
public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
- private final DiscoveryClient discovery;
+ private final EurekaClient eurekaClient;
private final MetricReader metrics;
@@ -45,10 +45,10 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
private int failCount = 0;
- public EurekaHealthIndicator(DiscoveryClient discovery, MetricReader metrics,
+ public EurekaHealthIndicator(EurekaClient eurekaClient, MetricReader metrics,
EurekaInstanceConfig instanceConfig) {
super();
- this.discovery = discovery;
+ this.eurekaClient = eurekaClient;
this.metrics = metrics;
this.instanceConfig = instanceConfig;
}
@@ -67,7 +67,7 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
}
private Status getStatus(Builder builder) {
- Status status = new Status(this.discovery.getInstanceRemoteStatus().toString(),
+ Status status = new Status(this.eurekaClient.getInstanceRemoteStatus().toString(),
"Remote status from Eureka server");
@SuppressWarnings("unchecked")
Metric value = (Metric) this.metrics
@@ -89,11 +89,11 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
}
private Map getApplications() {
- Applications applications = this.discovery.getApplications();
+ Applications applications = this.eurekaClient.getApplications();
if (applications == null) {
return Collections.emptyMap();
}
- Map result = new HashMap();
+ Map result = new HashMap<>();
for (Application application : applications.getRegisteredApplications()) {
result.put(application.getName(), application.getInstances().size());
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java
index 16533774..743779c2 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java
@@ -80,10 +80,14 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
private long aSGUpdateIntervalMs = 5 * MINUTES;
+ private long aSGCacheExpiryTimeoutMs = 10 * MINUTES; // defaults to longer than the asg update interval
+
private long responseCacheAutoExpirationInSeconds = 180;
private long responseCacheUpdateIntervalMs = 30 * 1000;
+ private boolean useReadOnlyResponseCache = true;
+
private boolean disableDelta;
private long maxIdleThreadInMinutesAgeForStatusReplication = 10;
@@ -132,6 +136,8 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
private int remoteRegionRegistryFetchInterval = 30;
+ private int remoteRegionFetchThreadPoolSize = 20;
+
private String remoteRegionTrustStore = "";
private String remoteRegionTrustStorePassword = "changeit";
@@ -154,6 +160,10 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
private boolean logIdentityHeaders = true;
+ private String listAutoScalingGroupsRoleName = "ListAutoScalingGroups";
+
+ private boolean enableReplicatedRequestCompression = false;
+
@Override
public boolean shouldEnableSelfPreservation() {
return this.enableSelfPreservation;
@@ -205,4 +215,13 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
return this.logIdentityHeaders;
}
+ @Override
+ public boolean shouldUseReadOnlyResponseCache() {
+ return this.useReadOnlyResponseCache;
+ }
+
+ @Override
+ public boolean shouldEnableReplicatedRequestCompression() {
+ return this.enableReplicatedRequestCompression;
+ }
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceIdDataCenterInfo.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceIdDataCenterInfo.java
new file mode 100644
index 00000000..b5003e5f
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceIdDataCenterInfo.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.netflix.appinfo.DataCenterInfo;
+import com.netflix.appinfo.UniqueIdentifier;
+
+/**
+ * @author Spencer Gibb
+ */
+public class InstanceIdDataCenterInfo implements DataCenterInfo,
+ UniqueIdentifier {
+
+ private String instanceId;
+
+ public InstanceIdDataCenterInfo(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+ @Override
+ public Name getName() {
+ return Name.MyOwn;
+ }
+
+ @Override
+ public String getId() {
+ return this.instanceId;
+ }
+
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceInfoFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceInfoFactory.java
new file mode 100644
index 00000000..6b2c26be
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/InstanceInfoFactory.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util.Map;
+
+import lombok.extern.apachecommons.CommonsLog;
+
+import com.netflix.appinfo.EurekaInstanceConfig;
+import com.netflix.appinfo.InstanceInfo;
+import com.netflix.appinfo.LeaseInfo;
+
+/**
+ * See com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider
+ * @author Spencer Gibb
+ */
+@CommonsLog
+public class InstanceInfoFactory {
+
+ public InstanceInfo create(EurekaInstanceConfig config) {
+ LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder()
+ .setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds())
+ .setDurationInSecs(config.getLeaseExpirationDurationInSeconds());
+
+ // Builder the instance information to be registered with eureka
+ // server
+ InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder();
+
+ builder.setNamespace(config.getNamespace())
+ .setAppName(config.getAppname())
+ .setAppGroupName(config.getAppGroupName())
+ .setDataCenterInfo(config.getDataCenterInfo())
+ .setIPAddr(config.getIpAddress())
+ .setHostName(config.getHostName(false))
+ .setPort(config.getNonSecurePort())
+ .enablePort(InstanceInfo.PortType.UNSECURE,
+ config.isNonSecurePortEnabled())
+ .setSecurePort(config.getSecurePort())
+ .enablePort(InstanceInfo.PortType.SECURE, config.getSecurePortEnabled())
+ .setVIPAddress(config.getVirtualHostName())
+ .setSecureVIPAddress(config.getSecureVirtualHostName())
+ .setHomePageUrl(config.getHomePageUrlPath(), config.getHomePageUrl())
+ .setStatusPageUrl(config.getStatusPageUrlPath(),
+ config.getStatusPageUrl())
+ .setHealthCheckUrls(config.getHealthCheckUrlPath(),
+ config.getHealthCheckUrl(), config.getSecureHealthCheckUrl())
+ .setASGName(config.getASGName());
+
+ // Start off with the STARTING state to avoid traffic
+ if (!config.isInstanceEnabledOnit()) {
+ InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.STARTING;
+ log.info("Setting initial instance status as: " + initialStatus);
+ builder.setStatus(initialStatus);
+ }
+ else {
+ log.info("Setting initial instance status as: "
+ + InstanceInfo.InstanceStatus.UP
+ + ". This may be too early for the instance to advertise itself as available. "
+ + "You would instead want to control this via a healthcheck handler.");
+ }
+
+ // Add any user-specific metadata information
+ for (Map.Entry mapEntry : config.getMetadataMap().entrySet()) {
+ String key = mapEntry.getKey();
+ String value = mapEntry.getValue();
+ builder.add(key, value);
+ }
+
+ InstanceInfo instanceInfo = builder.build();
+ instanceInfo.setLeaseInfo(leaseInfoBuilder.build());
+ return instanceInfo;
+ }
+}
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfigurationTests.java
index 5b5f5e02..164b2b1e 100644
--- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfigurationTests.java
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceAutoConfigurationTests.java
@@ -16,6 +16,10 @@
package org.springframework.cloud.netflix.config;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.times;
+
import javax.annotation.PostConstruct;
import org.junit.After;
@@ -31,11 +35,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
-import com.netflix.discovery.DiscoveryClient;
-import com.netflix.discovery.DiscoveryManager;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.BDDMockito.given;
+import com.netflix.discovery.EurekaClient;
/**
* @author Dave Syer
@@ -44,7 +44,7 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
- private DiscoveryClient client = Mockito.mock(DiscoveryClient.class);
+ private EurekaClient client = Mockito.mock(EurekaClient.class);
private InstanceInfo info = InstanceInfo.Builder.newBuilder().setAppName("app")
.setHostName("foo").setHomePageUrl("/", null).build();
@@ -68,21 +68,20 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
1,
this.context
.getBeanNamesForType(DiscoveryClientConfigServiceAutoConfiguration.class).length);
- Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
+ Mockito.verify(this.client, times(2)).getNextServerFromEureka("CONFIGSERVER", false);
Mockito.verify(this.client).shutdown();
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
assertEquals("http://foo:7001/", locator.getRawUri());
- assertEquals("bar", ApplicationInfoManager.getInstance().getInfo().getMetadata()
- .get("foo"));
+ ApplicationInfoManager infoManager = this.context.getBean(ApplicationInfoManager.class);
+ assertEquals("bar", infoManager.getInfo().getMetadata().get("foo"));
}
private void setup(String... env) {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(parent, env);
- parent.getDefaultListableBeanFactory().registerSingleton("mockDiscoveryClient",
+ parent.getDefaultListableBeanFactory().registerSingleton("eurekaClient",
this.client);
- DiscoveryManager.getInstance().setDiscoveryClient(this.client);
parent.register(PropertyPlaceholderAutoConfiguration.class,
DiscoveryClientConfigServiceBootstrapConfiguration.class,
EnvironmentKnobbler.class, ConfigClientProperties.class);
diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java
index a9819837..4581208c 100644
--- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java
+++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java
@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.config;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.BDDMockito.given;
+
import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
@@ -25,11 +28,7 @@ import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.netflix.appinfo.InstanceInfo;
-import com.netflix.discovery.DiscoveryClient;
-import com.netflix.discovery.DiscoveryManager;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.BDDMockito.given;
+import com.netflix.discovery.EurekaClient;
/**
* @author Dave Syer
@@ -38,7 +37,7 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
private AnnotationConfigApplicationContext context;
- private DiscoveryClient client = Mockito.mock(DiscoveryClient.class);
+ private EurekaClient client = Mockito.mock(EurekaClient.class);
private InstanceInfo info = InstanceInfo.Builder.newBuilder().setAppName("app")
.setHostName("foo").setHomePageUrl("/", null).build();
@@ -54,7 +53,7 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
public void offByDefault() throws Exception {
this.context = new AnnotationConfigApplicationContext(
DiscoveryClientConfigServiceBootstrapConfiguration.class);
- assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
+ assertEquals(0, this.context.getBeanNamesForType(EurekaClient.class).length);
assertEquals(
0,
this.context
@@ -104,8 +103,7 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, env);
this.context.getDefaultListableBeanFactory().registerSingleton(
- "mockDiscoveryClient", this.client);
- DiscoveryManager.getInstance().setDiscoveryClient(this.client);
+ "eurekaClient", this.client);
this.context.register(PropertyPlaceholderAutoConfiguration.class,
DiscoveryClientConfigServiceBootstrapConfiguration.class,
ConfigClientProperties.class);
diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java
index 4946a4ed..2d1f5078 100644
--- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java
+++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java
@@ -39,7 +39,7 @@ import com.netflix.appinfo.InstanceInfo;
import com.netflix.config.ConfigurationManager;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Pair;
-import com.netflix.eureka.PeerAwareInstanceRegistry;
+import com.netflix.eureka.PeerAwareInstanceRegistryImpl;
import com.netflix.eureka.cluster.PeerEurekaNode;
import com.netflix.eureka.resources.StatusResource;
import com.netflix.eureka.util.StatusInfo;
@@ -53,6 +53,11 @@ public class EurekaController {
@Value("${eureka.dashboard.path:/}")
private String dashboardPath = "";
+ private ApplicationInfoManager applicationInfoManager;
+
+ public EurekaController(ApplicationInfoManager applicationInfoManager) {
+ this.applicationInfoManager = applicationInfoManager;
+ }
@RequestMapping(method = RequestMethod.GET)
public String status(HttpServletRequest request, Map model) {
@@ -73,7 +78,7 @@ public class EurekaController {
@RequestMapping(value = "/lastn", method = RequestMethod.GET)
public String lastn(HttpServletRequest request, Map model) {
populateBase(request, model);
- PeerAwareInstanceRegistry registery = PeerAwareInstanceRegistry.getInstance();
+ PeerAwareInstanceRegistryImpl registery = PeerAwareInstanceRegistryImpl.getInstance();
ArrayList
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java
index d94b92f1..c854ea33 100644
--- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java
+++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
+import com.netflix.discovery.EurekaClient;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.expression.Expression;
@@ -34,8 +35,6 @@ import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
-import com.netflix.discovery.DiscoveryClient;
-import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.shared.Application;
import com.netflix.turbine.discovery.Instance;
import com.netflix.turbine.discovery.InstanceDiscovery;
@@ -60,13 +59,11 @@ public class EurekaInstanceDiscovery implements InstanceDiscovery {
private static final DynamicStringProperty ApplicationList = DynamicPropertyFactory
.getInstance().getStringProperty("turbine.appConfig", "");
+ private final EurekaClient eurekaClient;
private final Expression clusterNameExpression;
- public EurekaInstanceDiscovery(TurbineProperties turbineProperties) {
- // Eureka client should already be configured by spring-platform-netflix-core
- // initialize eureka client.
- // DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(),
- // new DefaultEurekaClientConfig());
+ public EurekaInstanceDiscovery(TurbineProperties turbineProperties, EurekaClient eurekaClient) {
+ this.eurekaClient = eurekaClient;
SpelExpressionParser parser = new SpelExpressionParser();
this.clusterNameExpression = parser.parseExpression(turbineProperties
.getClusterNameExpression());
@@ -78,7 +75,7 @@ public class EurekaInstanceDiscovery implements InstanceDiscovery {
*/
@Override
public Collection getInstanceList() throws Exception {
- List instances = new ArrayList();
+ List instances = new ArrayList<>();
List appNames = parseApps();
if (appNames == null || appNames.size() == 0) {
log.info("No apps configured, returning an empty instance list");
@@ -111,14 +108,9 @@ public class EurekaInstanceDiscovery implements InstanceDiscovery {
* @throws Exception
*/
private List getInstancesForApp(String appName) throws Exception {
- List instances = new ArrayList();
+ List instances = new ArrayList<>();
log.info("Fetching instances for app: " + appName);
- DiscoveryClient client = DiscoveryManager.getInstance().getDiscoveryClient();
- if (client == null) {
- log.info("Discovery client not ready for: " + appName);
- return instances;
- }
- Application app = client.getApplication(appName);
+ Application app = eurekaClient.getApplication(appName);
if (app == null) {
log.warn("Eureka returned null for app: " + appName);
}
diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java
index 3ae895f2..352fd9a1 100644
--- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java
+++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java
@@ -16,6 +16,8 @@
package org.springframework.cloud.netflix.turbine;
+import com.netflix.discovery.EurekaClient;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@@ -37,6 +39,9 @@ import com.netflix.turbine.streaming.servlet.TurbineStreamServlet;
@EnableDiscoveryClient
public class TurbineConfiguration implements SmartLifecycle, Ordered {
+ @Autowired
+ private EurekaClient eurekaClient;
+
@Bean
public ServletRegistrationBean turbineStreamServlet() {
return new ServletRegistrationBean(new TurbineStreamServlet(), "/turbine.stream");
@@ -49,7 +54,7 @@ public class TurbineConfiguration implements SmartLifecycle, Ordered {
@Bean
public InstanceDiscovery instanceDiscovery() {
- return new EurekaInstanceDiscovery(turbineProperties());
+ return new EurekaInstanceDiscovery(turbineProperties(), eurekaClient);
}
private boolean running;
@@ -66,9 +71,6 @@ public class TurbineConfiguration implements SmartLifecycle, Ordered {
@Override
public void start() {
- // TODO: figure out ordering, so this is already run by
- // EurekaDiscoveryClientConfiguration
- // DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
PluginsFactory.setClusterMonitorFactory(new SpringAggregatorFactory());
PluginsFactory.setInstanceDiscovery(instanceDiscovery());
TurbineInit.init();
diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java
index b4b46033..90b26cd5 100644
--- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java
+++ b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java
@@ -16,6 +16,9 @@
package org.springframework.cloud.netflix.turbine;
+import static org.mockito.Mockito.*;
+
+import com.netflix.discovery.EurekaClient;
import org.junit.Test;
import com.netflix.appinfo.InstanceInfo;
@@ -29,9 +32,10 @@ public class EurekaInstanceDiscoveryTest {
@Test
public void testGetClusterName() {
+ EurekaClient eurekaClient = mock(EurekaClient.class);
String appName = "testAppName";
EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(
- new TurbineProperties());
+ new TurbineProperties(), eurekaClient);
InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder().setAppName(appName)
.build();
String clusterName = discovery.getClusterName(instanceInfo);
@@ -40,9 +44,10 @@ public class EurekaInstanceDiscoveryTest {
@Test
public void testGetClusterNameCustomExpression() {
+ EurekaClient eurekaClient = mock(EurekaClient.class);
TurbineProperties turbineProperties = new TurbineProperties();
turbineProperties.setClusterNameExpression("aSGName");
- EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties);
+ EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, eurekaClient);
String asgName = "myAsgName";
InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder()
.setAppName("testApp").setASGName(asgName).build();
@@ -52,9 +57,10 @@ public class EurekaInstanceDiscoveryTest {
@Test
public void testGetClusterNameInstanceMetadataMapExpression() {
+ EurekaClient eurekaClient = mock(EurekaClient.class);
TurbineProperties turbineProperties = new TurbineProperties();
turbineProperties.setClusterNameExpression("metadata['cluster']");
- EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties);
+ EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, eurekaClient);
String metadataProperty = "myCluster";
InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder()
.setAppName("testApp").add("cluster", metadataProperty).build();