Apply eclipse formatting and cleanup
This commit is contained in:
@@ -1,13 +1,5 @@
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@@ -31,6 +23,14 @@ import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicURLConfiguration;
|
||||
|
||||
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ public class ArchaiusAutoConfiguration {
|
||||
@Bean
|
||||
public ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration() {
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(
|
||||
env);
|
||||
this.env);
|
||||
configureArchaius(envConfig);
|
||||
return envConfig;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class ArchaiusAutoConfiguration {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = env.getProperty("spring.application.name");
|
||||
String appName = this.env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
appName = "application";
|
||||
logger.warn("No spring.application.name found, defaulting to 'application'");
|
||||
|
||||
@@ -26,12 +26,14 @@ import com.netflix.config.ConfigurationManager;
|
||||
*
|
||||
*/
|
||||
public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
|
||||
public static String APPLICATION_CONTEXT = ApplicationContext.class.getName();
|
||||
|
||||
public static <T> T getNamedInstance(Class<T> type, String name) {
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context!=null && context.containsBean(name) ? context.getBean(name, type) : null;
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager
|
||||
.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context != null && context.containsBean(name) ? context
|
||||
.getBean(name, type) : null;
|
||||
}
|
||||
|
||||
public static <T> T getInstanceWithPrefix(Class<T> type, String prefix) {
|
||||
@@ -41,7 +43,7 @@ public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
public static void addApplicationContext(ConfigurableApplicationContext context) {
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
config .clearProperty(APPLICATION_CONTEXT);
|
||||
config.clearProperty(APPLICATION_CONTEXT);
|
||||
config.setProperty(APPLICATION_CONTEXT, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,73 +18,74 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration {
|
||||
ConfigurableEnvironment environment;
|
||||
ConfigurableEnvironment environment;
|
||||
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); //TODO: find a better way to do this
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); // TODO: find a better way to do this
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return environment.containsProperty(key);
|
||||
}
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return this.environment.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return environment.getProperty(key);
|
||||
}
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return this.environment.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources;
|
||||
if (this.environment != null
|
||||
&& this.environment instanceof ConfigurableEnvironment) {
|
||||
sources = this.environment.getPropertySources();
|
||||
}
|
||||
else {
|
||||
sources = new StandardEnvironment().getPropertySources();
|
||||
}
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources;
|
||||
if (this.environment != null
|
||||
&& this.environment instanceof ConfigurableEnvironment) {
|
||||
sources = this.environment.getPropertySources();
|
||||
}
|
||||
else {
|
||||
sources = new StandardEnvironment().getPropertySources();
|
||||
}
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source).getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.netflix.discovery.DiscoveryClient;
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config server via
|
||||
* discovery.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@@ -65,24 +65,24 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
|
||||
log.info("Environment is not ConfigurableEnvironment so cannot look up configserver");
|
||||
return;
|
||||
}
|
||||
InstanceInfo server = client.getNextServerFromEureka(config.getDiscovery()
|
||||
.getServiceId(), false);
|
||||
InstanceInfo server = this.client.getNextServerFromEureka(this.config
|
||||
.getDiscovery().getServiceId(), false);
|
||||
String url = server.getHomePageUrl();
|
||||
if (server.getMetadata().containsKey("password")) {
|
||||
String user = server.getMetadata().get("user");
|
||||
user = user == null ? "user" : user;
|
||||
config.setUsername(user);
|
||||
this.config.setUsername(user);
|
||||
String password = server.getMetadata().get("password");
|
||||
config.setPassword(password);
|
||||
this.config.setPassword(password);
|
||||
}
|
||||
if (server.getMetadata().containsKey("configPath")) {
|
||||
String path = server.getMetadata().get("configPath");
|
||||
if (url.endsWith("/") && path.startsWith("/")) {
|
||||
url = url.substring(0, url.length()-1);
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
url = url + path;
|
||||
}
|
||||
config.setUri(url);
|
||||
this.config.setUri(url);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Could not locate configserver via discovery", e);
|
||||
|
||||
@@ -34,24 +34,25 @@ import com.netflix.discovery.DiscoveryClient;
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass({EurekaInstanceConfigBean.class, DiscoveryClient.class, ConfigServerProperties.class})
|
||||
@ConditionalOnClass({ EurekaInstanceConfigBean.class, DiscoveryClient.class,
|
||||
ConfigServerProperties.class })
|
||||
public class EurekaClientConfigServerAutoConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private EurekaInstanceConfigBean instance;
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private ConfigServerProperties server;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (instance==null || server==null) {
|
||||
if (this.instance == null || this.server == null) {
|
||||
return;
|
||||
}
|
||||
String prefix = server.getPrefix();
|
||||
String prefix = this.server.getPrefix();
|
||||
if (StringUtils.hasText(prefix)) {
|
||||
instance.getMetadataMap().put("configPath", prefix);
|
||||
this.instance.getMetadataMap().put("configPath", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package org.springframework.cloud.netflix.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
@@ -11,66 +15,61 @@ import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* TODO: move to spring-boot?
|
||||
* User: spencergibb
|
||||
* Date: 4/24/14
|
||||
* Time: 9:13 PM
|
||||
* TODO: move to spring-boot? User: spencergibb Date: 4/24/14 Time: 9:13 PM
|
||||
*/
|
||||
public abstract class ServletWrappingEndpoint implements InitializingBean,
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
|
||||
protected String path;
|
||||
protected boolean sensitive;
|
||||
protected boolean enabled = true;
|
||||
protected String path;
|
||||
protected boolean sensitive;
|
||||
protected boolean enabled = true;
|
||||
|
||||
protected final ServletWrappingController controller = new ServletWrappingController();
|
||||
protected final ServletWrappingController controller = new ServletWrappingController();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName, String path,
|
||||
boolean sensitive, boolean enabled) {
|
||||
controller.setServletClass(servletClass);
|
||||
controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName,
|
||||
String path, boolean sensitive, boolean enabled) {
|
||||
this.controller.setServletClass(servletClass);
|
||||
this.controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return sensitive;
|
||||
}
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return this.sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHeartbeatEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.DataCenterInfo.Name;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
@@ -23,17 +31,15 @@ import com.netflix.discovery.converters.Converters.ApplicationsConverter;
|
||||
import com.netflix.discovery.converters.Converters.InstanceInfoConverter;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.thoughtworks.xstream.MarshallingStrategy;
|
||||
import com.thoughtworks.xstream.converters.*;
|
||||
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;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHeartbeatEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* A special purpose wrapper for an XStream TreeMarshallingStrategy that is aware of the
|
||||
@@ -44,7 +50,7 @@ import org.springframework.context.ApplicationContext;
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
@@ -60,15 +66,17 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
@Override
|
||||
public Object unmarshal(Object root, HierarchicalStreamReader reader,
|
||||
DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) {
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup, context);
|
||||
return delegate.unmarshal(root, reader, dataHolder, wrapped, mapper);
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
|
||||
this.context);
|
||||
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, context);
|
||||
delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
|
||||
this.context);
|
||||
this.delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
|
||||
}
|
||||
|
||||
public static class InstanceIdDataCenterInfo implements DataCenterInfo,
|
||||
@@ -87,7 +95,7 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return instanceId;
|
||||
return this.instanceId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -97,18 +105,20 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
private ConverterLookup delegate;
|
||||
private ApplicationContext context;
|
||||
|
||||
public DataCenterAwareConverterLookup(ConverterLookup delegate, ApplicationContext context) {
|
||||
public DataCenterAwareConverterLookup(ConverterLookup delegate,
|
||||
ApplicationContext context) {
|
||||
this.delegate = delegate;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter lookupConverterForType(@SuppressWarnings("rawtypes") Class type) {
|
||||
Converter converter = delegate.lookupConverterForType(type);
|
||||
Converter converter = this.delegate.lookupConverterForType(type);
|
||||
if (InstanceInfo.class == type) {
|
||||
return new DataCenterAwareConverter();
|
||||
} else if (Applications.class == type) {
|
||||
return new PublishingApplicationsConverter(context);
|
||||
}
|
||||
else if (Applications.class == type) {
|
||||
return new PublishingApplicationsConverter(this.context);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
@@ -124,7 +134,8 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
|
||||
public Object unmarshal(HierarchicalStreamReader reader,
|
||||
UnmarshallingContext unmarshallingContext) {
|
||||
Object obj = super.unmarshal(reader, unmarshallingContext);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(obj);
|
||||
@@ -147,14 +158,15 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
if ("setVersion".equals(invocation.getMethod().getName())) {
|
||||
Long version = Long.class.cast(invocation.getArguments()[0]);
|
||||
log.debug("Applications.setVersion() called with version: " + version);
|
||||
context.publishEvent(new DiscoveryHeartbeatEvent(invocation.getThis(), version));
|
||||
this.context.publishEvent(new DiscoveryHeartbeatEvent(invocation
|
||||
.getThis(), version));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataCenterAwareConverter extends InstanceInfoConverter {
|
||||
|
||||
|
||||
@Override
|
||||
public void marshal(Object source, HierarchicalStreamWriter writer,
|
||||
MarshallingContext context) {
|
||||
|
||||
@@ -11,16 +11,16 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
*/
|
||||
public class DiscoveryManagerInitializer {
|
||||
|
||||
@Autowired
|
||||
private EurekaClientConfig clientConfig;
|
||||
@Autowired
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
@Autowired
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
|
||||
|
||||
public synchronized void init() {
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
|
||||
DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
|
||||
}
|
||||
}
|
||||
public synchronized void init() {
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
|
||||
DiscoveryManager.getInstance().initComponent(this.instanceConfig,
|
||||
this.clientConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
* it is Eureka you want. All it does is turn on discovery and let the autoconfiguration
|
||||
* find the eureka classes if they are available (i.e. you need Eureka on the classpath as
|
||||
* well).
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -47,9 +47,9 @@ public class EurekaClientAutoConfiguration {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
XmlXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(context));
|
||||
new DataCenterAwareMarshallingStrategy(this.context));
|
||||
JsonXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(context));
|
||||
new DataCenterAwareMarshallingStrategy(this.context));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -64,5 +64,4 @@ public class EurekaClientAutoConfiguration {
|
||||
return new EurekaInstanceConfigBean();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -35,12 +35,13 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
@ConfigurationProperties("eureka.client")
|
||||
public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + EurekaServerConfigBean.DEFAULT_PREFIX + "/";
|
||||
public static final String DEFAULT_URL = "http://localhost:8761"
|
||||
+ EurekaServerConfigBean.DEFAULT_PREFIX + "/";
|
||||
|
||||
public static final String DEFAULT_ZONE = "defaultZone";
|
||||
|
||||
|
||||
private static final int MINUTES = 60;
|
||||
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private int registryFetchIntervalSeconds = 30;
|
||||
@@ -55,9 +56,9 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private String proxyHost;
|
||||
|
||||
private String proxyUserName;
|
||||
private String proxyUserName;
|
||||
|
||||
private String proxyPassword;
|
||||
private String proxyPassword;
|
||||
|
||||
private int eurekaServerReadTimeoutSeconds = 8;
|
||||
|
||||
@@ -83,16 +84,16 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private int heartbeatExecutorThreadPoolSize = 2;
|
||||
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private int cacheRefreshExecutorThreadPoolSize = 2;
|
||||
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private Map<String, String> serviceUrl = new HashMap<String, String>();
|
||||
|
||||
private Map<String,String> serviceUrl = new HashMap<String, String>();
|
||||
|
||||
{
|
||||
serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
}
|
||||
|
||||
private boolean gZipContent = true;
|
||||
@@ -117,43 +118,43 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return gZipContent;
|
||||
return this.gZipContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseDnsForFetchingServiceUrls() {
|
||||
return useDnsForFetchingServiceUrls;
|
||||
return this.useDnsForFetchingServiceUrls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegisterWithEureka() {
|
||||
return registerWithEureka;
|
||||
return this.registerWithEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPreferSameZoneEureka() {
|
||||
return preferSameZoneEureka;
|
||||
return this.preferSameZoneEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogDeltaDiff() {
|
||||
return logDeltaDiff;
|
||||
return this.logDeltaDiff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return disableDelta;
|
||||
return this.disableDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetchRegistryForRemoteRegions() {
|
||||
return fetchRemoteRegionsRegistry;
|
||||
return this.fetchRemoteRegionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailabilityZones(String region) {
|
||||
String value = availabilityZones.get(region);
|
||||
if (value==null) {
|
||||
String value = this.availabilityZones.get(region);
|
||||
if (value == null) {
|
||||
value = DEFAULT_ZONE;
|
||||
}
|
||||
return value.split(",");
|
||||
@@ -161,25 +162,25 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
@Override
|
||||
public List<String> getEurekaServerServiceUrls(String myZone) {
|
||||
String serviceUrls = serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = serviceUrl.get(DEFAULT_ZONE);
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
String serviceUrls = this.serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilterOnlyUpInstances() {
|
||||
return filterOnlyUpInstances;
|
||||
return this.filterOnlyUpInstances;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFetchRegistry() {
|
||||
return fetchRegistry;
|
||||
return this.fetchRegistry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -24,10 +28,10 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
public static final String DESCRIPTION = "Spring Cloud Eureka Discovery Client";
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean config;
|
||||
private EurekaInstanceConfigBean config;
|
||||
|
||||
@Autowired
|
||||
private com.netflix.discovery.DiscoveryClient discovery;
|
||||
@Autowired
|
||||
private com.netflix.discovery.DiscoveryClient discovery;
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
@@ -35,96 +39,103 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
return new ServiceInstance() {
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return config.getAppname();
|
||||
}
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
return new ServiceInstance() {
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return EurekaDiscoveryClient.this.config.getAppname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return config.getHostname();
|
||||
}
|
||||
@Override
|
||||
public String getHost() {
|
||||
return EurekaDiscoveryClient.this.config.getHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return config.getNonSecurePort();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public int getPort() {
|
||||
return EurekaDiscoveryClient.this.config.getNonSecurePort();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = discovery.getInstancesByVipAddress(serviceId, false);
|
||||
Iterable<ServiceInstance> instances = transform(infos, new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = this.discovery.getInstancesByVipAddress(serviceId,
|
||||
false);
|
||||
Iterable<ServiceInstance> instances = transform(infos,
|
||||
new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
|
||||
static class EurekaServiceInstance implements ServiceInstance {
|
||||
InstanceInfo instance;
|
||||
static class EurekaServiceInstance implements ServiceInstance {
|
||||
InstanceInfo instance;
|
||||
|
||||
EurekaServiceInstance(InstanceInfo instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
EurekaServiceInstance(InstanceInfo instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return instance.getAppName();
|
||||
}
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return this.instance.getAppName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return instance.getHostName();
|
||||
}
|
||||
@Override
|
||||
public String getHost() {
|
||||
return this.instance.getHostName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return instance.getPort();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int getPort() {
|
||||
return this.instance.getPort();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Lists.newArrayList(filter(transform(applications.getRegisteredApplications(), new Function<Application, String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable Application app) {
|
||||
if (app.getInstances().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return app.getName().toLowerCase();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Lists.newArrayList(filter(
|
||||
transform(applications.getRegisteredApplications(),
|
||||
new Function<Application, String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable Application app) {
|
||||
if (app.getInstances().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return app.getName().toLowerCase();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getAllInstances() {
|
||||
Applications applications = discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Iterable<ServiceInstance> instances = transform(concat(transform(applications.getRegisteredApplications(), new Function<Application, List<InstanceInfo>>() {
|
||||
public List<InstanceInfo> apply(@Nullable Application app) {
|
||||
return app.getInstances();
|
||||
}
|
||||
})), new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
@Override
|
||||
public List<ServiceInstance> getAllInstances() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Iterable<ServiceInstance> instances = transform(
|
||||
concat(transform(applications.getRegisteredApplications(),
|
||||
new Function<Application, List<InstanceInfo>>() {
|
||||
@Override
|
||||
public List<InstanceInfo> apply(@Nullable Application app) {
|
||||
return app.getInstances();
|
||||
}
|
||||
})), new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,8 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
closeDiscoveryClientJersey();
|
||||
logger.info("Removing application {} from eureka", instanceConfig.getAppname());
|
||||
logger.info("Removing application {} from eureka",
|
||||
this.instanceConfig.getAppname());
|
||||
DiscoveryManager.getInstance().shutdownComponent();
|
||||
}
|
||||
|
||||
@@ -112,25 +113,27 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
@Override
|
||||
public void start() {
|
||||
// only set the port if the nonSecurePort is 0 and this.port != 0
|
||||
if (port.get() != 0 && instanceConfig.getNonSecurePort() == 0) {
|
||||
instanceConfig.setNonSecurePort(port.get());
|
||||
if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
|
||||
this.instanceConfig.setNonSecurePort(this.port.get());
|
||||
}
|
||||
// only initialize if nonSecurePort is greater than 0 and it isn't already running
|
||||
// because of containerPortInitializer below
|
||||
if (!running.get() && instanceConfig.getNonSecurePort() > 0) {
|
||||
if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
|
||||
discoveryManagerIntitializer().init();
|
||||
|
||||
logger.info("Registering application {} with eureka with status {}",
|
||||
instanceConfig.getAppname(), instanceConfig.getInitialStatus());
|
||||
this.instanceConfig.getAppname(),
|
||||
this.instanceConfig.getInitialStatus());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(
|
||||
instanceConfig.getInitialStatus());
|
||||
this.instanceConfig.getInitialStatus());
|
||||
|
||||
if (healthCheckHandler != null) {
|
||||
if (this.healthCheckHandler != null) {
|
||||
DiscoveryManager.getInstance().getDiscoveryClient()
|
||||
.registerHealthCheck(healthCheckHandler);
|
||||
.registerHealthCheck(this.healthCheckHandler);
|
||||
}
|
||||
context.publishEvent(new InstanceRegisteredEvent<>(this, instanceConfig));
|
||||
running.set(true);
|
||||
this.context.publishEvent(new InstanceRegisteredEvent<>(this,
|
||||
this.instanceConfig));
|
||||
this.running.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,15 +141,15 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
public void stop() {
|
||||
logger.info(
|
||||
"Unregistering application {} with eureka with status OUT_OF_SERVICE",
|
||||
instanceConfig.getAppname());
|
||||
this.instanceConfig.getAppname());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(
|
||||
InstanceStatus.OUT_OF_SERVICE);
|
||||
running.set(false);
|
||||
this.running.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return running.get();
|
||||
return this.running.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,7 +169,7 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -24,12 +24,12 @@ 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.DiscoveryHealthIndicator;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHealthIndicator;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -67,28 +67,29 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
}
|
||||
|
||||
private Status getStatus(Builder builder) {
|
||||
Status status = new Status(discovery.getInstanceRemoteStatus().toString(),
|
||||
Status status = new Status(this.discovery.getInstanceRemoteStatus().toString(),
|
||||
"Remote status from Eureka server");
|
||||
@SuppressWarnings("unchecked")
|
||||
Metric<Number> value = (Metric<Number>) metrics
|
||||
Metric<Number> value = (Metric<Number>) this.metrics
|
||||
.findOne("counter.servo.discoveryclient_failed");
|
||||
if (value != null) {
|
||||
int renewalPeriod = instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int renewalPeriod = this.instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int latest = value.getValue().intValue();
|
||||
builder.withDetail("failCount", latest);
|
||||
builder.withDetail("renewalPeriod", renewalPeriod);
|
||||
if (failCount < latest) {
|
||||
if (this.failCount < latest) {
|
||||
status = new Status("UP", "Eureka discovery client is reporting failures");
|
||||
failCount = latest;
|
||||
} else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
this.failCount = latest;
|
||||
}
|
||||
else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private Map<String, Object> getApplications() {
|
||||
Applications applications = discovery.getApplications();
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@@ -42,99 +42,104 @@ import com.netflix.appinfo.UniqueIdentifier;
|
||||
@Data
|
||||
@ConfigurationProperties("eureka.instance")
|
||||
public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(EurekaInstanceConfigBean.class);
|
||||
|
||||
@Getter(AccessLevel.PRIVATE) @Setter(AccessLevel.PRIVATE)
|
||||
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
@Setter(AccessLevel.PRIVATE)
|
||||
private String[] hostInfo = initHostInfo();
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appname = "unknown";
|
||||
private String appname = "unknown";
|
||||
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
private int nonSecurePort = 80;
|
||||
private int nonSecurePort = 80;
|
||||
|
||||
private int securePort = 443;
|
||||
private int securePort = 443;
|
||||
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
|
||||
private boolean securePortEnabled;
|
||||
private boolean securePortEnabled;
|
||||
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String virtualHostName;
|
||||
private String virtualHostName;
|
||||
|
||||
private String secureVirtualHostName;
|
||||
private String secureVirtualHostName;
|
||||
|
||||
private String aSGName;
|
||||
private String aSGName;
|
||||
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
|
||||
private String ipAddress = hostInfo[0];
|
||||
private String ipAddress = this.hostInfo[0];
|
||||
|
||||
private String statusPageUrlPath = "/info";
|
||||
private String statusPageUrlPath = "/info";
|
||||
|
||||
private String statusPageUrl;
|
||||
private String statusPageUrl;
|
||||
|
||||
private String homePageUrlPath = "/";
|
||||
private String homePageUrlPath = "/";
|
||||
|
||||
private String homePageUrl;
|
||||
private String homePageUrl;
|
||||
|
||||
private String healthCheckUrlPath = "/health";
|
||||
private String healthCheckUrlPath = "/health";
|
||||
|
||||
private String healthCheckUrl;
|
||||
private String healthCheckUrl;
|
||||
|
||||
private String secureHealthCheckUrl;
|
||||
private String secureHealthCheckUrl;
|
||||
|
||||
private String namespace = "eureka";
|
||||
private String namespace = "eureka";
|
||||
|
||||
private String hostname = this.hostInfo[1];
|
||||
|
||||
private String hostname = hostInfo[1];
|
||||
|
||||
private boolean preferIpAddress = false;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
public String getHostname() {
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecurePortEnabled() {
|
||||
return securePortEnabled;
|
||||
return this.securePortEnabled;
|
||||
}
|
||||
|
||||
private String[] initHostInfo() {
|
||||
String[] info = new String[2];
|
||||
try {
|
||||
info[0] = InetAddress.getLocalHost().getHostAddress();
|
||||
info[1] = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error("Cannot get host info", e);
|
||||
}
|
||||
return info ;
|
||||
info[1] = InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
logger.error("Cannot get host info", e);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostName(boolean refresh) {
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
}
|
||||
|
||||
private final class IdentifyingDataCenterInfo implements DataCenterInfo, UniqueIdentifier {
|
||||
@Getter @Setter
|
||||
private Name name = Name.MyOwn;
|
||||
|
||||
private final class IdentifyingDataCenterInfo implements DataCenterInfo,
|
||||
UniqueIdentifier {
|
||||
@Getter
|
||||
@Setter
|
||||
private Name name = Name.MyOwn;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
String instanceId = metadataMap.get("instanceId");
|
||||
String instanceId = EurekaInstanceConfigBean.this.metadataMap
|
||||
.get("instanceId");
|
||||
if (instanceId != null) {
|
||||
String old = getHostname();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
@@ -142,7 +147,7 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
}
|
||||
return getHostname();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import com.netflix.eureka.EurekaServerConfig;
|
||||
|
||||
/**
|
||||
@@ -46,10 +46,11 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int eIPBindingRetryIntervalMs = 5 * MINUTES;
|
||||
|
||||
private boolean enableSelfPreservation = true;
|
||||
private boolean enableSelfPreservation = true;
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableSelfPreservation() {
|
||||
return enableSelfPreservation;
|
||||
return this.enableSelfPreservation;
|
||||
}
|
||||
|
||||
private double renewalPercentThreshold = 0.85;
|
||||
@@ -88,10 +89,11 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private long responseCacheUpdateIntervalMs = 30 * 1000;
|
||||
|
||||
private boolean disableDelta;
|
||||
private boolean disableDelta;
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return disableDelta;
|
||||
return this.disableDelta;
|
||||
}
|
||||
|
||||
private long maxIdleThreadInMinutesAgeForStatusReplication = 10;
|
||||
@@ -102,10 +104,11 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxElementsInStatusReplicationPool = 10000;
|
||||
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
|
||||
@Override
|
||||
public boolean shouldSyncWhenTimestampDiffers() {
|
||||
return syncWhenTimestampDiffers;
|
||||
return this.syncWhenTimestampDiffers;
|
||||
}
|
||||
|
||||
private int registrySyncRetries = 5;
|
||||
@@ -120,16 +123,18 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxTimeForReplication = 30000;
|
||||
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
|
||||
@Override
|
||||
public boolean shouldPrimeAwsReplicaConnections() {
|
||||
return primeAwsReplicaConnections;
|
||||
return this.primeAwsReplicaConnections;
|
||||
}
|
||||
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDeltaForRemoteRegions() {
|
||||
return disableDeltaForRemoteRegions;
|
||||
return this.disableDeltaForRemoteRegions;
|
||||
}
|
||||
|
||||
private int remoteRegionConnectTimeoutMs = 1000;
|
||||
@@ -142,25 +147,28 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int remoteRegionConnectionIdleTimeoutSeconds = 30;
|
||||
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContentFromRemoteRegion() {
|
||||
return gZipContentFromRemoteRegion;
|
||||
return this.gZipContentFromRemoteRegion;
|
||||
}
|
||||
|
||||
private Map<String, String> remoteRegionUrlsWithName = new HashMap<String, String>();
|
||||
|
||||
private String[] remoteRegionUrls;
|
||||
private String[] remoteRegionUrls;
|
||||
|
||||
private Map<String, Set<String>> remoteRegionAppWhitelist;
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public Set<String> getRemoteRegionAppWhitelist(String regionName) {
|
||||
if (null == regionName) {
|
||||
regionName = "global";
|
||||
} else {
|
||||
regionName = regionName.trim().toLowerCase();
|
||||
}
|
||||
return remoteRegionAppWhitelist.get(regionName);
|
||||
if (null == regionName) {
|
||||
regionName = "global";
|
||||
}
|
||||
else {
|
||||
regionName = regionName.trim().toLowerCase();
|
||||
}
|
||||
return this.remoteRegionAppWhitelist.get(regionName);
|
||||
}
|
||||
|
||||
private int remoteRegionRegistryFetchInterval = 30;
|
||||
@@ -170,34 +178,35 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
private String remoteRegionTrustStorePassword = "changeit";
|
||||
|
||||
private boolean disableTransparentFallbackToOtherRegion;
|
||||
|
||||
@Override
|
||||
public boolean disableTransparentFallbackToOtherRegion() {
|
||||
return disableTransparentFallbackToOtherRegion;
|
||||
return this.disableTransparentFallbackToOtherRegion;
|
||||
}
|
||||
|
||||
private boolean batchReplication;
|
||||
private boolean batchReplication;
|
||||
|
||||
@Override
|
||||
public boolean shouldBatchReplication() {
|
||||
return batchReplication;
|
||||
return this.batchReplication;
|
||||
}
|
||||
|
||||
private boolean logIdentityHeaders = true;
|
||||
private boolean logIdentityHeaders = true;
|
||||
|
||||
@Override
|
||||
public boolean shouldLogIdentityHeaders() {
|
||||
return logIdentityHeaders;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldLogIdentityHeaders() {
|
||||
return this.logIdentityHeaders;
|
||||
}
|
||||
|
||||
private boolean rateLimiterEnabled = false;
|
||||
private boolean rateLimiterEnabled = false;
|
||||
|
||||
private boolean rateLimiterThrottleStandardClients = false;
|
||||
private boolean rateLimiterThrottleStandardClients = false;
|
||||
|
||||
private Set<String> rateLimiterPrivilegedClients = Collections.emptySet();
|
||||
private Set<String> rateLimiterPrivilegedClients = Collections.emptySet();
|
||||
|
||||
private int rateLimiterBurstSize = 10;
|
||||
private int rateLimiterBurstSize = 10;
|
||||
|
||||
private int rateLimiterRegistryFetchAverageRate = 500;
|
||||
private int rateLimiterRegistryFetchAverageRate = 500;
|
||||
|
||||
private int rateLimiterFullFetchAverageRate = 100;
|
||||
private int rateLimiterFullFetchAverageRate = 100;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Julien Roy
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -10,9 +14,10 @@ import java.lang.annotation.*;
|
||||
@Documented
|
||||
public @interface FeignClient {
|
||||
/**
|
||||
* @return serviceId if loadbalance is true, url otherwise
|
||||
* No need to prefix serviceId with http://
|
||||
* @return serviceId if loadbalance is true, url otherwise No need to prefix serviceId
|
||||
* with http://
|
||||
*/
|
||||
String value();
|
||||
|
||||
boolean loadbalance() default true;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ import lombok.EqualsAndHashCode;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
class FeignClientFactoryBean extends FeignConfiguration implements FactoryBean<Object> {
|
||||
|
||||
private boolean loadbalance;
|
||||
@@ -18,18 +18,18 @@ class FeignClientFactoryBean extends FeignConfiguration implements FactoryBean<O
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
if (!schemeName.startsWith("http")) {
|
||||
schemeName = "http://"+schemeName;
|
||||
if (!this.schemeName.startsWith("http")) {
|
||||
this.schemeName = "http://" + this.schemeName;
|
||||
}
|
||||
if (loadbalance) {
|
||||
return loadBalance(type, schemeName);
|
||||
if (this.loadbalance) {
|
||||
return loadBalance(this.type, this.schemeName);
|
||||
}
|
||||
return feign().target(type, schemeName);
|
||||
return feign().target(this.type, this.schemeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,8 +9,9 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Configures component scanning directives for use with @{@link org.springframework.context.annotation.Configuration} classes.
|
||||
* Scan Spring Integration specific components.
|
||||
* Configures component scanning directives for use with @
|
||||
* {@link org.springframework.context.annotation.Configuration} classes. Scan Spring
|
||||
* Integration specific components.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.0
|
||||
@@ -22,9 +23,8 @@ import org.springframework.context.annotation.Import;
|
||||
public @interface FeignClientScan {
|
||||
|
||||
/**
|
||||
* Alias for the {@link #basePackages()} attribute.
|
||||
* Allows for more concise annotation declarations e.g.:
|
||||
* {@code @ComponentScan("org.my.pkg")} instead of
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||
* declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
|
||||
* {@code @ComponentScan(basePackages="org.my.pkg")}.
|
||||
*
|
||||
* @return the array of 'basePackages'.
|
||||
@@ -33,18 +33,22 @@ public @interface FeignClientScan {
|
||||
|
||||
/**
|
||||
* Base packages to scan for annotated components.
|
||||
* <p>{@link #value()} is an alias for (and mutually exclusive with) this attribute.
|
||||
* <p>Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
|
||||
* <p>
|
||||
* {@link #value()} is an alias for (and mutually exclusive with) this attribute.
|
||||
* <p>
|
||||
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
|
||||
* package names.
|
||||
*
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] basePackages() default {};
|
||||
|
||||
/**
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages
|
||||
* to scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>Consider creating a special no-op marker class or interface in each package
|
||||
* that serves no purpose other than being referenced by this attribute.
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
|
||||
* scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>
|
||||
* Consider creating a special no-op marker class or interface in each package that
|
||||
* serves no purpose other than being referenced by this attribute.
|
||||
*
|
||||
* @return the array of 'basePackageClasses'.
|
||||
*/
|
||||
|
||||
@@ -23,11 +23,11 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* patterned after Spring Integration IntegrationComponentScanRegistrar
|
||||
* @author Spencer Gibb patterned after Spring Integration
|
||||
* IntegrationComponentScanRegistrar
|
||||
*/
|
||||
public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {
|
||||
public class FeignClientScanRegistrar extends FeignConfiguration implements
|
||||
ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@@ -47,22 +47,25 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Set<String> basePackages = getBasePackages(importingClassMetadata);
|
||||
|
||||
ClassPathScanningCandidateComponentProvider scanner = getScanner();
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
|
||||
scanner.setResourceLoader(resourceLoader);
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
|
||||
for (String basePackage : basePackages) {
|
||||
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
|
||||
Set<BeanDefinition> candidateComponents = scanner
|
||||
.findCandidateComponents(basePackage);
|
||||
for (BeanDefinition candidateComponent : candidateComponents) {
|
||||
if (candidateComponent instanceof AnnotatedBeanDefinition) {
|
||||
//verify annotated class is an interface
|
||||
// verify annotated class is an interface
|
||||
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
|
||||
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
|
||||
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
|
||||
Assert.isTrue(annotationMetadata.isInterface(),
|
||||
"@FeignClient can only be specified on an interface");
|
||||
|
||||
BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
|
||||
@@ -72,42 +75,49 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder createBeanDefinition(AnnotationMetadata annotationMetadata) {
|
||||
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
Map<String, Object> attributes = annotationMetadata
|
||||
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
|
||||
String className = annotationMetadata.getClassName();
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
definition.addPropertyValue("loadbalance", attributes.get("loadbalance"));
|
||||
definition.addPropertyValue("type", className);
|
||||
definition.addPropertyValue("schemeName", attributes.get("value"));
|
||||
|
||||
String beanName = StringUtils.uncapitalize(className.substring(className.lastIndexOf(".") + 1));
|
||||
String beanName = StringUtils.uncapitalize(className.substring(className
|
||||
.lastIndexOf(".") + 1));
|
||||
return new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
|
||||
}
|
||||
|
||||
protected ClassPathScanningCandidateComponentProvider getScanner() {
|
||||
return new ClassPathScanningCandidateComponentProvider(false) {
|
||||
|
||||
@Override
|
||||
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.getMetadata().isIndependent()) {
|
||||
// TODO until SPR-11711 will be resolved
|
||||
if (beanDefinition.getMetadata().isInterface() &&
|
||||
beanDefinition.getMetadata().getInterfaceNames().length == 1 &&
|
||||
Annotation.class.getName().equals(beanDefinition.getMetadata().getInterfaceNames()[0])) {
|
||||
try {
|
||||
Class<?> target = ClassUtils.forName(beanDefinition.getMetadata().getClassName(), classLoader);
|
||||
return !target.isAnnotation();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Could not load target class: " + beanDefinition.getMetadata().getClassName(), e);
|
||||
|
||||
}
|
||||
@Override
|
||||
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.getMetadata().isIndependent()) {
|
||||
// TODO until SPR-11711 will be resolved
|
||||
if (beanDefinition.getMetadata().isInterface()
|
||||
&& beanDefinition.getMetadata().getInterfaceNames().length == 1
|
||||
&& Annotation.class.getName().equals(
|
||||
beanDefinition.getMetadata().getInterfaceNames()[0])) {
|
||||
try {
|
||||
Class<?> target = ClassUtils.forName(beanDefinition
|
||||
.getMetadata().getClassName(),
|
||||
FeignClientScanRegistrar.this.classLoader);
|
||||
return !target.isAnnotation();
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.logger.error("Could not load target class: "
|
||||
+ beanDefinition.getMetadata().getClassName(), e);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
|
||||
@@ -130,7 +140,8 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
if (basePackages.isEmpty()) {
|
||||
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
|
||||
basePackages.add(ClassUtils.getPackageName(importingClassMetadata
|
||||
.getClassName()));
|
||||
}
|
||||
return basePackages;
|
||||
}
|
||||
|
||||
@@ -20,20 +20,20 @@ import feign.ribbon.LoadBalancingTarget;
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignConfiguration {
|
||||
@Autowired
|
||||
ConfigurableEnvironmentConfiguration envConfig; //FIXME: howto enforce this?
|
||||
@Autowired
|
||||
ConfigurableEnvironmentConfiguration envConfig; // FIXME: howto enforce this?
|
||||
|
||||
@Autowired
|
||||
Decoder decoder;
|
||||
@Autowired
|
||||
Decoder decoder;
|
||||
|
||||
@Autowired
|
||||
Encoder encoder;
|
||||
@Autowired
|
||||
Encoder encoder;
|
||||
|
||||
@Autowired
|
||||
Logger logger;
|
||||
@Autowired
|
||||
Logger logger;
|
||||
|
||||
@Autowired
|
||||
Contract contract;
|
||||
@Autowired
|
||||
Contract contract;
|
||||
|
||||
@Autowired(required = false)
|
||||
Logger.Level logLevel;
|
||||
@@ -47,40 +47,43 @@ public class FeignConfiguration {
|
||||
@Autowired(required = false)
|
||||
Request.Options options;
|
||||
|
||||
@Autowired(required = false)
|
||||
Client ribbonClient;
|
||||
@Autowired(required = false)
|
||||
Client ribbonClient;
|
||||
|
||||
protected Feign.Builder feign() {
|
||||
protected Feign.Builder feign() {
|
||||
Feign.Builder builder = Feign.builder()
|
||||
//required values
|
||||
.logger(logger)
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(contract);
|
||||
// required values
|
||||
.logger(this.logger).encoder(this.encoder).decoder(this.decoder)
|
||||
.contract(this.contract);
|
||||
|
||||
//optional values
|
||||
if (logLevel != null)
|
||||
builder.logLevel(logLevel);
|
||||
if (retryer != null)
|
||||
builder.retryer(retryer);
|
||||
if (errorDecoder != null)
|
||||
builder.errorDecoder(errorDecoder);
|
||||
if (options != null)
|
||||
builder.options(options);
|
||||
// optional values
|
||||
if (this.logLevel != null) {
|
||||
builder.logLevel(this.logLevel);
|
||||
}
|
||||
if (this.retryer != null) {
|
||||
builder.retryer(this.retryer);
|
||||
}
|
||||
if (this.errorDecoder != null) {
|
||||
builder.errorDecoder(this.errorDecoder);
|
||||
}
|
||||
if (this.options != null) {
|
||||
builder.options(this.options);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Class<T> type, String schemeName) {
|
||||
return loadBalance(feign(), type, schemeName);
|
||||
}
|
||||
protected <T> T loadBalance(Class<T> type, String schemeName) {
|
||||
return loadBalance(feign(), type, schemeName);
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
if(ribbonClient != null) {
|
||||
return builder.client(ribbonClient).target(type, schemeName);
|
||||
} else {
|
||||
return builder.target(LoadBalancingTarget.create(type, schemeName));
|
||||
}
|
||||
}
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
if (this.ribbonClient != null) {
|
||||
return builder.client(this.ribbonClient).target(type, schemeName);
|
||||
}
|
||||
else {
|
||||
return builder.target(LoadBalancingTarget.create(type, schemeName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignUtils {
|
||||
static HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
static HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -17,8 +19,6 @@ import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
|
||||
/**
|
||||
@@ -26,25 +26,27 @@ import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
*/
|
||||
public class SpringDecoder implements Decoder {
|
||||
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringDecoder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException, FeignException {
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
FeignException {
|
||||
if (type instanceof Class || type instanceof ParameterizedType) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, messageConverters.get().getConverters());
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, this.messageConverters.get().getConverters());
|
||||
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException("type is not an instance of Class or ParameterizedType: " + type);
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException(
|
||||
"type is not an instance of Class or ParameterizedType: " + type);
|
||||
}
|
||||
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
private final Response response;
|
||||
|
||||
private FeignResponseAdapter(Response response) {
|
||||
@@ -53,23 +55,23 @@ public class SpringDecoder implements Decoder {
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(response.status());
|
||||
return HttpStatus.valueOf(this.response.status());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return response.status();
|
||||
return this.response.status();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return response.reason();
|
||||
return this.response.reason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
response.body().close();
|
||||
this.response.body().close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -78,12 +80,12 @@ public class SpringDecoder implements Decoder {
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return response.body().asInputStream();
|
||||
return this.response.body().asInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(response.headers());
|
||||
return getHttpHeaders(this.response.headers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,11 +16,11 @@ import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
|
||||
@@ -29,8 +30,8 @@ import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
public class SpringEncoder implements Encoder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringEncoder.class);
|
||||
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringEncoder() {
|
||||
}
|
||||
@@ -49,7 +50,8 @@ public class SpringEncoder implements Encoder {
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : messageConverters.get().getConverters()) {
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters.get()
|
||||
.getConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (requestContentType != null) {
|
||||
@@ -97,16 +99,16 @@ public class SpringEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
return outputStream;
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(request.headers());
|
||||
return getHttpHeaders(this.request.headers());
|
||||
}
|
||||
|
||||
public ByteArrayOutputStream getOutputStream() {
|
||||
return outputStream;
|
||||
return this.outputStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
@@ -12,128 +9,151 @@ import java.util.Map;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.MethodMetadata;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract {
|
||||
static final String ACCEPT = "Accept";
|
||||
static final String CONTENT_TYPE = "Content-Type";
|
||||
static final String ACCEPT = "Accept";
|
||||
static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
@Override
|
||||
protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
|
||||
RequestMapping mapping = RequestMapping.class.cast(methodAnnotation);
|
||||
if (mapping != null) {
|
||||
//HTTP Method
|
||||
checkOne(method, mapping.method(), "method");
|
||||
data.template().method(mapping.method()[0].name());
|
||||
@Override
|
||||
protected void processAnnotationOnMethod(MethodMetadata data,
|
||||
Annotation methodAnnotation, Method method) {
|
||||
RequestMapping mapping = RequestMapping.class.cast(methodAnnotation);
|
||||
if (mapping != null) {
|
||||
// HTTP Method
|
||||
checkOne(method, mapping.method(), "method");
|
||||
data.template().method(mapping.method()[0].name());
|
||||
|
||||
//path
|
||||
checkOne(method, mapping.value(), "value");
|
||||
// path
|
||||
checkOne(method, mapping.value(), "value");
|
||||
|
||||
String methodAnnotationValue = mapping.value()[0];
|
||||
String pathValue = emptyToNull(methodAnnotationValue);
|
||||
checkState(pathValue != null, "value was empty on method %s", method.getName());
|
||||
if (!methodAnnotationValue.startsWith("/") && !data.template().toString().endsWith("/")) {
|
||||
methodAnnotationValue = "/" + methodAnnotationValue;
|
||||
}
|
||||
data.template().append(methodAnnotationValue);
|
||||
String methodAnnotationValue = mapping.value()[0];
|
||||
String pathValue = emptyToNull(methodAnnotationValue);
|
||||
checkState(pathValue != null, "value was empty on method %s",
|
||||
method.getName());
|
||||
if (!methodAnnotationValue.startsWith("/")
|
||||
&& !data.template().toString().endsWith("/")) {
|
||||
methodAnnotationValue = "/" + methodAnnotationValue;
|
||||
}
|
||||
data.template().append(methodAnnotationValue);
|
||||
|
||||
//produces
|
||||
checkAtMostOne(method, mapping.produces(), "produces");
|
||||
String[] serverProduces = mapping.produces();
|
||||
String clientAccepts = serverProduces.length == 0 ? null: emptyToNull(serverProduces[0]);
|
||||
if (clientAccepts != null) {
|
||||
data.template().header(ACCEPT, clientAccepts);
|
||||
}
|
||||
// produces
|
||||
checkAtMostOne(method, mapping.produces(), "produces");
|
||||
String[] serverProduces = mapping.produces();
|
||||
String clientAccepts = serverProduces.length == 0 ? null
|
||||
: emptyToNull(serverProduces[0]);
|
||||
if (clientAccepts != null) {
|
||||
data.template().header(ACCEPT, clientAccepts);
|
||||
}
|
||||
|
||||
//consumes
|
||||
checkAtMostOne(method, mapping.consumes(), "consumes");
|
||||
String[] serverConsumes = mapping.consumes();
|
||||
String clientProduces = serverConsumes.length == 0 ? null: emptyToNull(serverConsumes[0]);
|
||||
if (clientProduces != null) {
|
||||
data.template().header(CONTENT_TYPE, clientProduces);
|
||||
}
|
||||
// consumes
|
||||
checkAtMostOne(method, mapping.consumes(), "consumes");
|
||||
String[] serverConsumes = mapping.consumes();
|
||||
String clientProduces = serverConsumes.length == 0 ? null
|
||||
: emptyToNull(serverConsumes[0]);
|
||||
if (clientProduces != null) {
|
||||
data.template().header(CONTENT_TYPE, clientProduces);
|
||||
}
|
||||
|
||||
//headers
|
||||
//TODO: only supports one header value per key
|
||||
if (mapping.headers() != null && mapping.headers().length > 0)
|
||||
for (String header : mapping.headers()) {
|
||||
int colon = header.indexOf(':');
|
||||
data.template().header(header.substring(0, colon), header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
// headers
|
||||
// TODO: only supports one header value per key
|
||||
if (mapping.headers() != null && mapping.headers().length > 0) {
|
||||
for (String header : mapping.headers()) {
|
||||
int colon = header.indexOf(':');
|
||||
data.template().header(header.substring(0, colon),
|
||||
header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && (values.length == 0 || values.length == 1),
|
||||
"Method %s can only contain at most 1 %s field. Found: %s", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && (values.length == 0 || values.length == 1),
|
||||
"Method %s can only contain at most 1 %s field. Found: %s",
|
||||
method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(),
|
||||
fieldName, values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
//TODO: support spring parameter annotations?
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
Class<? extends Annotation> annotationType = parameterAnnotation.annotationType();
|
||||
if (annotationType == PathVariable.class) {
|
||||
String name = PathVariable.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "PathVariable annotation was empty on param %s.", paramIndex);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
String varName = '{' + name + '}';
|
||||
if (data.template().url().indexOf(varName) == -1 &&
|
||||
!searchMapValues(data.template().queries(), varName) &&
|
||||
!searchMapValues(data.template().headers(), varName)) {
|
||||
data.formParams().add(name);
|
||||
}
|
||||
} else if (annotationType == RequestParam.class) {
|
||||
String name = RequestParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "QueryParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> query = addTemplatedParam(data.template().queries().get(name), name);
|
||||
data.template().query(name, query);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
} else if (annotationType == RequestHeader.class) {
|
||||
String name = RequestHeader.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "HeaderParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> header = addTemplatedParam(data.template().headers().get(name), name);
|
||||
data.template().header(name, header);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}/* else if (annotationType == FormParam.class) {
|
||||
String name = FormParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "FormParam.value() was empty on parameter %s", paramIndex);
|
||||
data.formParams().add(name);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}*/
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data,
|
||||
Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
// TODO: support spring parameter annotations?
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
Class<? extends Annotation> annotationType = parameterAnnotation
|
||||
.annotationType();
|
||||
if (annotationType == PathVariable.class) {
|
||||
String name = PathVariable.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"PathVariable annotation was empty on param %s.", paramIndex);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
String varName = '{' + name + '}';
|
||||
if (data.template().url().indexOf(varName) == -1
|
||||
&& !searchMapValues(data.template().queries(), varName)
|
||||
&& !searchMapValues(data.template().headers(), varName)) {
|
||||
data.formParams().add(name);
|
||||
}
|
||||
}
|
||||
else if (annotationType == RequestParam.class) {
|
||||
String name = RequestParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"QueryParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> query = addTemplatedParam(data.template().queries()
|
||||
.get(name), name);
|
||||
data.template().query(name, query);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}
|
||||
else if (annotationType == RequestHeader.class) {
|
||||
String name = RequestHeader.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"HeaderParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> header = addTemplatedParam(data.template().headers()
|
||||
.get(name), name);
|
||||
data.template().header(name, header);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}/*
|
||||
* else if (annotationType == FormParam.class) { String name =
|
||||
* FormParam.class.cast(parameterAnnotation).value();
|
||||
* checkState(emptyToNull(name) != null,
|
||||
* "FormParam.value() was empty on parameter %s", paramIndex);
|
||||
* data.formParams().add(name); nameParam(data, name, paramIndex);
|
||||
* isHttpAnnotation = true; }
|
||||
*/
|
||||
|
||||
}
|
||||
return isHttpAnnotation;
|
||||
}
|
||||
}
|
||||
return isHttpAnnotation;
|
||||
}
|
||||
|
||||
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
|
||||
Collection<Collection<V>> values = map.values();
|
||||
if (values == null)
|
||||
return false;
|
||||
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
|
||||
Collection<Collection<V>> values = map.values();
|
||||
if (values == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search))
|
||||
return true;
|
||||
}
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,17 @@ import feign.Response;
|
||||
*/
|
||||
public class FeignRibbonClient implements Client {
|
||||
|
||||
private Client defaultClient = new Default(
|
||||
new Lazy<SSLSocketFactory>() {
|
||||
@Override
|
||||
public SSLSocketFactory get() {
|
||||
return (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
}
|
||||
}, new Lazy<HostnameVerifier>() {
|
||||
@Override
|
||||
public HostnameVerifier get() {
|
||||
return HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
}
|
||||
});
|
||||
private Client defaultClient = new Default(new Lazy<SSLSocketFactory>() {
|
||||
@Override
|
||||
public SSLSocketFactory get() {
|
||||
return (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
}
|
||||
}, new Lazy<HostnameVerifier>() {
|
||||
@Override
|
||||
public HostnameVerifier get() {
|
||||
return HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
}
|
||||
});
|
||||
private SpringClientFactory factory;
|
||||
|
||||
public FeignRibbonClient(SpringClientFactory factory) {
|
||||
@@ -44,30 +43,34 @@ public class FeignRibbonClient implements Client {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
try {
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
try {
|
||||
|
||||
URI asUri = URI.create(request.url());
|
||||
String clientName = asUri.getHost();
|
||||
URI uriWithoutSchemeAndPort = URI.create(request.url().replace(asUri.getScheme() + "://" + asUri.getHost(), ""));
|
||||
RibbonLoadBalancer.RibbonRequest ribbonRequest = new RibbonLoadBalancer.RibbonRequest(request, uriWithoutSchemeAndPort);
|
||||
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest).toResponse();
|
||||
URI asUri = URI.create(request.url());
|
||||
String clientName = asUri.getHost();
|
||||
URI uriWithoutSchemeAndPort = URI.create(request.url().replace(
|
||||
asUri.getScheme() + "://" + asUri.getHost(), ""));
|
||||
RibbonLoadBalancer.RibbonRequest ribbonRequest = new RibbonLoadBalancer.RibbonRequest(
|
||||
request, uriWithoutSchemeAndPort);
|
||||
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest)
|
||||
.toResponse();
|
||||
|
||||
} catch (ClientException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw IOException.class.cast(e.getCause());
|
||||
}
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClientException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw IOException.class.cast(e.getCause());
|
||||
}
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
private RibbonLoadBalancer lbClient(String clientName) {
|
||||
IClientConfig config = factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = factory.getLoadBalancer(clientName);
|
||||
return new RibbonLoadBalancer(defaultClient, lb, config);
|
||||
}
|
||||
private RibbonLoadBalancer lbClient(String clientName) {
|
||||
IClientConfig config = this.factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
|
||||
return new RibbonLoadBalancer(this.defaultClient, lb, config);
|
||||
}
|
||||
|
||||
public void setDefaultClient(Client defaultClient) {
|
||||
this.defaultClient = defaultClient;
|
||||
}
|
||||
public void setDefaultClient(Client defaultClient) {
|
||||
this.defaultClient = defaultClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,115 +20,125 @@ import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
|
||||
public class RibbonLoadBalancer extends AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
|
||||
public class RibbonLoadBalancer
|
||||
extends
|
||||
AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
|
||||
|
||||
private final Client delegate;
|
||||
private final int connectTimeout;
|
||||
private final int readTimeout;
|
||||
private final IClientConfig clientConfig;
|
||||
private final Client delegate;
|
||||
private final int connectTimeout;
|
||||
private final int readTimeout;
|
||||
private final IClientConfig clientConfig;
|
||||
|
||||
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
this.setRetryHandler(RetryHandler.DEFAULT);
|
||||
this.clientConfig = clientConfig;
|
||||
this.delegate = delegate;
|
||||
connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
|
||||
readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
|
||||
}
|
||||
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb,
|
||||
IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
this.setRetryHandler(RetryHandler.DEFAULT);
|
||||
this.clientConfig = clientConfig;
|
||||
this.delegate = delegate;
|
||||
this.connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
|
||||
this.readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride) throws IOException {
|
||||
Request.Options options;
|
||||
if (configOverride != null) {
|
||||
options = new Request.Options(configOverride.get(CommonClientConfigKey.ConnectTimeout, connectTimeout), (configOverride.get(CommonClientConfigKey.ReadTimeout, readTimeout)));
|
||||
} else {
|
||||
options = new Request.Options(connectTimeout, readTimeout);
|
||||
}
|
||||
Response response = delegate.execute(request.toRequest(), options);
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
|
||||
throws IOException {
|
||||
Request.Options options;
|
||||
if (configOverride != null) {
|
||||
options = new Request.Options(configOverride.get(
|
||||
CommonClientConfigKey.ConnectTimeout, this.connectTimeout),
|
||||
(configOverride.get(CommonClientConfigKey.ReadTimeout,
|
||||
this.readTimeout)));
|
||||
}
|
||||
else {
|
||||
options = new Request.Options(this.connectTimeout, this.readTimeout);
|
||||
}
|
||||
Response response = this.delegate.execute(request.toRequest(), options);
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
|
||||
RibbonRequest request, IClientConfig requestConfig) {
|
||||
if (clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations, false)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(), requestConfig);
|
||||
} else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), requestConfig);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
|
||||
RibbonRequest request, IClientConfig requestConfig) {
|
||||
if (this.clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations, false)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
}
|
||||
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
|
||||
private final Request request;
|
||||
private final Request request;
|
||||
|
||||
RibbonRequest(Request request, URI uri) {
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
RibbonRequest(Request request, URI uri) {
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
|
||||
Request toRequest() {
|
||||
return new RequestTemplate()
|
||||
.method(request.method())
|
||||
.append(getUri().toASCIIString())
|
||||
.headers(request.headers())
|
||||
.body(request.body(), request.charset())
|
||||
.request();
|
||||
}
|
||||
Request toRequest() {
|
||||
return new RequestTemplate().method(this.request.method())
|
||||
.append(getUri().toASCIIString()).headers(this.request.headers())
|
||||
.body(this.request.body(), this.request.charset()).request();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new RibbonRequest(request, getUri());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new RibbonRequest(this.request, getUri());
|
||||
}
|
||||
}
|
||||
|
||||
static class RibbonResponse implements IResponse {
|
||||
static class RibbonResponse implements IResponse {
|
||||
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return response.body();
|
||||
}
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return this.response.body();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return response.body() != null;
|
||||
}
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return this.response.body() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return response.status() == 200;
|
||||
}
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return this.response.status() == 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return uri;
|
||||
}
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return response.headers();
|
||||
}
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return this.response.headers();
|
||||
}
|
||||
|
||||
Response toResponse() {
|
||||
return response;
|
||||
}
|
||||
Response toResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (response != null && response.body() != null) {
|
||||
response.body().close();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.response != null && this.response.body() != null) {
|
||||
this.response.body().close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
* you want. All it does is turn on circuit breakers and let the autoconfiguration find
|
||||
* the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as
|
||||
* well).
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsAsJsonPollerListener;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.catalina.core.ApplicationContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -37,11 +37,12 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsAsJsonPollerListener;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -63,7 +64,7 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
@Configuration
|
||||
@ConditionalOnExpression("${hystrix.stream.endpoint.enabled:true}")
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass({Endpoint.class, HystrixMetricsStreamServlet.class})
|
||||
@ConditionalOnClass({ Endpoint.class, HystrixMetricsStreamServlet.class })
|
||||
protected static class HystrixWebConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -74,13 +75,13 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({HystrixMetricsPoller.class, GaugeService.class})
|
||||
@ConditionalOnClass({ HystrixMetricsPoller.class, GaugeService.class })
|
||||
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(HystrixMetricsPollerConfiguration.class);
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private GaugeService gauges;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
@@ -92,7 +93,7 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (gauges==null) {
|
||||
if (this.gauges == null) {
|
||||
return;
|
||||
}
|
||||
MetricsAsJsonPollerListener listener = new MetricsAsJsonPollerListener() {
|
||||
@@ -100,7 +101,8 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
public void handleJsonMetric(String json) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = mapper.readValue(json, Map.class);
|
||||
Map<String, Object> map = HystrixMetricsPollerConfiguration.this.mapper
|
||||
.readValue(json, Map.class);
|
||||
if (map != null && map.containsKey("type")) {
|
||||
addMetrics(map, "hystrix.");
|
||||
}
|
||||
@@ -111,9 +113,9 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
}
|
||||
|
||||
};
|
||||
poller = new HystrixMetricsPoller(listener, 2000);
|
||||
this.poller = new HystrixMetricsPoller(listener, 2000);
|
||||
// start polling and it will write directly to the listener
|
||||
poller.start();
|
||||
this.poller.start();
|
||||
logger.info("Starting poller");
|
||||
}
|
||||
|
||||
@@ -129,10 +131,10 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
String prefix = prefixBuilder.toString();
|
||||
for (String key : map.keySet()) {
|
||||
Object value = map.get(key);
|
||||
if (!reserved.contains(key)) {
|
||||
if (!this.reserved.contains(key)) {
|
||||
if (value instanceof Number) {
|
||||
String name = prefix + "." + key;
|
||||
gauges.submit(name, ((Number) value).doubleValue());
|
||||
this.gauges.submit(name, ((Number) value).doubleValue());
|
||||
}
|
||||
else if (value instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -145,14 +147,14 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return poller != null ? poller.isRunning() : false;
|
||||
return this.poller != null ? this.poller.isRunning() : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,8 +169,8 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@@ -28,34 +28,38 @@ import com.netflix.hystrix.HystrixCircuitBreaker;
|
||||
import com.netflix.hystrix.HystrixCommandMetrics;
|
||||
|
||||
/**
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* <p>
|
||||
* This default implementation will set the system to <code>OUT_OF_SERVICE</code> and
|
||||
* include all open circuits by name.
|
||||
*
|
||||
* This default implementation will set the system to <code>OUT_OF_SERVICE</code> and
|
||||
* include all open circuits by name.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
|
||||
/** Status code for open circuits */
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
List<String> openCircuitBreakers = new ArrayList<String>();
|
||||
|
||||
|
||||
// Collect all open circuit breakers from Hystrix
|
||||
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(metrics.getCommandKey());
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
|
||||
.getInstance(metrics.getCommandKey());
|
||||
if (circuitBreaker.isOpen()) {
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::" + metrics.getCommandKey().name());
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
|
||||
+ metrics.getCommandKey().name());
|
||||
}
|
||||
}
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command group
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command
|
||||
// group
|
||||
// and key name
|
||||
if (openCircuitBreakers.size() > 0) {
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers", openCircuitBreakers);
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers",
|
||||
openCircuitBreakers);
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
|
||||
@@ -24,7 +24,8 @@ import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServl
|
||||
*/
|
||||
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
|
||||
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream", false, true);
|
||||
}
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
|
||||
false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,22 +22,22 @@ import com.netflix.client.IClient;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({IClient.class, RestTemplate.class})
|
||||
@ConditionalOnClass({ IClient.class, RestTemplate.class })
|
||||
@RibbonClients
|
||||
@AutoConfigureAfter(EurekaClientAutoConfiguration.class)
|
||||
public class RibbonAutoConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
private List<RibbonClientSpecification> configurations = new ArrayList<>();
|
||||
@Autowired(required = false)
|
||||
private List<RibbonClientSpecification> configurations = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
public SpringClientFactory springClientFactory() {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setConfigurations(configurations);
|
||||
public SpringClientFactory springClientFactory() {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setConfigurations(this.configurations);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RestTemplate.class)
|
||||
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@@ -35,6 +35,8 @@ import org.springframework.context.annotation.Import;
|
||||
@Documented
|
||||
public @interface RibbonClient {
|
||||
String value() default "";
|
||||
|
||||
String name() default "";
|
||||
|
||||
Class<?>[] configuration() default {};
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@ public class RibbonClientConfiguration {
|
||||
|
||||
// TODO: maybe re-instate autowired load balancers: identified by name they could be
|
||||
// associated with ribbon clients
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IClientConfig ribbonClientConfig() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.loadProperties(name);
|
||||
config.loadProperties(this.name);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -65,20 +65,21 @@ public class RibbonClientConfiguration {
|
||||
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer) {
|
||||
RestClient client = new RestClient(config);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
Monitors.registerObject("Client_" + name, client);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
//TODO: move to ribbon.eureka package
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerListFilter<Server> filter) {
|
||||
// TODO: move to ribbon.eureka package
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
|
||||
ServerListFilter<Server> filter) {
|
||||
ZoneAwareLoadBalancer<Server> balancer = new ZoneAwareLoadBalancer<>(config);
|
||||
wrapServerList(balancer);
|
||||
balancer.setFilter(filter);
|
||||
return balancer;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) {
|
||||
@@ -86,10 +87,11 @@ public class RibbonClientConfiguration {
|
||||
filter.initWithNiwsConfig(config);
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RibbonLoadBalancerContext ribbonLoadBalancerContext(ILoadBalancer loadBalancer, IClientConfig config) {
|
||||
public RibbonLoadBalancerContext ribbonLoadBalancerContext(
|
||||
ILoadBalancer loadBalancer, IClientConfig config) {
|
||||
return new RibbonLoadBalancerContext(loadBalancer, config);
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ public class RibbonClientConfiguration {
|
||||
// metadata *is* available.
|
||||
// @see com.netflix.appinfo.AmazonInfo.Builder
|
||||
dynamic.setServerListImpl(new DomainExtractingServerList(list, dynamic
|
||||
.getClientConfig(), approximateZoneFromHostname));
|
||||
.getClientConfig(), this.approximateZoneFromHostname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionR
|
||||
}
|
||||
|
||||
private String getClientName(Map<String, Object> client) {
|
||||
if (client==null) {
|
||||
if (client == null) {
|
||||
return null;
|
||||
}
|
||||
String value = (String) client.get("value");
|
||||
@@ -67,7 +67,8 @@ public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionR
|
||||
if (value != null && StringUtils.hasText(value)) {
|
||||
return value;
|
||||
}
|
||||
throw new IllegalStateException("Either 'name' or 'value' must be provided in @RibbonClient");
|
||||
throw new IllegalStateException(
|
||||
"Either 'name' or 'value' must be provided in @RibbonClient");
|
||||
}
|
||||
|
||||
private void registerClientConfiguration(BeanDefinitionRegistry registry,
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.context.annotation.Import;
|
||||
/**
|
||||
* Convenience annotation that allows user to combine multiple <code>@RibbonClient</code>
|
||||
* annotations on a single class (including in Java 7).
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
|
||||
@@ -9,36 +12,37 @@ import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private LoadBalancerClient loadBalancer;
|
||||
private LoadBalancerClient loadBalancer;
|
||||
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
|
||||
final URI originalUri = request.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
return loadBalancer.execute(serviceName, new LoadBalancerRequest<ClientHttpResponse>() {
|
||||
@Override
|
||||
public ClientHttpResponse apply(final ServiceInstance instance) throws Exception {
|
||||
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
|
||||
@Override
|
||||
public URI getURI() {
|
||||
URI uri = loadBalancer.reconstructURI(instance, originalUri);
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
return execution.execute(wrapper, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
|
||||
final ClientHttpRequestExecution execution) throws IOException {
|
||||
final URI originalUri = request.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
return this.loadBalancer.execute(serviceName,
|
||||
new LoadBalancerRequest<ClientHttpResponse>() {
|
||||
@Override
|
||||
public ClientHttpResponse apply(final ServiceInstance instance)
|
||||
throws Exception {
|
||||
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
|
||||
@Override
|
||||
public URI getURI() {
|
||||
URI uri = RibbonInterceptor.this.loadBalancer
|
||||
.reconstructURI(instance, originalUri);
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
return execution.execute(wrapper, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,72 +19,76 @@ import com.netflix.servo.monitor.Stopwatch;
|
||||
*/
|
||||
public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
|
||||
private SpringClientFactory clientFactory;
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
public RibbonLoadBalancerClient(SpringClientFactory clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
String serviceId = instance.getServiceId();
|
||||
RibbonLoadBalancerContext context = clientFactory.getLoadBalancerContext(serviceId);
|
||||
Server server = new Server(instance.getHost(), instance.getPort());
|
||||
return context.reconstructURIWithServer(server, original);
|
||||
}
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
String serviceId = instance.getServiceId();
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = new Server(instance.getHost(), instance.getPort());
|
||||
return context.reconstructURIWithServer(server, original);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return new RibbonServer(serviceId, getServer(serviceId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
|
||||
RibbonLoadBalancerContext context = clientFactory.getLoadBalancerContext(serviceId);
|
||||
Server server = getServer(serviceId, loadBalancer);
|
||||
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = getServer(serviceId, loadBalancer);
|
||||
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
|
||||
|
||||
ServerStats serverStats = context.getServerStats(server);
|
||||
context.noteOpenConnection(serverStats);
|
||||
Stopwatch tracer = context.getExecuteTracer().start();
|
||||
ServerStats serverStats = context.getServerStats(server);
|
||||
context.noteOpenConnection(serverStats);
|
||||
Stopwatch tracer = context.getExecuteTracer().start();
|
||||
|
||||
try {
|
||||
try {
|
||||
|
||||
T returnVal = request.apply(ribbonServer);
|
||||
recordStats(context, tracer, serverStats, returnVal, null);
|
||||
return returnVal;
|
||||
} catch (Exception e) {
|
||||
recordStats(context, tracer, serverStats, null, e);
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
T returnVal = request.apply(ribbonServer);
|
||||
recordStats(context, tracer, serverStats, returnVal, null);
|
||||
return returnVal;
|
||||
}
|
||||
catch (Exception e) {
|
||||
recordStats(context, tracer, serverStats, null, e);
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void recordStats(RibbonLoadBalancerContext context, Stopwatch tracer, ServerStats serverStats, Object entity, Throwable exception) {
|
||||
tracer.stop();
|
||||
long duration = tracer.getDuration(TimeUnit.MILLISECONDS);
|
||||
context.noteRequestCompletion(serverStats, entity, exception, duration, null/*errorHandler*/);
|
||||
}
|
||||
private void recordStats(RibbonLoadBalancerContext context, Stopwatch tracer,
|
||||
ServerStats serverStats, Object entity, Throwable exception) {
|
||||
tracer.stop();
|
||||
long duration = tracer.getDuration(TimeUnit.MILLISECONDS);
|
||||
context.noteRequestCompletion(serverStats, entity, exception, duration, null/* errorHandler */);
|
||||
}
|
||||
|
||||
protected Server getServer(String serviceId) {
|
||||
return getServer(serviceId, getLoadBalancer(serviceId));
|
||||
}
|
||||
protected Server getServer(String serviceId) {
|
||||
return getServer(serviceId, getLoadBalancer(serviceId));
|
||||
}
|
||||
|
||||
protected Server getServer(String serviceId, ILoadBalancer loadBalancer) {
|
||||
Server server = loadBalancer.chooseServer("default");
|
||||
if (server == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to locate ILoadBalancer for service: " + serviceId);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
protected Server getServer(String serviceId, ILoadBalancer loadBalancer) {
|
||||
Server server = loadBalancer.chooseServer("default");
|
||||
if (server == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to locate ILoadBalancer for service: " + serviceId);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
protected ILoadBalancer getLoadBalancer(String serviceId) {
|
||||
return clientFactory.getLoadBalancer(serviceId);
|
||||
}
|
||||
protected ILoadBalancer getLoadBalancer(String serviceId) {
|
||||
return this.clientFactory.getLoadBalancer(serviceId);
|
||||
}
|
||||
|
||||
protected static class RibbonServer implements ServiceInstance {
|
||||
protected static class RibbonServer implements ServiceInstance {
|
||||
protected String serviceId;
|
||||
protected Server server;
|
||||
|
||||
@@ -95,17 +99,17 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return server.getHost();
|
||||
return this.server.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return server.getPort();
|
||||
return this.server.getPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,35 +11,38 @@ import com.netflix.servo.monitor.Timer;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerContext extends LoadBalancerContext {
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig, RetryHandler handler) {
|
||||
super(lb, clientConfig, handler);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
RetryHandler handler) {
|
||||
super(lb, clientConfig, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteOpenConnection(ServerStats serverStats) {
|
||||
super.noteOpenConnection(serverStats);
|
||||
}
|
||||
@Override
|
||||
public void noteOpenConnection(ServerStats serverStats) {
|
||||
super.noteOpenConnection(serverStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getExecuteTracer() {
|
||||
return super.getExecuteTracer();
|
||||
}
|
||||
@Override
|
||||
public Timer getExecuteTracer() {
|
||||
return super.getExecuteTracer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, long responseTime) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime);
|
||||
}
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, long responseTime, RetryHandler errorHandler) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime, errorHandler);
|
||||
}
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime, RetryHandler errorHandler) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime, errorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
public void setApplicationContext(ApplicationContext parent) throws BeansException {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
public void setConfigurations(List<RibbonClientSpecification> configurations) {
|
||||
for (RibbonClientSpecification client : configurations) {
|
||||
this.configurations.put(client.getName(), client);
|
||||
@@ -47,8 +47,8 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Collection<AnnotationConfigApplicationContext> values = contexts.values();
|
||||
contexts.clear();
|
||||
Collection<AnnotationConfigApplicationContext> values = this.contexts.values();
|
||||
this.contexts.clear();
|
||||
for (AnnotationConfigApplicationContext context : values) {
|
||||
context.close();
|
||||
}
|
||||
@@ -91,28 +91,30 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext getContext(String name) {
|
||||
if (!contexts.containsKey(name)) {
|
||||
synchronized (contexts) {
|
||||
if (!contexts.containsKey(name)) {
|
||||
contexts.put(name, createContext(name));
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
synchronized (this.contexts) {
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
this.contexts.put(name, createContext(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return contexts.get(name);
|
||||
return this.contexts.get(name);
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext createContext(String name) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
if (configurations.containsKey(name)) {
|
||||
for (Class<?> configuration : configurations.get(name).getConfiguration()) {
|
||||
if (this.configurations.containsKey(name)) {
|
||||
for (Class<?> configuration : this.configurations.get(name)
|
||||
.getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
for (Entry<String, RibbonClientSpecification> entry : configurations.entrySet()) {
|
||||
for (Entry<String, RibbonClientSpecification> entry : this.configurations
|
||||
.entrySet()) {
|
||||
if (entry.getKey().startsWith("default.")) {
|
||||
for (Class<?> configuration : entry.getValue().getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
@@ -123,9 +125,9 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
new MapPropertySource("ribbon",
|
||||
Collections.<String, Object> singletonMap(
|
||||
"ribbon.client.name", name)));
|
||||
if (parent != null) {
|
||||
if (this.parent != null) {
|
||||
// Uses Environment from parent as well as beans
|
||||
context.setParent(parent);
|
||||
context.setParent(this.parent);
|
||||
}
|
||||
context.refresh();
|
||||
return context;
|
||||
|
||||
@@ -18,14 +18,14 @@ package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
@@ -36,88 +36,92 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
*/
|
||||
public class DomainExtractingServerList implements ServerList<Server> {
|
||||
|
||||
private ServerList<Server> list;
|
||||
private IClientConfig clientConfig;
|
||||
private ServerList<Server> list;
|
||||
private IClientConfig clientConfig;
|
||||
private boolean approximateZoneFromHostname;
|
||||
|
||||
public DomainExtractingServerList(ServerList<Server> list, IClientConfig clientConfig, boolean approximateZoneFromHostname) {
|
||||
this.list = list;
|
||||
this.clientConfig = clientConfig;
|
||||
public DomainExtractingServerList(ServerList<Server> list,
|
||||
IClientConfig clientConfig, boolean approximateZoneFromHostname) {
|
||||
this.list = list;
|
||||
this.clientConfig = clientConfig;
|
||||
this.approximateZoneFromHostname = approximateZoneFromHostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getInitialListOfServers() {
|
||||
List<Server> servers = setZones(list.getInitialListOfServers());
|
||||
return servers;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getInitialListOfServers() {
|
||||
List<Server> servers = setZones(this.list.getInitialListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
List<Server> servers = setZones(list.getUpdatedListOfServers());
|
||||
return servers;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
List<Server> servers = setZones(this.list.getUpdatedListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
private List<Server> setZones(List<Server> servers) {
|
||||
List<Server> result = new ArrayList<>();
|
||||
boolean isSecure = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.IsSecure, Boolean.TRUE);
|
||||
boolean shouldUseIpAddr = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
|
||||
for (Server server : servers) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
result.add(new DomainExtractingServer((DiscoveryEnabledServer) server,
|
||||
isSecure, shouldUseIpAddr, approximateZoneFromHostname));
|
||||
}
|
||||
else {
|
||||
result.add(server);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private List<Server> setZones(List<Server> servers) {
|
||||
List<Server> result = new ArrayList<>();
|
||||
boolean isSecure = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.IsSecure, Boolean.TRUE);
|
||||
boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
|
||||
for (Server server : servers) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
result.add(new DomainExtractingServer((DiscoveryEnabledServer) server,
|
||||
isSecure, shouldUseIpAddr, this.approximateZoneFromHostname));
|
||||
}
|
||||
else {
|
||||
result.add(server);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DomainExtractingServer extends DiscoveryEnabledServer {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
|
||||
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, boolean useIpAddr, boolean approximateZoneFromHostname) {
|
||||
//host and port are set in super()
|
||||
super(server.getInstanceInfo(), useSecurePort, useIpAddr);
|
||||
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort,
|
||||
boolean useIpAddr, boolean approximateZoneFromHostname) {
|
||||
// host and port are set in super()
|
||||
super(server.getInstanceInfo(), useSecurePort, useIpAddr);
|
||||
if (approximateZoneFromHostname) {
|
||||
setZone(extractApproximateZone(server));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setZone(server.getZone());
|
||||
}
|
||||
setId(extractId(server));
|
||||
setId(extractId(server));
|
||||
setAlive(server.isAlive());
|
||||
setReadyToServe(server.isReadyToServe());
|
||||
}
|
||||
}
|
||||
|
||||
private String extractId(Server server) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server;
|
||||
InstanceInfo instance = enabled.getInstanceInfo();
|
||||
if (instance.getMetadata().containsKey("instanceId")) {
|
||||
return instance.getMetadata().get("instanceId");
|
||||
}
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
private String extractId(Server server) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server;
|
||||
InstanceInfo instance = enabled.getInstanceInfo();
|
||||
if (instance.getMetadata().containsKey("instanceId")) {
|
||||
return instance.getMetadata().get("instanceId");
|
||||
}
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
private String extractApproximateZone(Server server) {
|
||||
String host = server.getHost();
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
private String extractApproximateZone(Server server) {
|
||||
String host = server.getHost();
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NFLoadBalancerRuleClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilterClassName;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -20,11 +14,17 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
|
||||
import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NFLoadBalancerRuleClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilterClassName;
|
||||
|
||||
/**
|
||||
* Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as:
|
||||
* <code>@zone</code>, NIWSServerListClassName, DeploymentContextBasedVipAddresses,
|
||||
* NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -51,9 +51,10 @@ public class EurekaRibbonClientConfiguration {
|
||||
|
||||
@PostConstruct
|
||||
public void preprocess() {
|
||||
if (clientConfig != null
|
||||
if (this.clientConfig != null
|
||||
&& ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) {
|
||||
String[] zones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
|
||||
String[] zones = this.clientConfig.getAvailabilityZones(this.clientConfig
|
||||
.getRegion());
|
||||
String zone = zones != null && zones.length > 0 ? zones[0] : null;
|
||||
if (zone != null) {
|
||||
// You can set this with archaius.deployment.* (maybe requires
|
||||
@@ -63,15 +64,15 @@ public class EurekaRibbonClientConfiguration {
|
||||
}
|
||||
}
|
||||
// TODO: should this look more like hibernate spring boot props?
|
||||
setProp(serviceId, NIWSServerListClassName.key(),
|
||||
setProp(this.serviceId, NIWSServerListClassName.key(),
|
||||
DiscoveryEnabledNIWSServerList.class.getName());
|
||||
// FIXME: what should this be?
|
||||
setProp(serviceId, DeploymentContextBasedVipAddresses.key(), serviceId);
|
||||
setProp(serviceId, NFLoadBalancerRuleClassName.key(),
|
||||
setProp(this.serviceId, DeploymentContextBasedVipAddresses.key(), this.serviceId);
|
||||
setProp(this.serviceId, NFLoadBalancerRuleClassName.key(),
|
||||
ZoneAvoidanceRule.class.getName());
|
||||
setProp(serviceId, NIWSServerListFilterClassName.key(),
|
||||
setProp(this.serviceId, NIWSServerListFilterClassName.key(),
|
||||
ZonePreferenceServerListFilter.class.getName());
|
||||
setProp(serviceId, EnableZoneAffinity.key(), "true");
|
||||
setProp(this.serviceId, EnableZoneAffinity.key(), "true");
|
||||
}
|
||||
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
|
||||
@@ -30,13 +30,13 @@ import com.netflix.loadbalancer.ZoneAffinityServerListFilter;
|
||||
/**
|
||||
* A filter that actively prefers the local zone (as defined by the deployment context, or
|
||||
* the Eureka instance metadata).
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* TODO: move out of ribbon.eureka package since it has nothing specific to eureka
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter<Server> {
|
||||
|
||||
private String zone;
|
||||
@@ -45,17 +45,18 @@ public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter
|
||||
public void initWithNiwsConfig(IClientConfig niwsClientConfig) {
|
||||
super.initWithNiwsConfig(niwsClientConfig);
|
||||
if (ConfigurationManager.getDeploymentContext() != null) {
|
||||
zone = ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone);
|
||||
this.zone = ConfigurationManager.getDeploymentContext().getValue(
|
||||
ContextKey.zone);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getFilteredListOfServers(List<Server> servers) {
|
||||
List<Server> output = super.getFilteredListOfServers(servers);
|
||||
if (zone != null && output.size() == servers.size()) {
|
||||
if (this.zone != null && output.size() == servers.size()) {
|
||||
List<Server> local = new ArrayList<Server>();
|
||||
for (Server server : output) {
|
||||
if (zone.equalsIgnoreCase(server.getZone())) {
|
||||
if (this.zone.equalsIgnoreCase(server.getZone())) {
|
||||
local.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
@@ -38,7 +39,7 @@ import com.netflix.servo.publish.PollScheduler;
|
||||
/**
|
||||
* {@link MetricReader} implementation that registers a {@link MetricObserver} with the
|
||||
* Netflix Servo library and exposes Servo metrics to the <code>/metric</code> endpoint.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@@ -88,8 +89,9 @@ public class ServoMetricCollector implements DisposableBean {
|
||||
.append(config.getName()).toString().toLowerCase();
|
||||
|
||||
if (servoMetric.hasNumberValue()) {
|
||||
metrics.set(new Metric<Number>(key, servoMetric.getNumberValue(),
|
||||
new Date(servoMetric.getTimestamp())));
|
||||
this.metrics.set(new Metric<Number>(key,
|
||||
servoMetric.getNumberValue(), new Date(servoMetric
|
||||
.getTimestamp())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* Auto configuration to configure Servo support.
|
||||
*
|
||||
* Auto configuration to configure Servo support.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@@ -40,9 +40,9 @@ import com.netflix.servo.monitor.Monitors;
|
||||
@ConditionalOnClass({ Monitors.class, MetricReader.class })
|
||||
@ConditionalOnBean(MetricReader.class)
|
||||
@AutoConfigureBefore(EndpointAutoConfiguration.class)
|
||||
@AutoConfigureAfter({MetricRepositoryAutoConfiguration.class})
|
||||
@AutoConfigureAfter({ MetricRepositoryAutoConfiguration.class })
|
||||
public class ServoMetricsAutoConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricCollector servoMetricCollector(MetricWriter metrics) {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
|
||||
* forward requests to backend servers. The backends can be registered manually through
|
||||
* configuration or via Eureka.
|
||||
*
|
||||
*
|
||||
* @see EnableZuulServer for how to get a Zuul server without any proxying
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
|
||||
@@ -12,9 +12,9 @@ import org.springframework.context.annotation.Import;
|
||||
* Set up the application to act as a generic Zuul server without any built-in reverse
|
||||
* proxy features. The routes into the Zuul server can be configured through
|
||||
* {@link ZuulProperties} (by default there are none).
|
||||
*
|
||||
*
|
||||
* @see EnableZuulProxy to see how to get reverse proxy out of the box
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
@@ -41,12 +41,12 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
}
|
||||
|
||||
public void addRoute(String path, String location) {
|
||||
staticRoutes.put(path, new ZuulRoute(path, location));
|
||||
this.staticRoutes.put(path, new ZuulRoute(path, location));
|
||||
resetRoutes();
|
||||
}
|
||||
|
||||
public void addRoute(ZuulRoute route) {
|
||||
staticRoutes.put(route.getPath(), route);
|
||||
this.staticRoutes.put(route.getPath(), route);
|
||||
resetRoutes();
|
||||
}
|
||||
|
||||
@@ -57,15 +57,15 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
|
||||
public Map<String, String> getRoutes() {
|
||||
|
||||
if (routes.get() == null) {
|
||||
routes.set(locateRoutes());
|
||||
if (this.routes.get() == null) {
|
||||
this.routes.set(locateRoutes());
|
||||
}
|
||||
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
|
||||
for (String key : routes.get().keySet()) {
|
||||
for (String key : this.routes.get().keySet()) {
|
||||
String url = key;
|
||||
values.put(url, routes.get().get(key).getLocation());
|
||||
values.put(url, this.routes.get().get(key).getLocation());
|
||||
}
|
||||
return values;
|
||||
|
||||
@@ -75,15 +75,15 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
String location = null;
|
||||
String targetPath = null;
|
||||
String id = null;
|
||||
String prefix = properties.getPrefix();
|
||||
for (Entry<String, ZuulRoute> entry : routes.get().entrySet()) {
|
||||
String prefix = this.properties.getPrefix();
|
||||
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
|
||||
String pattern = entry.getKey();
|
||||
if (pathMatcher.match(pattern, path)) {
|
||||
if (this.pathMatcher.match(pattern, path)) {
|
||||
ZuulRoute route = entry.getValue();
|
||||
id = route.getId();
|
||||
location = route.getLocation();
|
||||
targetPath = path;
|
||||
if (path.startsWith(prefix) && properties.isStripPrefix()) {
|
||||
if (path.startsWith(prefix) && this.properties.isStripPrefix()) {
|
||||
targetPath = path.substring(prefix.length());
|
||||
}
|
||||
if (route.isStripPrefix()) {
|
||||
@@ -102,7 +102,7 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
}
|
||||
|
||||
public void resetRoutes() {
|
||||
routes.set(locateRoutes());
|
||||
this.routes.set(locateRoutes());
|
||||
}
|
||||
|
||||
protected LinkedHashMap<String, ZuulRoute> locateRoutes() {
|
||||
@@ -110,16 +110,16 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
|
||||
|
||||
addConfiguredRoutes(routesMap);
|
||||
routesMap.putAll(staticRoutes);
|
||||
routesMap.putAll(this.staticRoutes);
|
||||
|
||||
if (discovery != null) {
|
||||
if (this.discovery != null) {
|
||||
// Add routes for discovery services by default
|
||||
List<String> services = discovery.getServices();
|
||||
List<String> services = this.discovery.getServices();
|
||||
for (String serviceId : services) {
|
||||
// Ignore specifically ignored services and those that were manually
|
||||
// configured
|
||||
String key = "/" + serviceId + "/**";
|
||||
if (!properties.getIgnoredServices().contains(serviceId)
|
||||
if (!this.properties.getIgnoredServices().contains(serviceId)
|
||||
&& !routesMap.containsKey(key)) {
|
||||
routesMap.put(key, new ZuulRoute(key, serviceId));
|
||||
}
|
||||
@@ -142,8 +142,8 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
path = "/" + path;
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(properties.getPrefix())) {
|
||||
path = properties.getPrefix() + path;
|
||||
if (StringUtils.hasText(this.properties.getPrefix())) {
|
||||
path = this.properties.getPrefix() + path;
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
}
|
||||
|
||||
protected void addConfiguredRoutes(Map<String, ZuulRoute> routes) {
|
||||
Map<String, ZuulRoute> routeEntries = properties.getRoutes();
|
||||
Map<String, ZuulRoute> routeEntries = this.properties.getRoutes();
|
||||
for (ZuulRoute entry : routeEntries.values()) {
|
||||
String route = entry.getPath();
|
||||
if (routes.containsKey(route)) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* Endpoint to display and reset the zuul proxy routes
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -40,7 +40,7 @@ public class RoutesEndpoint implements MvcEndpoint, ApplicationEventPublisherAwa
|
||||
@ResponseBody
|
||||
@ManagedOperation
|
||||
public Map<String, String> reset() {
|
||||
publisher.publishEvent(new RoutesRefreshedEvent(routes));
|
||||
this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes));
|
||||
return getRoutes();
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class RoutesEndpoint implements MvcEndpoint, ApplicationEventPublisherAwa
|
||||
@ResponseBody
|
||||
@ManagedAttribute
|
||||
public Map<String, String> getRoutes() {
|
||||
return routes.getRoutes();
|
||||
return this.routes.getRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,7 @@ public class RoutesRefreshedEvent extends ApplicationEvent {
|
||||
}
|
||||
|
||||
public RouteLocator getLocator() {
|
||||
return locator;
|
||||
return this.locator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
@Override
|
||||
public Collection<String> getRoutePaths() {
|
||||
Collection<String> paths = new LinkedHashSet<String>();
|
||||
for (ZuulRoute route : properties.getRoutes().values()) {
|
||||
for (ZuulRoute route : this.properties.getRoutes().values()) {
|
||||
paths.add(route.getPath());
|
||||
}
|
||||
return paths;
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ZuulConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouteLocator routeLocator() {
|
||||
return new SimpleRouteLocator(zuulProperties);
|
||||
return new SimpleRouteLocator(this.zuulProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -55,7 +55,7 @@ public class ZuulConfiguration {
|
||||
|
||||
@Bean
|
||||
public ZuulFilterInitializer zuulFilterInitializer() {
|
||||
return new ZuulFilterInitializer(filters);
|
||||
return new ZuulFilterInitializer(this.filters);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -74,8 +74,9 @@ public class ZuulConfiguration {
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent
|
||||
|| event instanceof RefreshScopeRefreshedEvent)
|
||||
zuulHandlerMapping.registerHandlers();
|
||||
|| event instanceof RefreshScopeRefreshedEvent) {
|
||||
this.zuulHandlerMapping.registerHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ZuulController extends ServletWrappingController {
|
||||
|
||||
public ZuulController() {
|
||||
setServletClass(ZuulServlet.class);
|
||||
setServletName("zuul");
|
||||
setSupportedMethods((String[])null); // Allow all
|
||||
}
|
||||
public ZuulController() {
|
||||
setServletClass(ZuulServlet.class);
|
||||
setServletName("zuul");
|
||||
setSupportedMethods((String[]) null); // Allow all
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
return super.handleRequestInternal(request, response);
|
||||
} finally {
|
||||
// @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
|
||||
RequestContext.getCurrentContext().unset();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
return super.handleRequestInternal(request, response);
|
||||
}
|
||||
finally {
|
||||
// @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
|
||||
RequestContext.getCurrentContext().unset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,43 +17,44 @@ import com.netflix.zuul.monitoring.MonitoringHelper;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*
|
||||
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
*
|
||||
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
*/
|
||||
public class ZuulFilterInitializer implements ServletContextListener {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ZuulFilterInitializer.class);
|
||||
private static final Logger LOGGER = LoggerFactory
|
||||
.getLogger(ZuulFilterInitializer.class);
|
||||
|
||||
private Map<String, ZuulFilter> filters;
|
||||
private Map<String, ZuulFilter> filters;
|
||||
|
||||
public ZuulFilterInitializer(Map<String, ZuulFilter> filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
|
||||
LOGGER.info("Starting filter initializer context listener");
|
||||
LOGGER.info("Starting filter initializer context listener");
|
||||
|
||||
//FIXME: mocks monitoring infrastructure as we don't need it for this simple app
|
||||
MonitoringHelper.initMocks();
|
||||
// FIXME: mocks monitoring infrastructure as we don't need it for this simple app
|
||||
MonitoringHelper.initMocks();
|
||||
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
|
||||
for (Map.Entry<String, ZuulFilter> entry : filters.entrySet()) {
|
||||
registry.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, ZuulFilter> entry : this.filters.entrySet()) {
|
||||
registry.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
LOGGER.info("Stopping filter initializer context listener");
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
for (Map.Entry<String, ZuulFilter> entry : filters.entrySet()) {
|
||||
registry.remove(entry.getKey());
|
||||
}
|
||||
clearLoaderCache();
|
||||
}
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
LOGGER.info("Stopping filter initializer context listener");
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
for (Map.Entry<String, ZuulFilter> entry : this.filters.entrySet()) {
|
||||
registry.remove(entry.getKey());
|
||||
}
|
||||
clearLoaderCache();
|
||||
}
|
||||
|
||||
private void clearLoaderCache() {
|
||||
FilterLoader instance = FilterLoader.getInstance();
|
||||
@@ -64,24 +65,17 @@ public class ZuulFilterInitializer implements ServletContextListener {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
/*private void initGroovyFilterManager() {
|
||||
|
||||
//TODO: support groovy filters loaded from filesystem in proxy
|
||||
FilterLoader.getInstance().setCompiler(new GroovyCompiler());
|
||||
|
||||
final String scriptRoot = props.getFilterRoot();
|
||||
LOGGER.info("Using file system script: " + scriptRoot);
|
||||
|
||||
try {
|
||||
FilterFileManager.setFilenameFilter(new GroovyFileFilter());
|
||||
FilterFileManager.init(5,
|
||||
scriptRoot + "/pre",
|
||||
scriptRoot + "/route",
|
||||
scriptRoot + "/post"
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
* private void initGroovyFilterManager() {
|
||||
*
|
||||
* //TODO: support groovy filters loaded from filesystem in proxy
|
||||
* FilterLoader.getInstance().setCompiler(new GroovyCompiler());
|
||||
*
|
||||
* final String scriptRoot = props.getFilterRoot();
|
||||
* LOGGER.info("Using file system script: " + scriptRoot);
|
||||
*
|
||||
* try { FilterFileManager.setFilenameFilter(new GroovyFileFilter());
|
||||
* FilterFileManager.init(5, scriptRoot + "/pre", scriptRoot + "/route", scriptRoot +
|
||||
* "/post" ); } catch (Exception e) { throw new RuntimeException(e); } }
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
|
||||
|
||||
/**
|
||||
* MVC HandlerMapping that maps incoming request paths to remote services.
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -25,13 +25,13 @@ public class ZuulHandlerMapping extends AbstractUrlHandlerMapping {
|
||||
}
|
||||
|
||||
protected void registerHandlers() {
|
||||
Collection<String> routes = routeLocator.getRoutePaths();
|
||||
Collection<String> routes = this.routeLocator.getRoutePaths();
|
||||
if (routes.isEmpty()) {
|
||||
logger.warn("No routes found from ProxyRouteLocator");
|
||||
this.logger.warn("No routes found from ProxyRouteLocator");
|
||||
}
|
||||
else {
|
||||
for (String url : routes) {
|
||||
registerHandler(url, zuul);
|
||||
registerHandler(url, this.zuul);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,19 +78,19 @@ public class ZuulProperties {
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
if (StringUtils.hasText(url)) {
|
||||
return url;
|
||||
if (StringUtils.hasText(this.url)) {
|
||||
return this.url;
|
||||
}
|
||||
return serviceId;
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
if (location != null
|
||||
&& (location.startsWith("http:") || location.startsWith("https:"))) {
|
||||
url = location;
|
||||
this.url = location;
|
||||
}
|
||||
else {
|
||||
serviceId = location;
|
||||
this.serviceId = location;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
@Bean
|
||||
@Override
|
||||
public ProxyRouteLocator routeLocator() {
|
||||
return new ProxyRouteLocator(discovery, zuulProperties);
|
||||
return new ProxyRouteLocator(this.discovery, this.zuulProperties);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -54,32 +54,32 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
@Bean
|
||||
// @RefreshScope
|
||||
public RoutesEndpoint zuulEndpoint() {
|
||||
return new RoutesEndpoint(routeLocator);
|
||||
return new RoutesEndpoint(this.routeLocator);
|
||||
}
|
||||
}
|
||||
|
||||
// pre filters
|
||||
@Bean
|
||||
public PreDecorationFilter preDecorationFilter() {
|
||||
return new PreDecorationFilter(routeLocator(), zuulProperties);
|
||||
return new PreDecorationFilter(routeLocator(), this.zuulProperties);
|
||||
}
|
||||
|
||||
// route filters
|
||||
@Bean
|
||||
public RibbonRoutingFilter ribbonRoutingFilter() {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
if (traces != null) {
|
||||
helper.setTraces(traces);
|
||||
if (this.traces != null) {
|
||||
helper.setTraces(this.traces);
|
||||
}
|
||||
RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, clientFactory);
|
||||
RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, this.clientFactory);
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleHostRoutingFilter simpleHostRoutingFilter() {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
if (traces != null) {
|
||||
helper.setTraces(traces);
|
||||
if (this.traces != null) {
|
||||
helper.setTraces(this.traces);
|
||||
}
|
||||
return new SimpleHostRoutingFilter(helper);
|
||||
}
|
||||
@@ -110,9 +110,9 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
}
|
||||
else if (event instanceof DiscoveryHeartbeatEvent) {
|
||||
DiscoveryHeartbeatEvent e = (DiscoveryHeartbeatEvent) event;
|
||||
if (latestHeartbeat.get() == null
|
||||
|| !latestHeartbeat.get().equals(e.getValue())) {
|
||||
latestHeartbeat.set(e.getValue());
|
||||
if (this.latestHeartbeat.get() == null
|
||||
|| !this.latestHeartbeat.get().equals(e.getValue())) {
|
||||
this.latestHeartbeat.set(e.getValue());
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@@ -120,8 +120,8 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
routeLocator.resetRoutes();
|
||||
zuulHandlerMapping.registerHandlers();
|
||||
this.routeLocator.resetRoutes();
|
||||
this.zuulHandlerMapping.registerHandlers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,8 +63,9 @@ public class ProxyRequestHelper {
|
||||
Map<String, List<String>> map = HTTPRequestUtils.getInstance().getQueryParams();
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
if (map == null)
|
||||
if (map == null) {
|
||||
return params;
|
||||
}
|
||||
|
||||
for (String key : map.keySet()) {
|
||||
|
||||
@@ -86,8 +87,9 @@ public class ProxyRequestHelper {
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String name = (String) headerNames.nextElement();
|
||||
String value = request.getHeader(name);
|
||||
if (isIncludedHeader(name))
|
||||
if (isIncludedHeader(name)) {
|
||||
headers.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> zuulRequestHeaders = context.getZuulRequestHeaders();
|
||||
@@ -129,8 +131,9 @@ public class ProxyRequestHelper {
|
||||
for (String value : header.getValue()) {
|
||||
ctx.addOriginResponseHeader(name, value);
|
||||
|
||||
if (name.equalsIgnoreCase("content-length"))
|
||||
if (name.equalsIgnoreCase("content-length")) {
|
||||
ctx.setOriginContentLength(value);
|
||||
}
|
||||
|
||||
if (isIncludedHeader(name)) {
|
||||
ctx.addZuulResponseHeader(name, value);
|
||||
@@ -179,7 +182,7 @@ public class ProxyRequestHelper {
|
||||
InputStream requestEntity) throws IOException {
|
||||
|
||||
Map<String, Object> info = new LinkedHashMap<String, Object>();
|
||||
if (traces != null) {
|
||||
if (this.traces != null) {
|
||||
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
StringBuilder query = new StringBuilder();
|
||||
@@ -216,7 +219,7 @@ public class ProxyRequestHelper {
|
||||
debugRequestEntity(info, ctx.getRequest().getInputStream());
|
||||
}
|
||||
}
|
||||
traces.add(info);
|
||||
this.traces.add(info);
|
||||
return info;
|
||||
}
|
||||
return info;
|
||||
@@ -224,7 +227,7 @@ public class ProxyRequestHelper {
|
||||
|
||||
public void appendDebug(Map<String, Object> info, int status,
|
||||
MultiValueMap<String, String> headers) {
|
||||
if (traces != null) {
|
||||
if (this.traces != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> trace = (Map<String, Object>) info.get("headers");
|
||||
Map<String, Object> output = new LinkedHashMap<String, Object>();
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters.post;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -14,53 +16,56 @@ import javax.servlet.RequestDispatcher;
|
||||
@Slf4j
|
||||
public class SendErrorFilter extends ZuulFilter {
|
||||
|
||||
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
|
||||
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
|
||||
|
||||
@Value("${error.path:/error}")
|
||||
private String errorPath;
|
||||
@Value("${error.path:/error}")
|
||||
private String errorPath;
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "post";
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "post";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
//only forward to errorPath if it hasn't been forwarded to already
|
||||
return ctx.containsKey("error.status_code") && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
|
||||
}
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
// only forward to errorPath if it hasn't been forwarded to already
|
||||
return ctx.containsKey("error.status_code")
|
||||
&& !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
int statusCode = (Integer)ctx.get("error.status_code");
|
||||
if (ctx.containsKey("error.exception")) {
|
||||
Object e = ctx.get("error.exception");
|
||||
log.warn("Error during filtering", Throwable.class.cast(e));
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.exception", e);
|
||||
}
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.status_code", statusCode);
|
||||
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(errorPath);
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
int statusCode = (Integer) ctx.get("error.status_code");
|
||||
if (ctx.containsKey("error.exception")) {
|
||||
Object e = ctx.get("error.exception");
|
||||
log.warn("Error during filtering", Throwable.class.cast(e));
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.exception", e);
|
||||
}
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.status_code", statusCode);
|
||||
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(
|
||||
this.errorPath);
|
||||
if (dispatcher != null) {
|
||||
ctx.set(SEND_ERROR_FILTER_RAN, true);
|
||||
if (!ctx.getResponse().isCommitted()) {
|
||||
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
|
||||
}
|
||||
if (!ctx.getResponse().isCommitted()) {
|
||||
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setErrorPath(String errorPath) {
|
||||
this.errorPath = errorPath;
|
||||
}
|
||||
public void setErrorPath(String errorPath) {
|
||||
this.errorPath = errorPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,14 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return !RequestContext.getCurrentContext().getZuulResponseHeaders().isEmpty()
|
||||
|| RequestContext.getCurrentContext().getResponseDataStream() != null
|
||||
|| RequestContext.getCurrentContext().getResponseBody() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
addResponseHeaders();
|
||||
@@ -64,8 +66,9 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
|
||||
// there is no body to send
|
||||
if (context.getResponseBody() == null && context.getResponseDataStream() == null)
|
||||
if (context.getResponseBody() == null && context.getResponseDataStream() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HttpServletResponse servletResponse = context.getResponse();
|
||||
servletResponse.setCharacterEncoding("UTF-8");
|
||||
@@ -82,8 +85,9 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
boolean isGzipRequested = false;
|
||||
final String requestEncoding = context.getRequest().getHeader(
|
||||
ZuulHeaders.ACCEPT_ENCODING);
|
||||
if (requestEncoding != null && requestEncoding.equals("gzip"))
|
||||
if (requestEncoding != null && requestEncoding.equals("gzip")) {
|
||||
isGzipRequested = true;
|
||||
}
|
||||
|
||||
is = context.getResponseDataStream();
|
||||
InputStream inputStream = is;
|
||||
@@ -93,7 +97,7 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
// decompress stream
|
||||
// before sending to client
|
||||
// else, stream gzip directly to client
|
||||
if (context.getResponseGZipped() && !isGzipRequested)
|
||||
if (context.getResponseGZipped() && !isGzipRequested) {
|
||||
try {
|
||||
inputStream = new GZIPInputStream(is);
|
||||
|
||||
@@ -106,8 +110,10 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
.toString());
|
||||
inputStream = is;
|
||||
}
|
||||
else if (context.getResponseGZipped() && isGzipRequested)
|
||||
}
|
||||
else if (context.getResponseGZipped() && isGzipRequested) {
|
||||
servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
writeResponse(inputStream, outStream);
|
||||
}
|
||||
}
|
||||
@@ -115,8 +121,9 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (is != null)
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
@@ -164,8 +171,9 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
for (String it : rd) {
|
||||
debugHeader.append("[[[" + it + "]]]");
|
||||
}
|
||||
if (INCLUDE_DEBUG_HEADER.get())
|
||||
if (INCLUDE_DEBUG_HEADER.get()) {
|
||||
servletResponse.addHeader("X-Zuul-Debug-Header", debugHeader.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (zuulResponseHeaders != null) {
|
||||
@@ -180,8 +188,9 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
// Only inserts Content-Length if origin provides it and origin response is not
|
||||
// gzipped
|
||||
if (SET_CONTENT_LENGTH.get()) {
|
||||
if (contentLength != null && !ctx.getResponseGZipped())
|
||||
if (contentLength != null && !ctx.getResponseGZipped()) {
|
||||
servletResponse.setContentLength(contentLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.netflix.config.DynamicBooleanProperty;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicStringProperty;
|
||||
@@ -7,42 +9,39 @@ import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.constants.ZuulConstants;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class DebugFilter extends ZuulFilter {
|
||||
|
||||
static final DynamicBooleanProperty routingDebug = DynamicPropertyFactory.getInstance()
|
||||
.getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false);
|
||||
static final DynamicStringProperty debugParameter = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug");
|
||||
static final DynamicBooleanProperty routingDebug = DynamicPropertyFactory
|
||||
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false);
|
||||
static final DynamicStringProperty debugParameter = DynamicPropertyFactory
|
||||
.getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug");
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean shouldFilter() {
|
||||
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||
if ("true".equals(request.getParameter(debugParameter.get())))
|
||||
return true;
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||
if ("true".equals(request.getParameter(debugParameter.get()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return routingDebug.get();
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
ctx.setDebugRouting(true);
|
||||
ctx.setDebugRequest(true);
|
||||
return null;
|
||||
}
|
||||
return routingDebug.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
ctx.setDebugRouting(true);
|
||||
ctx.setDebugRequest(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
protected Field requestField = null;
|
||||
|
||||
public FormBodyWrapperFilter() {
|
||||
requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req",
|
||||
HttpServletRequest.class);
|
||||
Assert.notNull(requestField, "HttpServletRequestWrapper.req field not found");
|
||||
requestField.setAccessible(true);
|
||||
this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class,
|
||||
"req", HttpServletRequest.class);
|
||||
Assert.notNull(this.requestField, "HttpServletRequestWrapper.req field not found");
|
||||
this.requestField.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,15 +48,17 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
String contentType = request.getContentType();
|
||||
|
||||
//Don't use this filter on GET method
|
||||
if(contentType == null) {
|
||||
// Don't use this filter on GET method
|
||||
if (contentType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Only use this filter for MediaType : application/x-www-form-urlencoded
|
||||
// Only use this filter for MediaType : application/x-www-form-urlencoded
|
||||
try {
|
||||
return MediaType.APPLICATION_FORM_URLENCODED.includes(MediaType.valueOf(contentType));
|
||||
} catch (InvalidMediaTypeException imte) {
|
||||
return MediaType.APPLICATION_FORM_URLENCODED.includes(MediaType
|
||||
.valueOf(contentType));
|
||||
}
|
||||
catch (InvalidMediaTypeException imte) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -67,8 +69,9 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
HttpServletRequest wrapped = (HttpServletRequest) requestField.get(request);
|
||||
requestField.set(request, new FormBodyRequestWrapper(wrapped));
|
||||
HttpServletRequest wrapped = (HttpServletRequest) this.requestField
|
||||
.get(request);
|
||||
this.requestField.set(request, new FormBodyRequestWrapper(wrapped));
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
Throwables.propagate(e);
|
||||
@@ -92,28 +95,29 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
if (contentData == null) {
|
||||
contentData = buildContentData();
|
||||
if (this.contentData == null) {
|
||||
this.contentData = buildContentData();
|
||||
}
|
||||
return contentData.length;
|
||||
return this.contentData.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
if (RequestContext.getCurrentContext().isChunkedRequestBody()) {
|
||||
return request.getInputStream();
|
||||
return this.request.getInputStream();
|
||||
}
|
||||
else {
|
||||
if (contentData == null) {
|
||||
contentData = buildContentData();
|
||||
if (this.contentData == null) {
|
||||
this.contentData = buildContentData();
|
||||
}
|
||||
return new ServletInputStreamWrapper(contentData);
|
||||
return new ServletInputStreamWrapper(this.contentData);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] buildContentData() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
for (Entry<String, String[]> entry : this.request.getParameterMap()
|
||||
.entrySet()) {
|
||||
for (String value : entry.getValue()) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append("&");
|
||||
|
||||
@@ -48,14 +48,14 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
|
||||
final String requestURI = ctx.getRequest().getRequestURI();
|
||||
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute(requestURI);
|
||||
ProxyRouteSpec route = this.routeLocator.getMatchingRoute(requestURI);
|
||||
|
||||
if (route != null) {
|
||||
|
||||
String location = route.getLocation();
|
||||
|
||||
if (location != null) {
|
||||
|
||||
|
||||
ctx.put("requestURI", route.getPath());
|
||||
ctx.put("proxy", route.getId());
|
||||
|
||||
@@ -70,7 +70,7 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
ctx.addOriginResponseHeader("X-Zuul-ServiceId", location);
|
||||
}
|
||||
|
||||
if (properties.isAddProxyHeaders()) {
|
||||
if (this.properties.isAddProxyHeaders()) {
|
||||
ctx.addZuulRequestHeader(
|
||||
"X-Forwarded-Host",
|
||||
ctx.getRequest().getServerName() + ":"
|
||||
|
||||
@@ -1,130 +1,142 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.HttpServletRequestWrapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class Servlet30WrapperFilter extends ZuulFilter {
|
||||
protected Field requestField = null;
|
||||
protected Field requestField = null;
|
||||
|
||||
public Servlet30WrapperFilter() {
|
||||
requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req",
|
||||
HttpServletRequest.class);
|
||||
Assert.notNull(requestField, "HttpServletRequestWrapper.req field not found");
|
||||
requestField.setAccessible(true);
|
||||
}
|
||||
public Servlet30WrapperFilter() {
|
||||
this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class,
|
||||
"req", HttpServletRequest.class);
|
||||
Assert.notNull(this.requestField, "HttpServletRequestWrapper.req field not found");
|
||||
this.requestField.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return true; //TODO: only if in servlet 3.0 env
|
||||
}
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return true; // TODO: only if in servlet 3.0 env
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
request = (HttpServletRequest) requestField.get(request);
|
||||
} catch (IllegalAccessException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
ctx.setRequest(new Servlet30RequestWrapper(request));
|
||||
//ctx.setResponse(new HttpServletResponseWrapper(ctx.getResponse()));
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
request = (HttpServletRequest) this.requestField.get(request);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
ctx.setRequest(new Servlet30RequestWrapper(request));
|
||||
// ctx.setResponse(new HttpServletResponseWrapper(ctx.getResponse()));
|
||||
return null;
|
||||
}
|
||||
|
||||
private class Servlet30RequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
private class Servlet30RequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
|
||||
Servlet30RequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
Servlet30RequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
return request.authenticate(response);
|
||||
}
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException,
|
||||
ServletException {
|
||||
return this.request.authenticate(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
request.login(username, password);
|
||||
}
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
this.request.login(username, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
request.logout();
|
||||
}
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
this.request.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
|
||||
return request.getParts();
|
||||
}
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException,
|
||||
ServletException {
|
||||
return this.request.getParts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
|
||||
return request.getPart(name);
|
||||
}
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, IllegalStateException,
|
||||
ServletException {
|
||||
return this.request.getPart(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return request.getServletContext();
|
||||
}
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return this.request.getServletContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return request.startAsync();
|
||||
}
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return this.request.startAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
return request.startAsync(servletRequest, servletResponse);
|
||||
}
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest,
|
||||
ServletResponse servletResponse) {
|
||||
return this.request.startAsync(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return request.isAsyncStarted();
|
||||
}
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return this.request.isAsyncStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return request.isAsyncSupported();
|
||||
}
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return this.request.isAsyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return request.getAsyncContext();
|
||||
}
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return this.request.getAsyncContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return request.getDispatcherType();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return this.request.getDispatcherType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,87 +22,94 @@ import com.netflix.zuul.context.RequestContext;
|
||||
/**
|
||||
* Hystrix wrapper around Eureka Ribbon command
|
||||
*
|
||||
* see original https://github.com/Netflix/zuul/blob/master/zuul-netflix/src/main/java/com/netflix/zuul/dependency/ribbon/hystrix/RibbonCommand.java
|
||||
* see original
|
||||
* https://github.com/Netflix/zuul/blob/master/zuul-netflix/src/main/java/com/
|
||||
* netflix/zuul/dependency/ribbon/hystrix/RibbonCommand.java
|
||||
*/
|
||||
public class RibbonCommand extends HystrixCommand<HttpResponse> {
|
||||
|
||||
private RestClient restClient;
|
||||
private Verb verb;
|
||||
private URI uri;
|
||||
private MultivaluedMap<String, String> headers;
|
||||
private MultivaluedMap<String, String> params;
|
||||
private InputStream requestEntity;
|
||||
private RestClient restClient;
|
||||
private Verb verb;
|
||||
private URI uri;
|
||||
private MultivaluedMap<String, String> headers;
|
||||
private MultivaluedMap<String, String> params;
|
||||
private InputStream requestEntity;
|
||||
|
||||
public RibbonCommand(RestClient restClient,
|
||||
Verb verb,
|
||||
String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params,
|
||||
InputStream requestEntity) throws URISyntaxException {
|
||||
this("default", restClient, verb, uri, headers, params, requestEntity);
|
||||
}
|
||||
public RibbonCommand(RestClient restClient, Verb verb, String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params, InputStream requestEntity)
|
||||
throws URISyntaxException {
|
||||
this("default", restClient, verb, uri, headers, params, requestEntity);
|
||||
}
|
||||
|
||||
public RibbonCommand(String commandKey,
|
||||
RestClient restClient,
|
||||
Verb verb,
|
||||
String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params,
|
||||
InputStream requestEntity) throws URISyntaxException {
|
||||
public RibbonCommand(String commandKey, RestClient restClient, Verb verb, String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params, InputStream requestEntity)
|
||||
throws URISyntaxException {
|
||||
|
||||
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(commandKey)).andCommandPropertiesDefaults(
|
||||
// we want to default to semaphore-isolation since this wraps
|
||||
// 2 others commands that are already thread isolated
|
||||
HystrixCommandProperties.Setter().withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
|
||||
.withExecutionIsolationSemaphoreMaxConcurrentRequests(DynamicPropertyFactory.getInstance().
|
||||
getIntProperty(ZuulConstants.ZUUL_EUREKA + commandKey + ".semaphore.maxSemaphores", 100).get())));
|
||||
super(
|
||||
Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(commandKey))
|
||||
.andCommandPropertiesDefaults(
|
||||
// we want to default to semaphore-isolation since this wraps
|
||||
// 2 others commands that are already thread isolated
|
||||
HystrixCommandProperties
|
||||
.Setter()
|
||||
.withExecutionIsolationStrategy(
|
||||
HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
|
||||
.withExecutionIsolationSemaphoreMaxConcurrentRequests(
|
||||
DynamicPropertyFactory
|
||||
.getInstance()
|
||||
.getIntProperty(
|
||||
ZuulConstants.ZUUL_EUREKA
|
||||
+ commandKey
|
||||
+ ".semaphore.maxSemaphores",
|
||||
100).get())));
|
||||
|
||||
this.restClient = restClient;
|
||||
this.verb = verb;
|
||||
this.uri = new URI(uri);
|
||||
this.headers = headers;
|
||||
this.params = params;
|
||||
this.requestEntity = requestEntity;
|
||||
}
|
||||
this.restClient = restClient;
|
||||
this.verb = verb;
|
||||
this.uri = new URI(uri);
|
||||
this.headers = headers;
|
||||
this.params = params;
|
||||
this.requestEntity = requestEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() throws Exception {
|
||||
try {
|
||||
return forward();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected HttpResponse run() throws Exception {
|
||||
try {
|
||||
return forward();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponse forward() throws Exception {
|
||||
private HttpResponse forward() throws Exception {
|
||||
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
|
||||
Builder builder = HttpRequest.newBuilder().
|
||||
verb(verb).
|
||||
uri(uri).
|
||||
entity(requestEntity);
|
||||
Builder builder = HttpRequest.newBuilder().verb(this.verb).uri(this.uri)
|
||||
.entity(this.requestEntity);
|
||||
|
||||
for (String name : headers.keySet()) {
|
||||
List<String> values = headers.get(name);
|
||||
for (String value : values) {
|
||||
builder.header(name, value);
|
||||
}
|
||||
}
|
||||
for (String name : this.headers.keySet()) {
|
||||
List<String> values = this.headers.get(name);
|
||||
for (String value : values) {
|
||||
builder.header(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : params.keySet()) {
|
||||
List<String> values = params.get(name);
|
||||
for (String value : values) {
|
||||
builder.queryParams(name, value);
|
||||
}
|
||||
}
|
||||
for (String name : this.params.keySet()) {
|
||||
List<String> values = this.params.get(name);
|
||||
for (String value : values) {
|
||||
builder.queryParams(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
HttpRequest httpClientRequest = builder.build();
|
||||
|
||||
HttpResponse response = restClient.executeWithLoadBalancer(httpClientRequest);
|
||||
context.set("ribbonResponse", response);
|
||||
return response;
|
||||
}
|
||||
HttpRequest httpClientRequest = builder.build();
|
||||
|
||||
HttpResponse response = this.restClient
|
||||
.executeWithLoadBalancer(httpClientRequest);
|
||||
context.set("ribbonResponse", response);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,25 +59,28 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
return (ctx.getRouteHost() == null && ctx.get("serviceId") != null && ctx
|
||||
.sendZuulResponse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = context.getRequest();
|
||||
|
||||
MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = helper
|
||||
MultiValueMap<String, String> headers = this.helper
|
||||
.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = this.helper
|
||||
.buildZuulRequestQueryParams(request);
|
||||
Verb verb = getVerb(request);
|
||||
InputStream requestEntity = getRequestBody(request);
|
||||
|
||||
String serviceId = (String) context.get("serviceId");
|
||||
|
||||
RestClient restClient = clientFactory.getClient(serviceId, RestClient.class);
|
||||
RestClient restClient = this.clientFactory.getClient(serviceId, RestClient.class);
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (context.get("requestURI") != null) {
|
||||
@@ -103,14 +106,14 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
|
||||
InputStream requestEntity) throws Exception {
|
||||
|
||||
Map<String, Object> info = helper.debug(verb.verb(), uri, headers, params,
|
||||
Map<String, Object> info = this.helper.debug(verb.verb(), uri, headers, params,
|
||||
requestEntity);
|
||||
|
||||
RibbonCommand command = new RibbonCommand(restClient, verb, uri,
|
||||
convertHeaders(headers), convertHeaders(params), requestEntity);
|
||||
try {
|
||||
HttpResponse response = command.execute();
|
||||
helper.appendDebug(info, response.getStatus(),
|
||||
this.helper.appendDebug(info, response.getStatus(),
|
||||
revertHeaders(response.getHeaders()));
|
||||
return response;
|
||||
}
|
||||
@@ -174,24 +177,30 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
}
|
||||
|
||||
Verb getVerb(String sMethod) {
|
||||
if (sMethod == null)
|
||||
if (sMethod == null) {
|
||||
return Verb.GET;
|
||||
}
|
||||
sMethod = sMethod.toLowerCase();
|
||||
if (sMethod.equals("post"))
|
||||
if (sMethod.equals("post")) {
|
||||
return Verb.POST;
|
||||
if (sMethod.equals("put"))
|
||||
}
|
||||
if (sMethod.equals("put")) {
|
||||
return Verb.PUT;
|
||||
if (sMethod.equals("delete"))
|
||||
}
|
||||
if (sMethod.equals("delete")) {
|
||||
return Verb.DELETE;
|
||||
if (sMethod.equals("options"))
|
||||
}
|
||||
if (sMethod.equals("options")) {
|
||||
return Verb.OPTIONS;
|
||||
if (sMethod.equals("head"))
|
||||
}
|
||||
if (sMethod.equals("head")) {
|
||||
return Verb.HEAD;
|
||||
}
|
||||
return Verb.GET;
|
||||
}
|
||||
|
||||
private void setResponse(HttpResponse resp) throws ClientException, IOException {
|
||||
helper.setResponse(resp.getStatus(),
|
||||
this.helper.setResponse(resp.getStatus(),
|
||||
!resp.hasEntity() ? null : resp.getInputStream(),
|
||||
revertHeaders(resp.getHeaders()));
|
||||
}
|
||||
|
||||
@@ -85,7 +85,8 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
private static final AtomicReference<HttpClient> CLIENT = new AtomicReference<HttpClient>(
|
||||
newClient());
|
||||
|
||||
private static final Timer CONNECTION_MANAGER_TIMER = new Timer("SimpleHostRoutingFilter.CONNECTION_MANAGER_TIMER", true);
|
||||
private static final Timer CONNECTION_MANAGER_TIMER = new Timer(
|
||||
"SimpleHostRoutingFilter.CONNECTION_MANAGER_TIMER", true);
|
||||
|
||||
// cleans expired connections at an interval
|
||||
static {
|
||||
@@ -96,8 +97,9 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
public void run() {
|
||||
try {
|
||||
final HttpClient hc = CLIENT.get();
|
||||
if (hc == null)
|
||||
if (hc == null) {
|
||||
return;
|
||||
}
|
||||
hc.getConnectionManager().closeExpiredConnections();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
@@ -153,6 +155,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
return 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return RequestContext.getCurrentContext().getRouteHost() != null
|
||||
&& RequestContext.getCurrentContext().sendZuulResponse();
|
||||
@@ -213,11 +216,13 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = context.getRequest();
|
||||
MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = helper
|
||||
MultiValueMap<String, String> headers = this.helper
|
||||
.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = this.helper
|
||||
.buildZuulRequestQueryParams(request);
|
||||
String verb = getVerb(request);
|
||||
InputStream requestEntity = getRequestBody(request);
|
||||
@@ -245,8 +250,8 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
MultiValueMap<String, String> params, InputStream requestEntity)
|
||||
throws Exception {
|
||||
|
||||
Map<String, Object> info = helper
|
||||
.debug(verb, uri, headers, params, requestEntity);
|
||||
Map<String, Object> info = this.helper.debug(verb, uri, headers, params,
|
||||
requestEntity);
|
||||
|
||||
URL host = RequestContext.getCurrentContext().getRouteHost();
|
||||
HttpHost httpHost = getHttpHost(host);
|
||||
@@ -277,7 +282,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
LOG.debug(httpHost.getHostName() + " " + httpHost.getPort() + " "
|
||||
+ httpHost.getSchemeName());
|
||||
HttpResponse zuulResponse = forwardRequest(httpclient, httpHost, httpRequest);
|
||||
helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(),
|
||||
this.helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(),
|
||||
revertHeaders(zuulResponse.getAllHeaders()));
|
||||
return zuulResponse;
|
||||
}
|
||||
@@ -346,7 +351,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
}
|
||||
|
||||
private void setResponse(HttpResponse response) throws IOException {
|
||||
helper.setResponse(response.getStatusLine().getStatusCode(),
|
||||
this.helper.setResponse(response.getStatusLine().getStatusCode(),
|
||||
response.getEntity() == null ? null : response.getEntity().getContent(),
|
||||
revertHeaders(response.getAllHeaders()));
|
||||
}
|
||||
@@ -359,14 +364,17 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
super(truststore);
|
||||
|
||||
TrustManager tm = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
@@ -374,19 +382,19 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
|
||||
TrustManager[] tms = new TrustManager[1];
|
||||
tms[0] = tm;
|
||||
sslContext.init(null, tms, null);
|
||||
this.sslContext.init(null, tms, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
|
||||
throws IOException, UnknownHostException {
|
||||
return sslContext.getSocketFactory().createSocket(socket, host, port,
|
||||
return this.sslContext.getSocketFactory().createSocket(socket, host, port,
|
||||
autoClose);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
return sslContext.getSocketFactory().createSocket();
|
||||
return this.sslContext.getSocketFactory().createSocket();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,8 @@ import org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ SimpleZuulServerApplicationTests.class, SampleZuulProxyApplicationTests.class })
|
||||
@SuiteClasses({ SimpleZuulServerApplicationTests.class,
|
||||
SampleZuulProxyApplicationTests.class })
|
||||
@Ignore
|
||||
public class AdhocTestSuite {
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -29,18 +29,20 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
public class ArchaiusAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context!=null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationCreated() {
|
||||
context = new AnnotationConfigApplicationContext(ArchaiusAutoConfiguration.class);
|
||||
AbstractConfiguration config = context.getBean(ConfigurableEnvironmentConfiguration.class);
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
AbstractConfiguration config = this.context
|
||||
.getBean(ConfigurableEnvironmentConfiguration.class);
|
||||
assertNotNull(config.getString("java.io.tmpdir"));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -26,6 +23,9 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -37,17 +37,19 @@ public class ArchaiusEndpointTests {
|
||||
@Test
|
||||
public void detectsPropertiesWhenSet() {
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
assertTrue(endpoint.invoke().containsKey("foo"));
|
||||
assertTrue(this.endpoint.invoke().containsKey("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotIncludeSpringEnvironment() {
|
||||
ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration(ConfigurationManager.getConfigInstance());
|
||||
ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration(new StandardEnvironment());
|
||||
ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration(
|
||||
ConfigurationManager.getConfigInstance());
|
||||
ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration(
|
||||
new StandardEnvironment());
|
||||
assertTrue(config.containsKey("user.dir"));
|
||||
composite.addConfiguration(config);
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
Map<String, Object> map = endpoint.invoke();
|
||||
Map<String, Object> map = this.endpoint.invoke();
|
||||
assertTrue(map.containsKey("foo"));
|
||||
assertFalse(map.containsKey("user.dir"));
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -28,6 +26,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -43,41 +43,45 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void offByDefault() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class);
|
||||
assertEquals(0, context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(
|
||||
0,
|
||||
context.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
Mockito.when(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.thenReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(
|
||||
1,
|
||||
context.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsPasssword() throws Exception {
|
||||
info.getMetadata().put("password", "bar");
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
this.info.getMetadata().put("password", "bar");
|
||||
Mockito.when(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.thenReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getUri());
|
||||
assertEquals("bar", locator.getPassword());
|
||||
assertEquals("user", locator.getUsername());
|
||||
@@ -85,23 +89,24 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void setsPath() throws Exception {
|
||||
info.getMetadata().put("configPath", "/bar");
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
this.info.getMetadata().put("configPath", "/bar");
|
||||
Mockito.when(this.client.getNextServerFromEureka("CONFIGSERVER", false))
|
||||
.thenReturn(this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/bar", locator.getUri());
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(context, env);
|
||||
context.getDefaultListableBeanFactory().registerSingleton("mockDiscoveryClient",
|
||||
client);
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
"mockDiscoveryClient", this.client);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class,
|
||||
ConfigClientProperties.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
@@ -28,6 +26,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -38,29 +38,30 @@ public class EurekaClientConfigServerAutoConfigurationTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void offByDefault() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
EurekaClientConfigServerAutoConfiguration.class);
|
||||
assertEquals(0,
|
||||
context.getBeanNamesForType(EurekaInstanceConfigBean.class).length);
|
||||
this.context.getBeanNamesForType(EurekaInstanceConfigBean.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
setup("spring.cloud.config.server.prefix=/config");
|
||||
assertEquals(1, context.getBeanNamesForType(EurekaInstanceConfig.class).length);
|
||||
EurekaInstanceConfig instance = context.getBean(EurekaInstanceConfig.class);
|
||||
assertEquals(1,
|
||||
this.context.getBeanNamesForType(EurekaInstanceConfig.class).length);
|
||||
EurekaInstanceConfig instance = this.context.getBean(EurekaInstanceConfig.class);
|
||||
assertEquals("/config", instance.getMetadataMap().get("configPath"));
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
context = new SpringApplicationBuilder(
|
||||
this.context = new SpringApplicationBuilder(
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
EurekaClientConfigServerAutoConfiguration.class,
|
||||
ConfigServerProperties.class, EurekaInstanceConfigBean.class).web(false)
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -29,6 +27,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -39,65 +39,64 @@ public class EurekaClientConfigBeanTests {
|
||||
|
||||
@After
|
||||
public void init() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicBinding() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.proxyHost=example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
assertEquals("example.com", context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.refresh();
|
||||
assertEquals("example.com", this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getProxyHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrl() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.serviceUrl.defaultZone:http://example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
assertEquals("{defaultZone=http://example.com}",
|
||||
context.getBean(EurekaClientConfigBean.class).getServiceUrl().toString());
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.getBean(EurekaClientConfigBean.class).getServiceUrl()
|
||||
.toString());
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrlWithCompositePropertySource() {
|
||||
CompositePropertySource source = new CompositePropertySource("composite");
|
||||
context.getEnvironment().getPropertySources().addFirst(source);
|
||||
this.context.getEnvironment().getPropertySources().addFirst(source);
|
||||
source.addPropertySource(new MapPropertySource("config", Collections
|
||||
.<String, Object> singletonMap("eureka.client.serviceUrl.defaultZone",
|
||||
"http://example.com")));
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
assertEquals("{defaultZone=http://example.com}",
|
||||
context.getBean(EurekaClientConfigBean.class).getServiceUrl().toString());
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.getBean(EurekaClientConfigBean.class).getServiceUrl()
|
||||
.toString());
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrlWithDefault() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.serviceUrl.defaultZone:http://example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.refresh();
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
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.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
@@ -30,6 +26,10 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.UniqueIdentifier;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -40,8 +40,8 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@After
|
||||
public void init() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test
|
||||
public void basicBinding() {
|
||||
addEnvironment(context, "eureka.instance.appGroupName=mygroup");
|
||||
addEnvironment(this.context, "eureka.instance.appGroupName=mygroup");
|
||||
setupContext();
|
||||
assertEquals("mygroup", getInstanceConfig().getAppGroupName());
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class EurekaInstanceConfigBeanTests {
|
||||
}
|
||||
|
||||
private void testNonSecurePort(String propName) {
|
||||
addEnvironment(context, propName + ":8888");
|
||||
addEnvironment(this.context, propName + ":8888");
|
||||
setupContext();
|
||||
assertEquals(8888, getInstanceConfig().getNonSecurePort());
|
||||
}
|
||||
@@ -95,13 +95,13 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testBadInitialStatus() {
|
||||
addEnvironment(context, "eureka.instance.initial-status:FOO");
|
||||
addEnvironment(this.context, "eureka.instance.initial-status:FOO");
|
||||
setupContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomInitialStatus() {
|
||||
addEnvironment(context, "eureka.instance.initial-status:STARTING");
|
||||
addEnvironment(this.context, "eureka.instance.initial-status:STARTING");
|
||||
setupContext();
|
||||
assertEquals("initialStatus wrong", InstanceStatus.STARTING, getInstanceConfig()
|
||||
.getInitialStatus());
|
||||
@@ -109,17 +109,17 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test
|
||||
public void testPerferIpAddress() throws Exception {
|
||||
addEnvironment(context, "eureka.instance.preferIpAddress:true");
|
||||
addEnvironment(this.context, "eureka.instance.preferIpAddress:true");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
assertTrue("Wrong hostname: " + instance.getHostname(),
|
||||
getInstanceConfig().getHostname().equals(instance.getIpAddress()));
|
||||
assertTrue("Wrong hostname: " + instance.getHostname(), getInstanceConfig()
|
||||
.getHostname().equals(instance.getIpAddress()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerferIpAddressInDatacenter() throws Exception {
|
||||
addEnvironment(context, "eureka.instance.preferIpAddress:true");
|
||||
addEnvironment(this.context, "eureka.instance.preferIpAddress:true");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
String id = ((UniqueIdentifier) instance.getDataCenterInfo()).getId();
|
||||
@@ -128,13 +128,13 @@ public class EurekaInstanceConfigBeanTests {
|
||||
}
|
||||
|
||||
private void setupContext() {
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
protected EurekaInstanceConfigBean getInstanceConfig() {
|
||||
return context.getBean(EurekaInstanceConfigBean.class);
|
||||
return this.context.getBean(EurekaInstanceConfigBean.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -25,21 +25,22 @@ public class EurekaSampleApplication {
|
||||
return new InMemoryMetricRepository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthCheckHandler healthCheckHandler() {
|
||||
return new HealthCheckHandler() {
|
||||
@Override
|
||||
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) {
|
||||
return InstanceInfo.InstanceStatus.UP;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Bean
|
||||
public HealthCheckHandler healthCheckHandler() {
|
||||
return new HealthCheckHandler() {
|
||||
@Override
|
||||
public InstanceInfo.InstanceStatus getStatus(
|
||||
InstanceInfo.InstanceStatus currentStatus) {
|
||||
return InstanceInfo.InstanceStatus.UP;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return "Hello world";
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(EurekaSampleApplication.class).web(true).run(args);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
@@ -28,6 +25,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -38,74 +38,75 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@DirtiesContext
|
||||
public class FeignClientTests extends FeignConfiguration {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
@Autowired
|
||||
TestClient testClient;
|
||||
TestClient testClient;
|
||||
|
||||
//@FeignClient(value = "http://localhost:9876", loadbalance = false)
|
||||
// @FeignClient(value = "http://localhost:9876", loadbalance = false)
|
||||
@FeignClient("feignclienttest")
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@FeignClientScan
|
||||
protected static class Application {
|
||||
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
public Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
public List<Hello> getHellos();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=feignclienttest", "management.contextPath=/admin")
|
||||
.run(args);
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@FeignClientScan
|
||||
protected static class Application {
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", testClient);
|
||||
assertTrue("testClient is not a java Proxy", Proxy.isProxyClass(testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(testClient);
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=feignclienttest",
|
||||
"management.contextPath=/admin").run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", this.testClient);
|
||||
assertTrue("testClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
//TODO: only works if port is hardcoded cant resolve ${local.server.port} in annotation
|
||||
/*@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}*/
|
||||
// TODO: only works if port is hardcoded cant resolve ${local.server.port} in
|
||||
// annotation
|
||||
/*
|
||||
* @Test public void testSimpleType() { Hello hello = testClient.getHello();
|
||||
* assertNotNull("hello was null", hello); assertEquals("first hello didn't match",
|
||||
* new Hello("hello world 1"), hello); }
|
||||
*/
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -20,8 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -29,85 +31,90 @@ import java.util.List;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SpringDecoderTests.Application.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest", "spring.jmx.enabled=true" })
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest",
|
||||
"spring.jmx.enabled=true" })
|
||||
@DirtiesContext
|
||||
public class SpringDecoderTests extends FeignConfiguration {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
public TestClient testClient() {
|
||||
return feign().target(TestClient.class, "http://localhost:"+port);
|
||||
}
|
||||
public TestClient testClient() {
|
||||
return feign().target(TestClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application implements TestClient {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application implements TestClient {
|
||||
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
@Override
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
@Override
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
@Override
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=springdecodertest", "management.contextPath=/admin")
|
||||
.run(args);
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=springdecodertest",
|
||||
"management.contextPath=/admin").run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient().getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient().getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserParameterizedTypeDecode() {
|
||||
List<Hello> hellos = testClient().getHellos();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hellos.get(0));
|
||||
}
|
||||
@Test
|
||||
public void testUserParameterizedTypeDecode() {
|
||||
List<Hello> hellos = testClient().getHellos();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"),
|
||||
hellos.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleParameterizedTypeDecode() {
|
||||
List<String> hellos = testClient().getHelloStrings();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
}
|
||||
@Test
|
||||
public void testSimpleParameterizedTypeDecode() {
|
||||
List<String> hellos = testClient().getHelloStrings();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Hello {
|
||||
private String message;
|
||||
}
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Hello {
|
||||
private String message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ public class HystrixConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void nonWebAppStartsUp() {
|
||||
new SpringApplicationBuilder(HystrixCircuitBreakerConfiguration.class).web(false).run().close();
|
||||
new SpringApplicationBuilder(HystrixCircuitBreakerConfiguration.class).web(false)
|
||||
.run().close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -19,9 +20,11 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -38,13 +41,15 @@ public class HystrixOnlyTests {
|
||||
|
||||
@Test
|
||||
public void testNormalExecution() {
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + port + "/", String.class);
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/", String.class);
|
||||
assertEquals("incorrect response", "Hello world", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureFallback() {
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + port + "/fail", String.class);
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/fail", String.class);
|
||||
assertEquals("incorrect fallback", "Fallback Hello world", s);
|
||||
}
|
||||
|
||||
@@ -59,12 +64,14 @@ public class HystrixOnlyTests {
|
||||
@Test
|
||||
public void testNoDiscoveryHealth() {
|
||||
Map map = getHealth();
|
||||
//There is explicitly no discovery, so there should be no discovery health key
|
||||
assertFalse("Incorrect existing discovery health key", map.containsKey("discovery"));
|
||||
// There is explicitly no discovery, so there should be no discovery health key
|
||||
assertFalse("Incorrect existing discovery health key",
|
||||
map.containsKey("discovery"));
|
||||
}
|
||||
|
||||
private Map getHealth() {
|
||||
return new TestRestTemplate().getForObject("http://localhost:" + port + "/admin/health", Map.class);
|
||||
return new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/admin/health", Map.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +91,7 @@ class Service {
|
||||
}
|
||||
}
|
||||
|
||||
//Don't use @SpringBootApplication because we don't want to component scan
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableCircuitBreaker
|
||||
@@ -101,12 +108,12 @@ class HystrixOnlyApplication {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return service.hello();
|
||||
return this.service.hello();
|
||||
}
|
||||
|
||||
@RequestMapping("/fail")
|
||||
public String fail() {
|
||||
return service.fail();
|
||||
return this.service.fail();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
|
||||
@@ -46,7 +46,7 @@ public class PlainRibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -36,6 +34,8 @@ import com.netflix.loadbalancer.AvailabilityFilteringRule;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -51,7 +51,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void ruleDefaultsToAvailability() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
AvailabilityFilteringRule.class.cast(loadBalancer.getRule());
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListFilterOverride() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
assertEquals("myTestZone",
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter())
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -24,10 +22,6 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.TestConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList;
|
||||
import org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration;
|
||||
@@ -42,6 +36,8 @@ import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -57,7 +53,7 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
@@ -65,7 +61,7 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void ruleDefaultsToZoneAvoidance() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
ZoneAvoidanceRule.class.cast(loadBalancer.getRule());
|
||||
}
|
||||
@@ -73,10 +69,11 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListFilterOverride() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
assertEquals("myTestZone",
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()).getZone());
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter())
|
||||
.getZone());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -17,77 +18,82 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptorTests {
|
||||
|
||||
@Mock
|
||||
HttpRequest request;
|
||||
@Mock
|
||||
HttpRequest request;
|
||||
|
||||
@Mock
|
||||
ClientHttpRequestExecution execution;
|
||||
@Mock
|
||||
ClientHttpRequestExecution execution;
|
||||
|
||||
@Mock
|
||||
ClientHttpResponse response;
|
||||
@Mock
|
||||
ClientHttpResponse response;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept() throws Exception {
|
||||
RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080));
|
||||
RibbonInterceptor interceptor = new RibbonInterceptor(new MyClient(server));
|
||||
@Test
|
||||
public void testIntercept() throws Exception {
|
||||
RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080));
|
||||
RibbonInterceptor interceptor = new RibbonInterceptor(new MyClient(server));
|
||||
|
||||
when(request.getURI()).thenReturn(new URL("http://myservice").toURI());
|
||||
when(execution.execute(isA(HttpRequest.class), isA(byte[].class))).thenReturn(response);
|
||||
ArgumentCaptor<HttpRequestWrapper> argument = ArgumentCaptor.forClass(HttpRequestWrapper.class);
|
||||
when(this.request.getURI()).thenReturn(new URL("http://myservice").toURI());
|
||||
when(this.execution.execute(isA(HttpRequest.class), isA(byte[].class)))
|
||||
.thenReturn(this.response);
|
||||
ArgumentCaptor<HttpRequestWrapper> argument = ArgumentCaptor
|
||||
.forClass(HttpRequestWrapper.class);
|
||||
|
||||
ClientHttpResponse response = interceptor.intercept(request, new byte[0], execution);
|
||||
ClientHttpResponse response = interceptor.intercept(this.request, new byte[0],
|
||||
this.execution);
|
||||
|
||||
assertNotNull("response was null", response);
|
||||
verify(execution).execute(argument.capture(), isA(byte[].class));
|
||||
HttpRequestWrapper wrapper = argument.getValue();
|
||||
assertEquals("wrong constructed uri", new URL("http://myhost:8080").toURI(), wrapper.getURI());
|
||||
}
|
||||
assertNotNull("response was null", response);
|
||||
verify(this.execution).execute(argument.capture(), isA(byte[].class));
|
||||
HttpRequestWrapper wrapper = argument.getValue();
|
||||
assertEquals("wrong constructed uri", new URL("http://myhost:8080").toURI(),
|
||||
wrapper.getURI());
|
||||
}
|
||||
|
||||
protected static class MyClient implements LoadBalancerClient {
|
||||
ServiceInstance instance;
|
||||
protected static class MyClient implements LoadBalancerClient {
|
||||
ServiceInstance instance;
|
||||
|
||||
public MyClient(ServiceInstance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
public MyClient(ServiceInstance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return instance;
|
||||
}
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
try {
|
||||
return request.apply(instance);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
try {
|
||||
return request.apply(this.instance);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
return UriComponentsBuilder.fromUri(original)
|
||||
.host(instance.getHost())
|
||||
.port(instance.getPort())
|
||||
.build()
|
||||
.toUri();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
return UriComponentsBuilder.fromUri(original).host(instance.getHost())
|
||||
.port(instance.getPort()).build().toUri();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
@@ -25,113 +17,130 @@ import com.netflix.loadbalancer.LoadBalancerStats;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerClientTests {
|
||||
|
||||
@Mock
|
||||
SpringClientFactory clientFactory;
|
||||
@Mock
|
||||
SpringClientFactory clientFactory;
|
||||
|
||||
@Mock
|
||||
BaseLoadBalancer loadBalancer;
|
||||
@Mock
|
||||
BaseLoadBalancer loadBalancer;
|
||||
|
||||
@Mock
|
||||
LoadBalancerStats loadBalancerStats;
|
||||
@Mock
|
||||
LoadBalancerStats loadBalancerStats;
|
||||
|
||||
@Mock
|
||||
ServerStats serverStats;
|
||||
@Mock
|
||||
ServerStats serverStats;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Mockito.when(clientFactory.getLoadBalancerContext(anyString())).thenReturn(new RibbonLoadBalancerContext(loadBalancer));
|
||||
}
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Mockito.when(this.clientFactory.getLoadBalancerContext(anyString())).thenReturn(
|
||||
new RibbonLoadBalancerContext(this.loadBalancer));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reconstructURI() throws Exception {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
URI uri = client.reconstructURI(serviceInstance, new URL("http://" + server.serviceId).toURI());
|
||||
assertEquals(server.getHost(), uri.getHost());
|
||||
assertEquals(server.getPort(), uri.getPort());
|
||||
}
|
||||
@Test
|
||||
public void reconstructURI() throws Exception {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
URI uri = client.reconstructURI(serviceInstance, new URL("http://"
|
||||
+ server.serviceId).toURI());
|
||||
assertEquals(server.getHost(), uri.getHost());
|
||||
assertEquals(server.getPort(), uri.getPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChoose() {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
assertServiceInstance(server, serviceInstance);
|
||||
}
|
||||
@Test
|
||||
public void testChoose() {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
assertServiceInstance(server, serviceInstance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute() {
|
||||
final RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
@Test
|
||||
public void testExecute() {
|
||||
final RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
|
||||
final String returnVal = "myval";
|
||||
Object actualReturn = client.execute(server.getServiceId(), new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(server, instance);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
final String returnVal = "myval";
|
||||
Object actualReturn = client.execute(server.getServiceId(),
|
||||
new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(server, instance);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
|
||||
verifyServerStats();
|
||||
verifyServerStats();
|
||||
|
||||
assertEquals("retVal was wrong", returnVal, actualReturn);
|
||||
}
|
||||
assertEquals("retVal was wrong", returnVal, actualReturn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteException() {
|
||||
final RibbonServer ribbonServer = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer);
|
||||
|
||||
@Test
|
||||
public void testExecuteException() {
|
||||
final RibbonServer ribbonServer = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer);
|
||||
try {
|
||||
client.execute(ribbonServer.getServiceId(),
|
||||
new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(ribbonServer, instance);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
fail("Should have thrown exception");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertNotNull(e);
|
||||
}
|
||||
|
||||
try {
|
||||
client.execute(ribbonServer.getServiceId(), new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(ribbonServer, instance);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
fail("Should have thrown exception");
|
||||
} catch (Exception e) {
|
||||
assertNotNull(e);
|
||||
}
|
||||
verifyServerStats();
|
||||
}
|
||||
|
||||
verifyServerStats();
|
||||
}
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080));
|
||||
}
|
||||
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080));
|
||||
}
|
||||
protected void verifyServerStats() {
|
||||
verify(this.serverStats).incrementActiveRequestsCount();
|
||||
verify(this.serverStats).decrementActiveRequestsCount();
|
||||
verify(this.serverStats).incrementNumRequests();
|
||||
verify(this.serverStats).noteResponseTime(anyDouble());
|
||||
}
|
||||
|
||||
protected void verifyServerStats() {
|
||||
verify(serverStats).incrementActiveRequestsCount();
|
||||
verify(serverStats).decrementActiveRequestsCount();
|
||||
verify(serverStats).incrementNumRequests();
|
||||
verify(serverStats).noteResponseTime(anyDouble());
|
||||
}
|
||||
protected void assertServiceInstance(RibbonServer ribbonServer,
|
||||
ServiceInstance instance) {
|
||||
assertNotNull("instance was null", instance);
|
||||
assertEquals("serviceId was wrong", ribbonServer.getServiceId(),
|
||||
instance.getServiceId());
|
||||
assertEquals("host was wrong", ribbonServer.getHost(), instance.getHost());
|
||||
assertEquals("port was wrong", ribbonServer.getPort(), instance.getPort());
|
||||
}
|
||||
|
||||
protected void assertServiceInstance(RibbonServer ribbonServer, ServiceInstance instance) {
|
||||
assertNotNull("instance was null", instance);
|
||||
assertEquals("serviceId was wrong", ribbonServer.getServiceId(), instance.getServiceId());
|
||||
assertEquals("host was wrong", ribbonServer.getHost(), instance.getHost());
|
||||
assertEquals("port was wrong", ribbonServer.getPort(), instance.getPort());
|
||||
}
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(
|
||||
RibbonServer ribbonServer) {
|
||||
when(this.loadBalancer.getName()).thenReturn(ribbonServer.getServiceId());
|
||||
when(this.loadBalancer.chooseServer(anyString())).thenReturn(ribbonServer.server);
|
||||
when(this.loadBalancer.getLoadBalancerStats()).thenReturn(this.loadBalancerStats);
|
||||
when(this.loadBalancerStats.getSingleServerStat(ribbonServer.server)).thenReturn(
|
||||
this.serverStats);
|
||||
when(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())).thenReturn(
|
||||
this.loadBalancer);
|
||||
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(RibbonServer ribbonServer) {
|
||||
when(loadBalancer.getName()).thenReturn(ribbonServer.getServiceId());
|
||||
when(loadBalancer.chooseServer(anyString())).thenReturn(ribbonServer.server);
|
||||
when(loadBalancer.getLoadBalancerStats()).thenReturn(loadBalancerStats);
|
||||
when(loadBalancerStats.getSingleServerStat(ribbonServer.server)).thenReturn(serverStats);
|
||||
when(clientFactory.getLoadBalancer(loadBalancer.getName())).thenReturn(loadBalancer);
|
||||
|
||||
return new RibbonLoadBalancerClient(clientFactory);
|
||||
}
|
||||
return new RibbonLoadBalancerClient(this.clientFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
@@ -24,6 +22,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
|
||||
import com.netflix.client.DefaultLoadBalancerRetryHandler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -34,14 +34,15 @@ public class SpringClientFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testConfigureRetry() {
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(ArchaiusAutoConfiguration.class);
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
EnvironmentTestUtils.addEnvironment(parent, "foo.ribbon.MaxAutoRetries:2");
|
||||
factory.setApplicationContext(parent);
|
||||
DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) factory
|
||||
this.factory.setApplicationContext(parent);
|
||||
DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) this.factory
|
||||
.getLoadBalancerContext("foo").getRetryHandler();
|
||||
assertEquals(2, retryHandler.getMaxRetriesOnSameServer());
|
||||
parent.close();
|
||||
factory.destroy();
|
||||
this.factory.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -19,81 +13,97 @@ import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DomainExtractingServerListTests {
|
||||
|
||||
static final String IP_ADDR = "10.0.0.2";
|
||||
static final int PORT = 8080;
|
||||
static final String ZONE = "myzone.mydomain.com";
|
||||
static final String HOST_NAME = "myHostName."+ZONE;
|
||||
static final String INSTANCE_ID = "myInstanceId";
|
||||
static final String IP_ADDR = "10.0.0.2";
|
||||
static final int PORT = 8080;
|
||||
static final String ZONE = "myzone.mydomain.com";
|
||||
static final String HOST_NAME = "myHostName." + ZONE;
|
||||
static final String INSTANCE_ID = "myInstanceId";
|
||||
|
||||
@Test
|
||||
public void testDomainExtractingServer() {
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(new DefaultClientConfigImpl(), true);
|
||||
@Test
|
||||
public void testDomainExtractingServer() {
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(
|
||||
new DefaultClientConfigImpl(), true);
|
||||
|
||||
List<Server> servers = serverList.getInitialListOfServers();
|
||||
assertNotNull("servers was null", servers);
|
||||
assertEquals("servers was not size 1", 1, servers.size());
|
||||
List<Server> servers = serverList.getInitialListOfServers();
|
||||
assertNotNull("servers was null", servers);
|
||||
assertEquals("servers was not size 1", 1, servers.size());
|
||||
|
||||
DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE);
|
||||
assertEquals("hostPort was wrong", HOST_NAME+":"+PORT, des.getHostPort());
|
||||
}
|
||||
DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE);
|
||||
assertEquals("hostPort was wrong", HOST_NAME + ":" + PORT, des.getHostPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainExtractingServerDontApproximateZone() {
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(new DefaultClientConfigImpl(), false);
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(
|
||||
new DefaultClientConfigImpl(), false);
|
||||
|
||||
List<Server> servers = serverList.getInitialListOfServers();
|
||||
assertNotNull("servers was null", servers);
|
||||
assertEquals("servers was not size 1", 1, servers.size());
|
||||
|
||||
DomainExtractingServer des = assertDomainExtractingServer(servers, null);
|
||||
assertEquals("hostPort was wrong", HOST_NAME+":"+PORT, des.getHostPort());
|
||||
assertEquals("hostPort was wrong", HOST_NAME + ":" + PORT, des.getHostPort());
|
||||
}
|
||||
|
||||
protected DomainExtractingServer assertDomainExtractingServer(List<Server> servers, String zone) {
|
||||
Server actualServer = servers.get(0);
|
||||
assertTrue("server was not a DomainExtractingServer", actualServer instanceof DomainExtractingServer);
|
||||
DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer);
|
||||
assertEquals("zone was wrong", zone, des.getZone());
|
||||
assertEquals("instanceId was wrong", INSTANCE_ID, des.getId());
|
||||
return des;
|
||||
}
|
||||
protected DomainExtractingServer assertDomainExtractingServer(List<Server> servers,
|
||||
String zone) {
|
||||
Server actualServer = servers.get(0);
|
||||
assertTrue("server was not a DomainExtractingServer",
|
||||
actualServer instanceof DomainExtractingServer);
|
||||
DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer);
|
||||
assertEquals("zone was wrong", zone, des.getZone());
|
||||
assertEquals("instanceId was wrong", INSTANCE_ID, des.getId());
|
||||
return des;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainExtractingServerUseIpAddress() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true);
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(config, true);
|
||||
@Test
|
||||
public void testDomainExtractingServerUseIpAddress() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true);
|
||||
DomainExtractingServerList serverList = getDomainExtractingServerList(config,
|
||||
true);
|
||||
|
||||
List<Server> servers = serverList.getInitialListOfServers();
|
||||
assertNotNull("servers was null", servers);
|
||||
assertEquals("servers was not size 1", 1, servers.size());
|
||||
List<Server> servers = serverList.getInitialListOfServers();
|
||||
assertNotNull("servers was null", servers);
|
||||
assertEquals("servers was not size 1", 1, servers.size());
|
||||
|
||||
DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE);
|
||||
assertEquals("hostPort was wrong", IP_ADDR+":"+PORT, des.getHostPort());
|
||||
}
|
||||
DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE);
|
||||
assertEquals("hostPort was wrong", IP_ADDR + ":" + PORT, des.getHostPort());
|
||||
}
|
||||
|
||||
protected DomainExtractingServerList getDomainExtractingServerList(DefaultClientConfigImpl config, boolean approximateZoneFromHostname) {
|
||||
DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class);
|
||||
protected DomainExtractingServerList getDomainExtractingServerList(
|
||||
DefaultClientConfigImpl config, boolean approximateZoneFromHostname) {
|
||||
DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
ServerList<Server> originalServerList = mock(ServerList.class);
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
|
||||
when(server.getInstanceInfo()).thenReturn(instanceInfo);
|
||||
when(server.getHost()).thenReturn(HOST_NAME);
|
||||
when(server.getInstanceInfo()).thenReturn(instanceInfo);
|
||||
when(server.getHost()).thenReturn(HOST_NAME);
|
||||
|
||||
when(instanceInfo.getMetadata()).thenReturn(ImmutableMap.<String, String>builder().put("instanceId", INSTANCE_ID).build());
|
||||
when(instanceInfo.getHostName()).thenReturn(HOST_NAME);
|
||||
when(instanceInfo.getIPAddr()).thenReturn(IP_ADDR);
|
||||
when(instanceInfo.getPort()).thenReturn(PORT);
|
||||
when(instanceInfo.getMetadata()).thenReturn(
|
||||
ImmutableMap.<String, String> builder().put("instanceId", INSTANCE_ID)
|
||||
.build());
|
||||
when(instanceInfo.getHostName()).thenReturn(HOST_NAME);
|
||||
when(instanceInfo.getIPAddr()).thenReturn(IP_ADDR);
|
||||
when(instanceInfo.getPort()).thenReturn(PORT);
|
||||
|
||||
when(originalServerList.getInitialListOfServers()).thenReturn(Arrays.<Server>asList(server));
|
||||
when(originalServerList.getInitialListOfServers()).thenReturn(
|
||||
Arrays.<Server> asList(server));
|
||||
|
||||
return new DomainExtractingServerList(originalServerList, config, approximateZoneFromHostname);
|
||||
}
|
||||
return new DomainExtractingServerList(originalServerList, config,
|
||||
approximateZoneFromHostname);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,11 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@@ -33,6 +28,11 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
|
||||
@@ -50,7 +50,7 @@ public class EurekaRibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void ruleDefaultsToZoneAvoidance() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
ZoneAvoidanceRule.class.cast(loadBalancer.getRule());
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -26,6 +24,8 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -34,17 +34,18 @@ public class ZonePreferenceServerListFilterTests {
|
||||
|
||||
private Server dsyer = new Server("dsyer", 8080);
|
||||
private Server localhost = new Server("localhost", 8080);
|
||||
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
dsyer.setZone("dsyer");
|
||||
localhost.setZone("localhost");
|
||||
this.dsyer.setZone("dsyer");
|
||||
this.localhost.setZone("localhost");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noZoneSet() {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays.asList(localhost));
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays
|
||||
.asList(this.localhost));
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
@@ -52,7 +53,8 @@ public class ZonePreferenceServerListFilterTests {
|
||||
public void withZoneSetAndNoMatches() {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
ReflectionTestUtils.setField(filter, "zone", "dsyer");
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays.asList(localhost));
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays
|
||||
.asList(this.localhost));
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
@@ -60,7 +62,8 @@ public class ZonePreferenceServerListFilterTests {
|
||||
public void withZoneSetAndMatches() {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
ReflectionTestUtils.setField(filter, "zone", "dsyer");
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays.asList(dsyer, localhost));
|
||||
List<Server> result = filter.getFilteredListOfServers(Arrays.asList(this.dsyer,
|
||||
this.localhost));
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -38,11 +36,12 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = FormZuulProxyApplication.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port: 0",
|
||||
"zuul.routes.simple: /simple/**" })
|
||||
@IntegrationTest({ "server.port: 0", "zuul.routes.simple: /simple/**" })
|
||||
@DirtiesContext
|
||||
public class FormZuulProxyApplicationTests {
|
||||
|
||||
@@ -62,8 +61,9 @@ public class FormZuulProxyApplicationTests {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/simple", HttpMethod.POST,
|
||||
new HttpEntity<MultiValueMap<String,String>>(form, headers), String.class);
|
||||
"http://localhost:" + this.port + "/simple", HttpMethod.POST,
|
||||
new HttpEntity<MultiValueMap<String, String>>(form, headers),
|
||||
String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Posted! {foo=[bar]}", result.getBody());
|
||||
}
|
||||
@@ -73,16 +73,18 @@ public class FormZuulProxyApplicationTests {
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
||||
form.set("foo", "bar");
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE+"; charset=UTF-8"));
|
||||
headers.setContentType(MediaType
|
||||
.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8"));
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/simple", HttpMethod.POST,
|
||||
new HttpEntity<MultiValueMap<String,String>>(form, headers), String.class);
|
||||
"http://localhost:" + this.port + "/simple", HttpMethod.POST,
|
||||
new HttpEntity<MultiValueMap<String, String>>(form, headers),
|
||||
String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Posted! {foo=[bar]}", result.getBody());
|
||||
}
|
||||
}
|
||||
|
||||
//Don't use @SpringBootApplication because we don't want to component scan
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@@ -126,7 +128,7 @@ class FormZuulProxyApplication {
|
||||
|
||||
}
|
||||
|
||||
//Load balancer with fixed server list for "simple" pointing to localhost
|
||||
// Load balancer with fixed server list for "simple" pointing to localhost
|
||||
@Configuration
|
||||
class FormRibbonClientConfiguration {
|
||||
@Bean
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -19,6 +12,13 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
@@ -41,12 +41,13 @@ public class ProxyRouteLocatorTests {
|
||||
public void init() {
|
||||
initMocks(this);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPath() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
|
||||
properties.init();
|
||||
this.properties.init();
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
|
||||
assertEquals("foo", route.getLocation());
|
||||
@@ -55,10 +56,11 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPathWithPrefix() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**"));
|
||||
this.properties.setPrefix("/proxy");
|
||||
properties.init();
|
||||
this.properties.init();
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
|
||||
assertEquals("foo", route.getLocation());
|
||||
@@ -67,8 +69,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPathWithNoPrefixStripping() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo", new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
this.properties.setStripPrefix(false);
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
@@ -79,7 +83,8 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPathWithLocalPrefixStripping() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo"));
|
||||
this.properties.setStripPrefix(false);
|
||||
this.properties.setPrefix("/proxy");
|
||||
@@ -91,8 +96,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPathWithGlobalPrefixStripping() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put("foo", new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put("foo",
|
||||
new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
this.properties.setPrefix("/proxy");
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1");
|
||||
@@ -102,11 +109,12 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetMatchingPathWithRoutePrefixStripping() throws Exception {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
ZuulRoute zuulRoute = new ZuulRoute("/foo/**");
|
||||
zuulRoute.setStripPrefix(true);
|
||||
this.properties.getRoutes().put("foo", zuulRoute);
|
||||
properties.init();
|
||||
this.properties.init();
|
||||
routeLocator.getRoutes(); // force refresh
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1");
|
||||
assertEquals("foo", route.getLocation());
|
||||
@@ -115,9 +123,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetRoutes() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**"));
|
||||
properties.init();
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/" + ASERVICE + "/**"));
|
||||
this.properties.init();
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
|
||||
@@ -128,8 +137,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetRoutesWithMapping() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", ASERVICE));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE,
|
||||
new ZuulRoute("/" + ASERVICE + "/**", ASERVICE));
|
||||
this.properties.setPrefix("/foo");
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
@@ -138,8 +149,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetPhysicalRoutes() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", "http://" + ASERVICE));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE,
|
||||
new ZuulRoute("/" + ASERVICE + "/**", "http://" + ASERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
|
||||
@@ -150,7 +163,8 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultRoute() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", ASERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
@@ -162,8 +176,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultPhysicalRoute() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", "http://" + ASERVICE));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.getRoutes().put(ASERVICE,
|
||||
new ZuulRoute("/**", "http://" + ASERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
|
||||
@@ -174,11 +190,11 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testIgnoreRoutes() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
this.properties.setIgnoredServices(Lists.newArrayList(IGNOREDSERVICE));
|
||||
|
||||
when(discovery.getServices()).thenReturn(
|
||||
Lists.newArrayList(IGNOREDSERVICE));
|
||||
when(this.discovery.getServices()).thenReturn(Lists.newArrayList(IGNOREDSERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
String serviceId = routesMap.get(getMapping(IGNOREDSERVICE));
|
||||
@@ -187,10 +203,10 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testAutoRoutes() {
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
|
||||
when(discovery.getServices()).thenReturn(
|
||||
Lists.newArrayList(MYSERVICE));
|
||||
when(this.discovery.getServices()).thenReturn(Lists.newArrayList(MYSERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
|
||||
@@ -201,11 +217,14 @@ public class ProxyRouteLocatorTests {
|
||||
|
||||
@Test
|
||||
public void testAutoRoutesCanBeOverridden() {
|
||||
this.properties.getRoutes().put(MYSERVICE, new ZuulRoute("/"+MYSERVICE + "/**", "http://example.com/" + MYSERVICE));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.properties.getRoutes()
|
||||
.put(MYSERVICE,
|
||||
new ZuulRoute("/" + MYSERVICE + "/**", "http://example.com/"
|
||||
+ MYSERVICE));
|
||||
ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery,
|
||||
this.properties);
|
||||
|
||||
when(discovery.getServices()).thenReturn(
|
||||
Lists.newArrayList(MYSERVICE));
|
||||
when(this.discovery.getServices()).thenReturn(Lists.newArrayList(MYSERVICE));
|
||||
|
||||
Map<String, String> routesMap = routeLocator.getRoutes();
|
||||
|
||||
@@ -217,22 +236,22 @@ public class ProxyRouteLocatorTests {
|
||||
protected void assertMapping(Map<String, String> routesMap, String serviceId) {
|
||||
assertMapping(routesMap, serviceId, serviceId);
|
||||
}
|
||||
|
||||
protected void assertMapping(Map<String, String> routesMap, String expectedRoute, String key) {
|
||||
|
||||
protected void assertMapping(Map<String, String> routesMap, String expectedRoute,
|
||||
String key) {
|
||||
String mapping = getMapping(key);
|
||||
String route = routesMap.get(mapping);
|
||||
assertEquals("routesMap had wrong value for " + mapping, expectedRoute,
|
||||
route);
|
||||
assertEquals("routesMap had wrong value for " + mapping, expectedRoute, route);
|
||||
}
|
||||
|
||||
private String getMapping(String serviceId) {
|
||||
return "/" + serviceId + "/**";
|
||||
}
|
||||
|
||||
protected void assertDefaultMapping(Map<String, String> routesMap, String expectedRoute) {
|
||||
protected void assertDefaultMapping(Map<String, String> routesMap,
|
||||
String expectedRoute) {
|
||||
String mapping = "/**";
|
||||
String route = routesMap.get(mapping);
|
||||
assertEquals("routesMap had wrong value for " + mapping, expectedRoute,
|
||||
route);
|
||||
assertEquals("routesMap had wrong value for " + mapping, expectedRoute, route);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -34,13 +32,14 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SampleZuulProxyApplication.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port: 0",
|
||||
"zuul.routes.other: /test/**=http://localhost:7777/local",
|
||||
"zuul.routes.another: /another/twolevel/**",
|
||||
"zuul.routes.simple: /simple/**" })
|
||||
"zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**" })
|
||||
@DirtiesContext
|
||||
public class SampleZuulProxyApplicationTests {
|
||||
|
||||
@@ -55,18 +54,19 @@ public class SampleZuulProxyApplicationTests {
|
||||
|
||||
@Test
|
||||
public void bindRouteUsingPhysicalRoute() {
|
||||
assertEquals("http://localhost:7777/local", routes.getRoutes().get("/test/**"));
|
||||
assertEquals("http://localhost:7777/local",
|
||||
this.routes.getRoutes().get("/test/**"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindRouteUsingOnlyPath() {
|
||||
assertEquals("simple", routes.getRoutes().get("/simple/**"));
|
||||
assertEquals("simple", this.routes.getRoutes().get("/simple/**"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getOnSelfViaRibbonRoutingFilter() {
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/simple/local/1", HttpMethod.GET,
|
||||
"http://localhost:" + this.port + "/simple/local/1", HttpMethod.GET,
|
||||
new HttpEntity<>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Gotten!", result.getBody());
|
||||
@@ -74,10 +74,10 @@ public class SampleZuulProxyApplicationTests {
|
||||
|
||||
@Test
|
||||
public void deleteOnSelfViaSimpleHostRoutingFilter() {
|
||||
routes.addRoute("/self/**", "http://localhost:" + port + "/local");
|
||||
endpoint.reset();
|
||||
this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local");
|
||||
this.endpoint.reset();
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/self/1", HttpMethod.DELETE,
|
||||
"http://localhost:" + this.port + "/self/1", HttpMethod.DELETE,
|
||||
new HttpEntity<>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Deleted!", result.getBody());
|
||||
@@ -86,7 +86,7 @@ public class SampleZuulProxyApplicationTests {
|
||||
@Test
|
||||
public void testNotFound() {
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/myinvalidpath", HttpMethod.GET,
|
||||
"http://localhost:" + this.port + "/myinvalidpath", HttpMethod.GET,
|
||||
new HttpEntity<>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode());
|
||||
}
|
||||
@@ -94,22 +94,21 @@ public class SampleZuulProxyApplicationTests {
|
||||
@Test
|
||||
public void getSecondLevel() {
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/another/twolevel/local/1", HttpMethod.GET,
|
||||
new HttpEntity<>((Void) null), String.class);
|
||||
"http://localhost:" + this.port + "/another/twolevel/local/1",
|
||||
HttpMethod.GET, new HttpEntity<>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Gotten!", result.getBody());
|
||||
}
|
||||
}
|
||||
|
||||
//Don't use @SpringBootApplication because we don't want to component scan
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableZuulProxy
|
||||
@RibbonClients({
|
||||
@RibbonClient(name = "simple", configuration = SimpleRibbonClientConfiguration.class),
|
||||
@RibbonClient(name = "another", configuration = AnotherRibbonClientConfiguration.class)
|
||||
})
|
||||
@RibbonClient(name = "simple", configuration = SimpleRibbonClientConfiguration.class),
|
||||
@RibbonClient(name = "another", configuration = AnotherRibbonClientConfiguration.class) })
|
||||
class SampleZuulProxyApplication {
|
||||
|
||||
@RequestMapping("/testing123")
|
||||
@@ -168,7 +167,7 @@ class SampleZuulProxyApplication {
|
||||
|
||||
}
|
||||
|
||||
//Load balancer with fixed server list for "simple" pointing to localhost
|
||||
// Load balancer with fixed server list for "simple" pointing to localhost
|
||||
@Configuration
|
||||
class SimpleRibbonClientConfiguration {
|
||||
@Bean
|
||||
@@ -179,6 +178,7 @@ class SimpleRibbonClientConfiguration {
|
||||
return balancer;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
class AnotherRibbonClientConfiguration {
|
||||
@Bean
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,10 +23,13 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SimpleZuulServerApplication.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port: 0"})
|
||||
@IntegrationTest({ "server.port: 0" })
|
||||
@DirtiesContext
|
||||
public class SimpleZuulServerApplicationTests {
|
||||
|
||||
@@ -41,13 +41,13 @@ public class SimpleZuulServerApplicationTests {
|
||||
|
||||
@Test
|
||||
public void bindRoute() {
|
||||
assertTrue(routes.getRoutePaths().contains("/testing123/**"));
|
||||
assertTrue(this.routes.getRoutePaths().contains("/testing123/**"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getOnSelf() {
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/", HttpMethod.GET,
|
||||
"http://localhost:" + this.port + "/", HttpMethod.GET,
|
||||
new HttpEntity<Void>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
assertEquals("Hello world", result.getBody());
|
||||
@@ -56,14 +56,14 @@ public class SimpleZuulServerApplicationTests {
|
||||
@Test
|
||||
public void getOnSelfViaFilter() {
|
||||
ResponseEntity<String> result = new TestRestTemplate().exchange(
|
||||
"http://localhost:" + port + "/testing123/1", HttpMethod.GET,
|
||||
"http://localhost:" + this.port + "/testing123/1", HttpMethod.GET,
|
||||
new HttpEntity<Void>((Void) null), String.class);
|
||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Don't use @SpringBootApplication because we don't want to component scan
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters.post;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -17,12 +14,15 @@ import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import com.netflix.util.Pair;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class PreDecorationFilterTests {
|
||||
|
||||
|
||||
private PreDecorationFilter filter;
|
||||
|
||||
@Mock
|
||||
@@ -31,32 +31,32 @@ public class PreDecorationFilterTests {
|
||||
private ZuulProperties properties = new ZuulProperties();
|
||||
|
||||
private ProxyRouteLocator routeLocator;
|
||||
|
||||
|
||||
private MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
initMocks(this);
|
||||
routeLocator = new ProxyRouteLocator(discovery, properties);
|
||||
filter = new PreDecorationFilter(routeLocator, properties);
|
||||
this.routeLocator = new ProxyRouteLocator(this.discovery, this.properties);
|
||||
this.filter = new PreDecorationFilter(this.routeLocator, this.properties);
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
ctx.setRequest(request);
|
||||
ctx.setRequest(this.request);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void basicProperties() throws Exception {
|
||||
assertEquals(5, filter.filterOrder());
|
||||
assertEquals(true, filter.shouldFilter());
|
||||
assertEquals("pre", filter.filterType());
|
||||
assertEquals(5, this.filter.filterOrder());
|
||||
assertEquals(true, this.filter.shouldFilter());
|
||||
assertEquals("pre", this.filter.filterType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixRouteAddsHeader() throws Exception {
|
||||
properties.setPrefix("/api");
|
||||
properties.setStripPrefix(true);
|
||||
request.setRequestURI("/api/foo/1");
|
||||
routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
filter.run();
|
||||
this.properties.setPrefix("/api");
|
||||
this.properties.setStripPrefix(true);
|
||||
this.request.setRequestURI("/api/foo/1");
|
||||
this.routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", "foo", null, false));
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertEquals("/foo/1", ctx.get("requestURI"));
|
||||
assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
|
||||
@@ -66,11 +66,11 @@ public class PreDecorationFilterTests {
|
||||
|
||||
@Test
|
||||
public void prefixRouteWithRouteStrippingAddsHeader() throws Exception {
|
||||
properties.setPrefix("/api");
|
||||
properties.setStripPrefix(true);
|
||||
request.setRequestURI("/api/foo/1");
|
||||
routeLocator.addRoute("/foo/**", "foo");
|
||||
filter.run();
|
||||
this.properties.setPrefix("/api");
|
||||
this.properties.setStripPrefix(true);
|
||||
this.request.setRequestURI("/api/foo/1");
|
||||
this.routeLocator.addRoute("/foo/**", "foo");
|
||||
this.filter.run();
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
assertEquals("/1", ctx.get("requestURI"));
|
||||
assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
|
||||
@@ -78,8 +78,7 @@ public class PreDecorationFilterTests {
|
||||
assertEquals("foo", getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid"));
|
||||
}
|
||||
|
||||
private Object getHeader(List<Pair<String, String>> headers,
|
||||
String key) {
|
||||
private Object getHeader(List<Pair<String, String>> headers, String key) {
|
||||
String value = null;
|
||||
for (Pair<String, String> pair : headers) {
|
||||
if (pair.first().toLowerCase().equals(key.toLowerCase())) {
|
||||
|
||||
@@ -35,213 +35,226 @@ import com.netflix.eureka.util.StatusInfo;
|
||||
@RequestMapping("${eureka.dashboard.path:/}")
|
||||
public class EurekaController {
|
||||
|
||||
@Value("${eureka.dashboard.path:/}")
|
||||
private String dashboardPath = "";
|
||||
@Value("${eureka.dashboard.path:/}")
|
||||
private String dashboardPath = "";
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public String status(HttpServletRequest request, Map<String, Object> model) {
|
||||
populateBase(request, model);
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public String status(HttpServletRequest request, Map<String, Object> model) {
|
||||
populateBase(request, model);
|
||||
|
||||
populateApps(model);
|
||||
populateApps(model);
|
||||
|
||||
StatusInfo statusInfo = new StatusResource().getStatusInfo();
|
||||
model.put("statusInfo", statusInfo);
|
||||
StatusInfo statusInfo = new StatusResource().getStatusInfo();
|
||||
model.put("statusInfo", statusInfo);
|
||||
|
||||
populateInstanceInfo(model, statusInfo);
|
||||
populateInstanceInfo(model, statusInfo);
|
||||
|
||||
return "eureka/status";
|
||||
}
|
||||
return "eureka/status";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/lastn", method = RequestMethod.GET)
|
||||
public String lastn(HttpServletRequest request, Map<String, Object> model) {
|
||||
populateBase(request, model);
|
||||
PeerAwareInstanceRegistry registery = PeerAwareInstanceRegistry.getInstance();
|
||||
@RequestMapping(value = "/lastn", method = RequestMethod.GET)
|
||||
public String lastn(HttpServletRequest request, Map<String, Object> model) {
|
||||
populateBase(request, model);
|
||||
PeerAwareInstanceRegistry registery = PeerAwareInstanceRegistry.getInstance();
|
||||
|
||||
ArrayList<Map<String, Object>> lastNCanceled = new ArrayList<>();
|
||||
List<Pair<Long, String>> list = registery.getLastNCanceledInstances();
|
||||
for (Pair<Long, String> entry : list) {
|
||||
lastNCanceled.add(registeredInstance(entry.second(), entry.first().longValue()));
|
||||
}
|
||||
model.put("lastNCanceled", lastNCanceled);
|
||||
ArrayList<Map<String, Object>> lastNCanceled = new ArrayList<>();
|
||||
List<Pair<Long, String>> list = registery.getLastNCanceledInstances();
|
||||
for (Pair<Long, String> entry : list) {
|
||||
lastNCanceled.add(registeredInstance(entry.second(), entry.first()
|
||||
.longValue()));
|
||||
}
|
||||
model.put("lastNCanceled", lastNCanceled);
|
||||
|
||||
list = registery.getLastNRegisteredInstances();
|
||||
ArrayList<Map<String, Object>> lastNRegistered = new ArrayList<>();
|
||||
for (Pair<Long, String> entry : list) {
|
||||
lastNRegistered.add(registeredInstance(entry.second(), entry.first().longValue()));
|
||||
}
|
||||
model.put("lastNRegistered", lastNRegistered);
|
||||
list = registery.getLastNRegisteredInstances();
|
||||
ArrayList<Map<String, Object>> lastNRegistered = new ArrayList<>();
|
||||
for (Pair<Long, String> entry : list) {
|
||||
lastNRegistered.add(registeredInstance(entry.second(), entry.first()
|
||||
.longValue()));
|
||||
}
|
||||
model.put("lastNRegistered", lastNRegistered);
|
||||
|
||||
return "eureka/lastn";
|
||||
}
|
||||
return "eureka/lastn";
|
||||
}
|
||||
|
||||
private Map<String, Object> registeredInstance(String id, long date) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("id", id);
|
||||
map.put("date", new Date(date));
|
||||
return map;
|
||||
}
|
||||
private Map<String, Object> registeredInstance(String id, long date) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("id", id);
|
||||
map.put("date", new Date(date));
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void populateBase(HttpServletRequest request, Map<String, Object> model) {
|
||||
model.put("time", new Date());
|
||||
model.put("basePath", "/");
|
||||
model.put("dashboardPath", dashboardPath.equals("/") ? "" : dashboardPath);
|
||||
protected void populateBase(HttpServletRequest request, Map<String, Object> model) {
|
||||
model.put("time", new Date());
|
||||
model.put("basePath", "/");
|
||||
model.put("dashboardPath", this.dashboardPath.equals("/") ? ""
|
||||
: this.dashboardPath);
|
||||
|
||||
populateHeader(model);
|
||||
populateHeader(model);
|
||||
|
||||
populateNavbar(request, model);
|
||||
}
|
||||
populateNavbar(request, model);
|
||||
}
|
||||
|
||||
private void populateHeader(Map<String, Object> model) {
|
||||
model.put("currentTime", StatusResource.getCurrentTimeAsString());
|
||||
model.put("upTime", StatusInfo.getUpTime());
|
||||
model.put("environment", ConfigurationManager.getDeploymentContext().getDeploymentEnvironment());
|
||||
model.put("datacenter", ConfigurationManager.getDeploymentContext().getDeploymentDatacenter());
|
||||
model.put("registry", PeerAwareInstanceRegistry.getInstance());
|
||||
model.put("isBelowRenewThresold", PeerAwareInstanceRegistry.getInstance().isBelowRenewThresold() == 1);
|
||||
private void populateHeader(Map<String, Object> model) {
|
||||
model.put("currentTime", StatusResource.getCurrentTimeAsString());
|
||||
model.put("upTime", StatusInfo.getUpTime());
|
||||
model.put("environment", ConfigurationManager.getDeploymentContext()
|
||||
.getDeploymentEnvironment());
|
||||
model.put("datacenter", ConfigurationManager.getDeploymentContext()
|
||||
.getDeploymentDatacenter());
|
||||
model.put("registry", PeerAwareInstanceRegistry.getInstance());
|
||||
model.put("isBelowRenewThresold", PeerAwareInstanceRegistry.getInstance()
|
||||
.isBelowRenewThresold() == 1);
|
||||
|
||||
DataCenterInfo info = ApplicationInfoManager.getInstance().getInfo().getDataCenterInfo();
|
||||
if(info.getName() == DataCenterInfo.Name.Amazon) {
|
||||
AmazonInfo amazonInfo = (AmazonInfo) info;
|
||||
model.put("amazonInfo", amazonInfo);
|
||||
model.put("amiId", amazonInfo.get(AmazonInfo.MetaDataKey.amiId));
|
||||
model.put("availabilityZone", amazonInfo.get(AmazonInfo.MetaDataKey.availabilityZone));
|
||||
model.put("instanceId", amazonInfo.get(AmazonInfo.MetaDataKey.instanceId));
|
||||
}
|
||||
}
|
||||
DataCenterInfo info = ApplicationInfoManager.getInstance().getInfo()
|
||||
.getDataCenterInfo();
|
||||
if (info.getName() == DataCenterInfo.Name.Amazon) {
|
||||
AmazonInfo amazonInfo = (AmazonInfo) info;
|
||||
model.put("amazonInfo", amazonInfo);
|
||||
model.put("amiId", amazonInfo.get(AmazonInfo.MetaDataKey.amiId));
|
||||
model.put("availabilityZone",
|
||||
amazonInfo.get(AmazonInfo.MetaDataKey.availabilityZone));
|
||||
model.put("instanceId", amazonInfo.get(AmazonInfo.MetaDataKey.instanceId));
|
||||
}
|
||||
}
|
||||
|
||||
private void populateNavbar(HttpServletRequest request, Map<String, Object> model) {
|
||||
Map<String, String> replicas = new LinkedHashMap<>();
|
||||
List<PeerEurekaNode> list = PeerAwareInstanceRegistry.getInstance().getReplicaNodes();
|
||||
for (PeerEurekaNode node : list) {
|
||||
try {
|
||||
URI uri = new URI(node.getServiceUrl());
|
||||
String href = node.getServiceUrl();
|
||||
replicas.put(uri.getHost(), href);
|
||||
} catch(Exception e) {
|
||||
//ignore?
|
||||
}
|
||||
}
|
||||
model.put("replicas", replicas.entrySet());
|
||||
}
|
||||
private void populateNavbar(HttpServletRequest request, Map<String, Object> model) {
|
||||
Map<String, String> replicas = new LinkedHashMap<>();
|
||||
List<PeerEurekaNode> list = PeerAwareInstanceRegistry.getInstance()
|
||||
.getReplicaNodes();
|
||||
for (PeerEurekaNode node : list) {
|
||||
try {
|
||||
URI uri = new URI(node.getServiceUrl());
|
||||
String href = node.getServiceUrl();
|
||||
replicas.put(uri.getHost(), href);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore?
|
||||
}
|
||||
}
|
||||
model.put("replicas", replicas.entrySet());
|
||||
}
|
||||
|
||||
private void populateApps(Map<String, Object> model) {
|
||||
List<com.netflix.discovery.shared.Application> sortedApplications = PeerAwareInstanceRegistry.getInstance().getSortedApplications();
|
||||
private void populateApps(Map<String, Object> model) {
|
||||
List<com.netflix.discovery.shared.Application> sortedApplications = PeerAwareInstanceRegistry
|
||||
.getInstance().getSortedApplications();
|
||||
|
||||
ArrayList<Map<String, Object>> apps = new ArrayList<>();
|
||||
ArrayList<Map<String, Object>> apps = new ArrayList<>();
|
||||
|
||||
for(Application app : sortedApplications) {
|
||||
LinkedHashMap<String, Object> appData = new LinkedHashMap<>();
|
||||
apps.add(appData);
|
||||
for (Application app : sortedApplications) {
|
||||
LinkedHashMap<String, Object> appData = new LinkedHashMap<>();
|
||||
apps.add(appData);
|
||||
|
||||
appData.put("name", app.getName());
|
||||
Map<String, Integer> amiCounts = new HashMap<>();
|
||||
Map<InstanceInfo.InstanceStatus,List<Pair<String, String>>> instancesByStatus = new HashMap<>();
|
||||
Map<String,Integer> zoneCounts = new HashMap<>();
|
||||
appData.put("name", app.getName());
|
||||
Map<String, Integer> amiCounts = new HashMap<>();
|
||||
Map<InstanceInfo.InstanceStatus, List<Pair<String, String>>> instancesByStatus = new HashMap<>();
|
||||
Map<String, Integer> zoneCounts = new HashMap<>();
|
||||
|
||||
for(InstanceInfo info : app.getInstances()){
|
||||
String id = info.getId();
|
||||
String url = info.getStatusPageUrl();
|
||||
InstanceInfo.InstanceStatus status = info.getStatus();
|
||||
String ami = "n/a";
|
||||
String zone = "";
|
||||
if(info.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon){
|
||||
AmazonInfo dcInfo = (AmazonInfo)info.getDataCenterInfo();
|
||||
ami = dcInfo.get(AmazonInfo.MetaDataKey.amiId);
|
||||
zone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone);
|
||||
}
|
||||
for (InstanceInfo info : app.getInstances()) {
|
||||
String id = info.getId();
|
||||
String url = info.getStatusPageUrl();
|
||||
InstanceInfo.InstanceStatus status = info.getStatus();
|
||||
String ami = "n/a";
|
||||
String zone = "";
|
||||
if (info.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) {
|
||||
AmazonInfo dcInfo = (AmazonInfo) info.getDataCenterInfo();
|
||||
ami = dcInfo.get(AmazonInfo.MetaDataKey.amiId);
|
||||
zone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone);
|
||||
}
|
||||
|
||||
Integer count = amiCounts.get(ami);
|
||||
if(count != null){
|
||||
amiCounts.put(ami, Integer.valueOf(count.intValue()+1));
|
||||
}else {
|
||||
amiCounts.put(ami, Integer.valueOf(1));
|
||||
}
|
||||
Integer count = amiCounts.get(ami);
|
||||
if (count != null) {
|
||||
amiCounts.put(ami, Integer.valueOf(count.intValue() + 1));
|
||||
}
|
||||
else {
|
||||
amiCounts.put(ami, Integer.valueOf(1));
|
||||
}
|
||||
|
||||
count = zoneCounts.get(zone);
|
||||
if(count != null){
|
||||
zoneCounts.put(zone, Integer.valueOf(count.intValue()+1));
|
||||
}else {
|
||||
zoneCounts.put(zone, Integer.valueOf(1));
|
||||
}
|
||||
List<Pair<String, String>> list = instancesByStatus.get(status);
|
||||
count = zoneCounts.get(zone);
|
||||
if (count != null) {
|
||||
zoneCounts.put(zone, Integer.valueOf(count.intValue() + 1));
|
||||
}
|
||||
else {
|
||||
zoneCounts.put(zone, Integer.valueOf(1));
|
||||
}
|
||||
List<Pair<String, String>> list = instancesByStatus.get(status);
|
||||
|
||||
if(list == null){
|
||||
list = new ArrayList<>();
|
||||
instancesByStatus.put(status, list);
|
||||
}
|
||||
list.add(new Pair<>(id, url));
|
||||
}
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
instancesByStatus.put(status, list);
|
||||
}
|
||||
list.add(new Pair<>(id, url));
|
||||
}
|
||||
|
||||
appData.put("amiCounts", amiCounts.entrySet());
|
||||
appData.put("zoneCounts", zoneCounts.entrySet());
|
||||
appData.put("amiCounts", amiCounts.entrySet());
|
||||
appData.put("zoneCounts", zoneCounts.entrySet());
|
||||
|
||||
ArrayList<Map<String, Object>> instanceInfos = new ArrayList<>();
|
||||
appData.put("instanceInfos", instanceInfos);
|
||||
ArrayList<Map<String, Object>> instanceInfos = new ArrayList<>();
|
||||
appData.put("instanceInfos", instanceInfos);
|
||||
|
||||
for (Iterator<Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String,String>>>> iter =
|
||||
instancesByStatus.entrySet().iterator(); iter.hasNext();) {
|
||||
Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String,String>>> entry = iter.next();
|
||||
List<Pair<String, String>> value = entry.getValue();
|
||||
InstanceInfo.InstanceStatus status = entry.getKey();
|
||||
for (Iterator<Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String, String>>>> iter = instancesByStatus
|
||||
.entrySet().iterator(); iter.hasNext();) {
|
||||
Map.Entry<InstanceInfo.InstanceStatus, List<Pair<String, String>>> entry = iter
|
||||
.next();
|
||||
List<Pair<String, String>> value = entry.getValue();
|
||||
InstanceInfo.InstanceStatus status = entry.getKey();
|
||||
|
||||
LinkedHashMap<String, Object> instanceData = new LinkedHashMap<>();
|
||||
instanceInfos.add(instanceData);
|
||||
LinkedHashMap<String, Object> instanceData = new LinkedHashMap<>();
|
||||
instanceInfos.add(instanceData);
|
||||
|
||||
instanceData.put("status", entry.getKey());
|
||||
ArrayList<Map<String, Object>> instances = new ArrayList<>();
|
||||
instanceData.put("instances", instances);
|
||||
instanceData.put("isNotUp", status != InstanceInfo.InstanceStatus.UP);
|
||||
instanceData.put("status", entry.getKey());
|
||||
ArrayList<Map<String, Object>> instances = new ArrayList<>();
|
||||
instanceData.put("instances", instances);
|
||||
instanceData.put("isNotUp", status != InstanceInfo.InstanceStatus.UP);
|
||||
|
||||
/*if(status != InstanceInfo.InstanceStatus.UP){
|
||||
buf.append("<font color=red size=+1><b>");
|
||||
}
|
||||
buf.append("<b>").append(status.name()).append("</b> (").append(value.size()).append(") - ");
|
||||
if(status != InstanceInfo.InstanceStatus.UP){
|
||||
buf.append("</font></b>");
|
||||
}*/
|
||||
/*
|
||||
* if(status != InstanceInfo.InstanceStatus.UP){
|
||||
* buf.append("<font color=red size=+1><b>"); }
|
||||
* buf.append("<b>").append(status
|
||||
* .name()).append("</b> (").append(value.size()).append(") - ");
|
||||
* if(status != InstanceInfo.InstanceStatus.UP){
|
||||
* buf.append("</font></b>"); }
|
||||
*/
|
||||
|
||||
for(Pair<String,String> p : value) {
|
||||
LinkedHashMap<String, Object> instance = new LinkedHashMap<>();
|
||||
instances.add(instance);
|
||||
instance.put("id", p.first());
|
||||
instance.put("url", p.second());
|
||||
instance.put("isHref", p.second().startsWith("http"));
|
||||
/*String id = p.first();
|
||||
String url = p.second();
|
||||
if(url != null && url.startsWith("http")){
|
||||
buf.append("<a href=\"").append(url).append("\">");
|
||||
}else {
|
||||
url = null;
|
||||
}
|
||||
buf.append(id);
|
||||
if(url != null){
|
||||
buf.append("</a>");
|
||||
}
|
||||
buf.append(", ");*/
|
||||
}
|
||||
}
|
||||
//out.println("<td>" + buf.toString() + "</td></tr>");
|
||||
}
|
||||
for (Pair<String, String> p : value) {
|
||||
LinkedHashMap<String, Object> instance = new LinkedHashMap<>();
|
||||
instances.add(instance);
|
||||
instance.put("id", p.first());
|
||||
instance.put("url", p.second());
|
||||
instance.put("isHref", p.second().startsWith("http"));
|
||||
/*
|
||||
* String id = p.first(); String url = p.second(); if(url != null &&
|
||||
* url.startsWith("http")){
|
||||
* buf.append("<a href=\"").append(url).append("\">"); }else { url =
|
||||
* null; } buf.append(id); if(url != null){ buf.append("</a>"); }
|
||||
* buf.append(", ");
|
||||
*/
|
||||
}
|
||||
}
|
||||
// out.println("<td>" + buf.toString() + "</td></tr>");
|
||||
}
|
||||
|
||||
model.put("apps", apps);
|
||||
}
|
||||
model.put("apps", apps);
|
||||
}
|
||||
|
||||
private void populateInstanceInfo(Map<String, Object> model, StatusInfo statusInfo) {
|
||||
InstanceInfo instanceInfo = statusInfo.getInstanceInfo();
|
||||
private void populateInstanceInfo(Map<String, Object> model, StatusInfo statusInfo) {
|
||||
InstanceInfo instanceInfo = statusInfo.getInstanceInfo();
|
||||
|
||||
Map<String,String> instanceMap = new HashMap<>();
|
||||
instanceMap.put("ipAddr", instanceInfo.getIPAddr());
|
||||
instanceMap.put("status", instanceInfo.getStatus().toString());
|
||||
if(instanceInfo.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) {
|
||||
AmazonInfo info = (AmazonInfo) instanceInfo.getDataCenterInfo();
|
||||
instanceMap.put("availability-zone", info.get(AmazonInfo.MetaDataKey.availabilityZone));
|
||||
instanceMap.put("public-ipv4", info.get(AmazonInfo.MetaDataKey.publicIpv4));
|
||||
instanceMap.put("instance-id", info.get(AmazonInfo.MetaDataKey.instanceId));
|
||||
instanceMap.put("public-hostname", info.get(AmazonInfo.MetaDataKey.publicHostname));
|
||||
instanceMap.put("ami-id", info.get(AmazonInfo.MetaDataKey.amiId));
|
||||
instanceMap.put("instance-type", info.get(AmazonInfo.MetaDataKey.instanceType));
|
||||
}
|
||||
Map<String, String> instanceMap = new HashMap<>();
|
||||
instanceMap.put("ipAddr", instanceInfo.getIPAddr());
|
||||
instanceMap.put("status", instanceInfo.getStatus().toString());
|
||||
if (instanceInfo.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) {
|
||||
AmazonInfo info = (AmazonInfo) instanceInfo.getDataCenterInfo();
|
||||
instanceMap.put("availability-zone",
|
||||
info.get(AmazonInfo.MetaDataKey.availabilityZone));
|
||||
instanceMap.put("public-ipv4", info.get(AmazonInfo.MetaDataKey.publicIpv4));
|
||||
instanceMap.put("instance-id", info.get(AmazonInfo.MetaDataKey.instanceId));
|
||||
instanceMap.put("public-hostname",
|
||||
info.get(AmazonInfo.MetaDataKey.publicHostname));
|
||||
instanceMap.put("ami-id", info.get(AmazonInfo.MetaDataKey.amiId));
|
||||
instanceMap.put("instance-type",
|
||||
info.get(AmazonInfo.MetaDataKey.instanceType));
|
||||
}
|
||||
|
||||
model.put("instanceInfo", instanceMap);
|
||||
}
|
||||
model.put("instanceInfo", instanceMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.eureka.server;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for the Eureka dashboard (UI).
|
||||
* Configuration properties for the Eureka dashboard (UI).
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@ConfigurationProperties("eureka.dashboard")
|
||||
@Data
|
||||
public class EurekaDashboardProperties {
|
||||
|
||||
|
||||
/**
|
||||
* The path to the Eureka dashboard (relative to the servlet path). Defaults to "/".
|
||||
*/
|
||||
private String path = "/";
|
||||
|
||||
|
||||
/**
|
||||
* FLag to enable the Eureka dashboard. Default true.
|
||||
*/
|
||||
|
||||
@@ -117,22 +117,32 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
// ignore
|
||||
}
|
||||
LoggingConfiguration.getInstance().configure();
|
||||
EurekaServerConfigurationManager.getInstance()
|
||||
.setConfiguration(eurekaServerConfig);
|
||||
XmlXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(applicationContext));
|
||||
JsonXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(applicationContext));
|
||||
EurekaServerConfigurationManager
|
||||
.getInstance()
|
||||
.setConfiguration(
|
||||
EurekaServerInitializerConfiguration.this.eurekaServerConfig);
|
||||
XmlXStream
|
||||
.getInstance()
|
||||
.setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(
|
||||
EurekaServerInitializerConfiguration.this.applicationContext));
|
||||
JsonXStream
|
||||
.getInstance()
|
||||
.setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(
|
||||
EurekaServerInitializerConfiguration.this.applicationContext));
|
||||
// PeerAwareInstanceRegistry.getInstance();
|
||||
applicationContext
|
||||
EurekaServerInitializerConfiguration.this.applicationContext
|
||||
.publishEvent(new EurekaRegistryAvailableEvent(
|
||||
eurekaServerConfig));
|
||||
EurekaServerInitializerConfiguration.this.eurekaServerConfig));
|
||||
}
|
||||
}.contextInitialized(new ServletContextEvent(servletContext));
|
||||
}.contextInitialized(new ServletContextEvent(
|
||||
EurekaServerInitializerConfiguration.this.servletContext));
|
||||
logger.info("Started Eureka Server");
|
||||
running = true;
|
||||
applicationContext.publishEvent(new EurekaServerStartedEvent(
|
||||
eurekaServerConfig));
|
||||
EurekaServerInitializerConfiguration.this.running = true;
|
||||
EurekaServerInitializerConfiguration.this.applicationContext
|
||||
.publishEvent(new EurekaServerStartedEvent(
|
||||
EurekaServerInitializerConfiguration.this.eurekaServerConfig));
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Help!
|
||||
@@ -144,12 +154,12 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
running = false;
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
return this.running;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,7 +179,7 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -189,8 +199,8 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EurekaRegistryAvailableEvent event) {
|
||||
if (instance == null) {
|
||||
instance = PeerAwareInstanceRegistry.getInstance();
|
||||
if (this.instance == null) {
|
||||
this.instance = PeerAwareInstanceRegistry.getInstance();
|
||||
safeInit();
|
||||
replaceInstance(getProxyForInstance());
|
||||
expectRegistrations(1);
|
||||
@@ -198,9 +208,10 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
}
|
||||
|
||||
private void safeInit() {
|
||||
Method method = ReflectionUtils.findMethod(InstanceRegistry.class, "postInit");
|
||||
Method method = ReflectionUtils
|
||||
.findMethod(InstanceRegistry.class, "postInit");
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
ReflectionUtils.invokeMethod(method, instance);
|
||||
ReflectionUtils.invokeMethod(method, this.instance);
|
||||
}
|
||||
|
||||
private void replaceInstance(Object proxy) {
|
||||
@@ -221,7 +232,7 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
|
||||
private Object getProxyForInstance() {
|
||||
// Wrap the instance registry...
|
||||
ProxyFactory factory = new ProxyFactory(instance);
|
||||
ProxyFactory factory = new ProxyFactory(this.instance);
|
||||
// ...with the LeaseManagerMessageBroker
|
||||
factory.addAdvice(new PiggybackMethodInterceptor(leaseManagerMessageBroker(),
|
||||
LeaseManagerLite.class));
|
||||
@@ -243,9 +254,9 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
try {
|
||||
// Awful ugly hack to work around lack of DI in eureka
|
||||
field.setAccessible(true);
|
||||
int value = (int) ReflectionUtils.getField(field, instance);
|
||||
int value = (int) ReflectionUtils.getField(field, this.instance);
|
||||
if (value == 0 && count > 0) {
|
||||
ReflectionUtils.setField(field, instance, count);
|
||||
ReflectionUtils.setField(field, this.instance, count);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -262,7 +273,7 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
|
||||
* hasn't sent any renewals recently. This happens for a standalone server. It
|
||||
* seems like a bad default, so we set it to the smallest non-zero value we can,
|
||||
* so that any instances that subsequently register can bump up the threshold.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user