Compare commits

...
Author SHA1 Message Date
Spencer Gibb ae3da1099d Update SNAPSHOT to RELEASE 1.0.5.RELEASE 2015-12-10 14:15:08 -07:00
Spencer Gibb 5010ad1156 Force isCircuitBreakerOpen to String (if it's a Boolean for example)
see https://github.com/Netflix/Hystrix/pull/927
2015-12-09 12:38:57 -07:00
Konstantin A. Zolotukhin 4136e397de null check for command bound circuit breaker 2015-11-20 15:50:28 -07:00
Spencer Gibb bf1e0d6d44 Bumped to 1.0.5.BUILD-SNAPSHOT 2015-11-16 10:13:36 -07:00
Dave Syer bc807aae9e Use better icon image for magnifying glass
Fixes gh-628
2015-11-09 14:25:33 +00:00
Spencer Gibb 727d8be2dc Change from @Autowired to context.getBean.
Solves problems where FeignClientFactoryBean is run before auto-configuration.

fixed gh-441
2015-10-14 11:52:11 -06:00
Dave Syer f98a7d5bc5 Take into account secure port settings when looking for config server
When the config server is located via discovery
(spring.cloud.config.discovery.enabled=true) the discovery process
should attempt to establish whether the config server prefers to
be accessed securely (e.g. it registered with Eureka as
nonSecurePortEnabled=false). This change ensures that this happens.

Fixes gh-450
2015-09-25 13:09:33 +01:00
Dave Syer 5dccd03d73 Fix broken test
This test made wrong assumptions about the content of the child
context when trying to simulate autoconfiguration. It needed
an extra EurekaClientAutoConfiguration.
2015-09-25 13:04:52 +01:00
Dave Syer f904b52a1d Tweak eureka lifecycle so it re-registers after a refresh
This version of Eureka is a bit of a singleton pig, so it's hard
to control the lifecycle, but this seems to work for all the tests
and also the eureka-first and ribbon-eureka samples.

Fixes gh-551 for 1.0.x
2015-09-24 17:07:22 +01:00
Spencer Gibb ac86e7798e Fix Feign ResponseEntity<Void> NPE
fixes gh-539
2015-09-14 12:38:43 -06:00
Spencer Gibb 13a3ea071d Only manage turbine-core dep in modules
fixes gh-511
2015-09-02 10:49:32 -06:00
Dave Syer 43a5241d3c Fix autoconfig ordering so that health indicators always work 2015-09-02 13:29:41 +01:00
23 changed files with 241 additions and 175 deletions
+2 -2
View File
@@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.0.3.BUILD-SNAPSHOT</version>
<version>1.0.3.RELEASE</version>
<relativePath />
</parent>
<artifactId>spring-cloud-netflix-docs</artifactId>
<packaging>pom</packaging>
<name>Spring Cloud Netflix Docs</name>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<description>Spring Cloud Docs</description>
<properties>
<docs.main>spring-cloud-netflix</docs.main>
+21 -45
View File
@@ -5,11 +5,11 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.0.3.BUILD-SNAPSHOT</version>
<version>1.0.3.RELEASE</version>
<relativePath />
</parent>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Cloud Netflix</name>
<description>Spring Cloud Netflix</description>
@@ -21,8 +21,8 @@
</scm>
<properties>
<bintray.package>netflix</bintray.package>
<spring-cloud-commons.version>1.0.3.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>1.0.3.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-commons.version>1.0.3.RELEASE</spring-cloud-commons.version>
<spring-cloud-config.version>1.0.3.RELEASE</spring-cloud-config.version>
<main.basedir>${basedir}</main.basedir>
<archaius.version>0.6.5</archaius.version>
<eureka.version>1.1.147</eureka.version>
@@ -32,7 +32,6 @@
<zuul.version>1.0.28</zuul.version>
<rxjava.version>1.0.11</rxjava.version>
<java.version>1.7</java.version>
<turbine.version>1.0.0</turbine.version>
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
<cloud-connectors.version>1.1.1.RELEASE</cloud-connectors.version>
</properties>
@@ -83,87 +82,87 @@
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine-amqp</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-sidecar</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine-amqp</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-zuul-server</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
@@ -210,29 +209,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.turbine</groupId>
<artifactId>turbine-core</artifactId>
<version>${turbine.version}</version>
<exclusions>
<exclusion>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Eureka core dep that is now optional -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-netflix-core</artifactId>
@@ -21,8 +21,9 @@ import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.ApplicationInfoManager;
@@ -39,7 +40,8 @@ import com.netflix.discovery.EurekaClientConfig;
@ConditionalOnBean({ EurekaDiscoveryClientConfiguration.class })
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
@Configuration
public class DiscoveryClientConfigServiceAutoConfiguration {
public class DiscoveryClientConfigServiceAutoConfiguration
implements ApplicationListener<RefreshScopeRefreshedEvent> {
@Autowired
private EurekaClientConfig clientConfig;
@@ -47,28 +49,24 @@ public class DiscoveryClientConfigServiceAutoConfiguration {
@Autowired
private EurekaInstanceConfig instanceConfig;
@Autowired
private ConfigurationPropertiesBindingPostProcessor binder;
@Autowired
private EurekaDiscoveryClientConfiguration lifecycle;
@PostConstruct
public void init() {
this.lifecycle.stop();
rebind(this.clientConfig, "eurekaClientConfig");
rebind(this.instanceConfig, "eurekaInstanceConfig");
if (DiscoveryManager.getInstance().getDiscoveryClient() != null) {
DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
}
if (DiscoveryManager.getInstance().getDiscoveryClient() != null) {
DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
}
ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
DiscoveryManager.getInstance().initComponent(this.instanceConfig,
this.clientConfig);
this.lifecycle.start();
}
private void rebind(Object bean, String name) {
this.binder.postProcessBeforeInitialization(bean, name);
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent arg0) {
init();
}
}
@@ -16,17 +16,19 @@
package org.springframework.cloud.netflix.config;
import lombok.extern.apachecommons.CommonsLog;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -37,9 +39,11 @@ import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.DiscoveryManager;
import lombok.extern.apachecommons.CommonsLog;
/**
* Bootstrap configuration for a config client that wants to lookup the config server via
* discovery.
* Bootstrap configuration for a config client that wants to lookup the config
* server via discovery.
*
* @author Dave Syer
*/
@@ -49,20 +53,25 @@ import com.netflix.discovery.DiscoveryManager;
@EnableDiscoveryClient
@Import(EurekaClientAutoConfiguration.class)
@CommonsLog
public class DiscoveryClientConfigServiceBootstrapConfiguration implements
SmartApplicationListener {
public class DiscoveryClientConfigServiceBootstrapConfiguration implements SmartApplicationListener {
private HeartbeatMonitor monitor = new HeartbeatMonitor();
@Autowired
private ConfigClientProperties config;
@Autowired
private org.springframework.cloud.client.discovery.DiscoveryClient client;
@Autowired
private ApplicationContext context;
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
if (event instanceof ContextRefreshedEvent
&& ((ContextRefreshedEvent) event).getApplicationContext() == context) {
refresh();
}
else if (event instanceof HeartbeatEvent) {
} else if (event instanceof HeartbeatEvent) {
if (this.monitor.update(((HeartbeatEvent) event).getValue())) {
refresh();
}
@@ -88,12 +97,9 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
private void refresh() {
try {
log.info("Locating configserver via discovery");
InstanceInfo server = DiscoveryManager
.getInstance()
.getDiscoveryClient()
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(),
false);
String url = server.getHomePageUrl();
InstanceInfo server = DiscoveryManager.getInstance().getDiscoveryClient()
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(), false);
String url = getHomePage(server);
if (server.getMetadata().containsKey("password")) {
String user = server.getMetadata().get("user");
user = user == null ? "user" : user;
@@ -109,10 +115,17 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
url = url + path;
}
this.config.setUri(url);
}
catch (Exception ex) {
} catch (Exception ex) {
log.warn("Could not locate configserver via discovery", ex);
}
}
private String getHomePage(InstanceInfo server) {
List<ServiceInstance> instances = client.getInstances(this.config.getDiscovery().getServiceId());
if (instances==null || instances.isEmpty()) {
return server.getHomePageUrl();
}
return instances.get(0).getUri().toString() + "/";
}
}
@@ -27,8 +27,10 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent;
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
@@ -50,7 +52,7 @@ import com.netflix.discovery.converters.XmlXStream;
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class)
@AutoConfigureBefore({NoopDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class})
public class EurekaClientAutoConfiguration implements ApplicationListener<ParentContextApplicationContextInitializer.ParentContextAvailableEvent> {
@Autowired
@@ -60,7 +62,7 @@ public class EurekaClientAutoConfiguration implements ApplicationListener<Parent
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
int nonSecurePort;
@PostConstruct
public void init() {
XmlXStream.getInstance().setMarshallingStrategy(
@@ -70,13 +72,13 @@ public class EurekaClientAutoConfiguration implements ApplicationListener<Parent
}
@Bean
@ConditionalOnMissingBean(EurekaClientConfig.class)
@ConditionalOnMissingBean(value=EurekaClientConfig.class, search = SearchStrategy.CURRENT)
public EurekaClientConfigBean eurekaClientConfigBean() {
return new EurekaClientConfigBean();
}
@Bean
@ConditionalOnMissingBean(EurekaInstanceConfig.class)
@ConditionalOnMissingBean(value=EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean();
instance.setNonSecurePort(this.nonSecurePort);
@@ -110,8 +110,8 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
@Override
public int getPort() {
// assume if unsecure is enabled, that is the default
if (this.instance.isPortEnabled(UNSECURE) || !this.instance.isPortEnabled(SECURE)) {
// assume if secure is enabled, that is the default
if (!this.instance.isPortEnabled(SECURE)) {
return this.instance.getPort();
}
return this.instance.getSecurePort();
@@ -16,14 +16,17 @@
package org.springframework.cloud.netflix.feign;
import java.util.List;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -37,7 +40,6 @@ import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import feign.ribbon.LoadBalancingTarget;
import feign.slf4j.Slf4jLogger;
/**
@@ -45,7 +47,7 @@ import feign.slf4j.Slf4jLogger;
*/
@Data
@EqualsAndHashCode(callSuper = false)
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean, ApplicationContextAware {
private Class<?> type;
@@ -53,35 +55,7 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
private String url;
@Autowired
private Decoder decoder;
@Autowired
private Encoder encoder;
@Autowired
private Logger logger;
@Autowired
private Contract contract;
@Autowired(required = false)
private Logger.Level logLevel;
@Autowired(required = false)
private Retryer retryer;
@Autowired(required = false)
private ErrorDecoder errorDecoder;
@Autowired(required = false)
private Request.Options options;
@Autowired(required = false)
private Client ribbonClient;
@Autowired(required = false)
private List<RequestInterceptor> requestInterceptors;
private ApplicationContext context;
@Override
public void afterPropertiesSet() throws Exception {
@@ -91,40 +65,67 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
}
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
protected Feign.Builder feign() {
// @formatter:off
Feign.Builder builder = Feign.builder()
// required values
.logger(this.logger).encoder(this.encoder).decoder(this.decoder)
.contract(this.contract);
.logger(get(Logger.class))
.encoder(get(Encoder.class))
.decoder(get(Decoder.class))
.contract(get(Contract.class));
// @formatter:on
// optional values
if (this.logLevel != null) {
builder.logLevel(this.logLevel);
Logger.Level level = getOptional(Logger.Level.class);
if (level != null) {
builder.logLevel(level);
}
if (this.retryer != null) {
builder.retryer(this.retryer);
Retryer retryer = getOptional(Retryer.class);
if (retryer != null) {
builder.retryer(retryer);
}
if (this.errorDecoder != null) {
builder.errorDecoder(this.errorDecoder);
ErrorDecoder errorDecoder = getOptional(ErrorDecoder.class);
if (errorDecoder != null) {
builder.errorDecoder(errorDecoder);
}
if (this.options != null) {
builder.options(this.options);
Request.Options options = getOptional(Request.Options.class);
if (options != null) {
builder.options(options);
}
if (this.requestInterceptors != null) {
builder.requestInterceptors(this.requestInterceptors);
Map<String, RequestInterceptor> requestInterceptors = this.context.getBeansOfType(RequestInterceptor.class);
if (requestInterceptors != null) {
builder.requestInterceptors(requestInterceptors.values());
}
return builder;
}
protected <T> T get(Class<T> type) {
return this.context.getBean(type);
}
protected <T> T getOptional(Class<T> type) {
try {
return this.context.getBean(type);
} catch (NoSuchBeanDefinitionException e) {
//ignore
}
return null;
}
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
builder.logger(new Slf4jLogger(type)); // TODO: how to have choice here?
if (this.ribbonClient != null) {
return builder.client(this.ribbonClient).target(type, schemeName);
}
else {
return builder.target(LoadBalancingTarget.create(type, schemeName));
Client client = getOptional(Client.class);
if (client != null) {
return builder.client(client).target(type, schemeName);
}
throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-ribbon?");
}
@Override
@@ -39,8 +39,12 @@ public class ResponseEntityDecoder implements Decoder {
type = ((ParameterizedType) type).getActualTypeArguments()[0];
Object decodedObject = decoder.decode(response, type);
Class<?> clazz = null;
if (decodedObject != null) {
clazz = decodedObject.getClass();
}
return createResponse(
decodedObject.getClass(),
clazz,
decodedObject,
response);
}
@@ -56,9 +60,11 @@ public class ResponseEntityDecoder implements Decoder {
headers.put(key, new LinkedList<>(response.headers().get(key)));
}
return new ResponseEntity<T>(
clazz.cast(instance),
headers,
T retVal = null;
if (clazz != null && instance != null) {
retVal = clazz.cast(instance);
}
return new ResponseEntity<>(retVal, headers,
HttpStatus.valueOf(response.status()));
}
}
@@ -47,7 +47,7 @@ public class HystrixHealthIndicator extends AbstractHealthIndicator {
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
.getInstance(metrics.getCommandKey());
if (circuitBreaker.isOpen()) {
if (circuitBreaker != null && circuitBreaker.isOpen()) {
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
+ metrics.getCommandKey().name());
}
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
@@ -61,20 +62,18 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
@Test
public void onWhenRequested() throws Exception {
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
this.info);
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
.willReturn(this.info);
setup("spring.cloud.config.discovery.enabled=true");
assertEquals(
1,
this.context
.getBeanNamesForType(DiscoveryClientConfigServiceAutoConfiguration.class).length);
assertEquals(1, this.context.getBeanNamesForType(
DiscoveryClientConfigServiceAutoConfiguration.class).length);
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
Mockito.verify(this.client).shutdown();
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
assertEquals("http://foo:7001/", locator.getRawUri());
assertEquals("bar", ApplicationInfoManager.getInstance().getInfo().getMetadata()
.get("foo"));
assertEquals("bar",
ApplicationInfoManager.getInstance().getInfo().getMetadata().get("foo"));
}
private void setup(String... env) {
@@ -89,8 +88,11 @@ public class DiscoveryClientConfigServiceAutoConfigurationTests {
parent.refresh();
this.context = new AnnotationConfigApplicationContext();
this.context.setParent(parent);
this.context.register(DiscoveryClientConfigServiceAutoConfiguration.class);
this.context.register(PropertyPlaceholderAutoConfiguration.class,
DiscoveryClientConfigServiceAutoConfiguration.class,
EurekaClientAutoConfiguration.class);
this.context.refresh();
DiscoveryManager.getInstance().setDiscoveryClient(this.client);
}
@Configuration
@@ -25,12 +25,15 @@ import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.PortType;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.DiscoveryManager;
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import java.util.Arrays;
/**
* @author Dave Syer
*/
@@ -55,32 +58,45 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
this.context = new AnnotationConfigApplicationContext(
DiscoveryClientConfigServiceBootstrapConfiguration.class);
assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
assertEquals(
0,
this.context
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
assertEquals(0, this.context.getBeanNamesForType(
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
}
@Test
public void onWhenRequested() throws Exception {
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
this.info);
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
.willReturn(this.info);
setup("spring.cloud.config.discovery.enabled=true");
assertEquals(
1,
this.context
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
assertEquals(1, 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.getRawUri());
}
@Test
public void secureWhenRequested() throws Exception {
info = InstanceInfo.Builder.newBuilder().setAppName("app").setHostName("foo")
.setHomePageUrl("/", null).enablePort(PortType.SECURE, true).setSecurePort(443).build();
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
.willReturn(this.info);
given(this.client.getInstancesByVipAddress("CONFIGSERVER", false))
.willReturn(Arrays.asList(info));
setup("spring.cloud.config.discovery.enabled=true");
assertEquals(1, this.context.getBeanNamesForType(
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
assertEquals("https://foo:443/", locator.getRawUri());
}
@Test
public void setsPasssword() throws Exception {
this.info.getMetadata().put("password", "bar");
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
this.info);
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
.willReturn(this.info);
setup("spring.cloud.config.discovery.enabled=true");
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
@@ -92,8 +108,8 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
@Test
public void setsPath() throws Exception {
this.info.getMetadata().put("configPath", "/bar");
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
this.info);
given(this.client.getNextServerFromEureka("CONFIGSERVER", false))
.willReturn(this.info);
setup("spring.cloud.config.discovery.enabled=true");
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
@@ -103,8 +119,8 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
private void setup(String... env) {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, env);
this.context.getDefaultListableBeanFactory().registerSingleton(
"mockDiscoveryClient", this.client);
this.context.getDefaultListableBeanFactory()
.registerSingleton("mockDiscoveryClient", this.client);
DiscoveryManager.getInstance().setDiscoveryClient(this.client);
this.context.register(PropertyPlaceholderAutoConfiguration.class,
DiscoveryClientConfigServiceBootstrapConfiguration.class,
@@ -95,6 +95,17 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
}
@Test
public void testResponseEntityVoid() {
ResponseEntity<Void> response = testClient().getHelloVoid();
assertNotNull("response was null", response);
List<String> headers = response.getHeaders().get("X-test-header");
assertNotNull("headers was null", headers);
assertEquals("headers size was wrong", 1, headers.size());
String header = headers.get(0);
assertEquals("header was wrong", "myval", header);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@@ -114,6 +125,9 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
public List<String> getHelloStrings();
@RequestMapping(method = RequestMethod.GET, value = "/hellovoid")
public ResponseEntity<Void> getHelloVoid();
}
@Configuration
@@ -126,6 +140,11 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
return ResponseEntity.ok(new Hello("hello world via response"));
}
@Override
public ResponseEntity<Void> getHelloVoid() {
return ResponseEntity.noContent().header("X-test-header", "myval").build();
}
@Override
public Hello getHello() {
return new Hello("hello world 1");
@@ -19,6 +19,8 @@ package org.springframework.cloud.netflix.feign.valid;
import org.junit.Test;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -32,16 +34,39 @@ import static org.junit.Assert.assertNotNull;
public class FeignClientValidationTests {
@Test
public void valid() {
public void validNotLoadBalanced() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
GoodConfiguration.class);
assertNotNull(context.getBean(GoodConfiguration.Client.class));
GoodUrlConfiguration.class);
assertNotNull(context.getBean(GoodUrlConfiguration.Client.class));
context.close();
}
@Configuration
@EnableFeignClients
protected static class GoodConfiguration {
protected static class GoodUrlConfiguration {
@FeignClient(url="http://example.com")
interface Client {
@RequestMapping(method = RequestMethod.GET, value = "/")
@Deprecated
String get();
}
}
@Test
public void validLoadBalanced() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
RibbonAutoConfiguration.class,
FeignRibbonClientAutoConfiguration.class,
GoodServiceIdConfiguration.class);
assertNotNull(context.getBean(GoodServiceIdConfiguration.Client.class));
context.close();
}
@Configuration
@EnableFeignClients
protected static class GoodServiceIdConfiguration {
@FeignClient("foo")
interface Client {
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
@@ -13,7 +13,7 @@
<url>http://projects.spring.io/spring-cloud/</url>
<properties>
<main.basedir>${basedir}/..</main.basedir>
<spring-cloud.version>1.0.4.BUILD-SNAPSHOT</spring-cloud.version>
<spring-cloud.version>1.0.5.RELEASE</spring-cloud.version>
<wro4j.version>1.7.6</wro4j.version>
</properties>
<dependencies>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>
@@ -8,12 +8,12 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<properties>
<main.basedir>${basedir}/..</main.basedir>
<spring-cloud.version>1.0.4.BUILD-SNAPSHOT</spring-cloud.version>
<spring-cloud.version>1.0.5.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 13 KiB

@@ -42,7 +42,7 @@
<% } else {
/* We have some circuits that are open */
%>
Circuit <font color="orange"><%= isCircuitBreakerOpen.replace("true", "Open").replace("false", "Closed") %>)</font>
Circuit <font color="orange"><%= isCircuitBreakerOpen.toString().replace("true", "Open").replace("false", "Closed") %>)</font>
<% } %>
<% } %>
</div>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-netflix-sidecar</artifactId>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-turbine-amqp</artifactId>
+9 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.4.BUILD-SNAPSHOT</version>
<version>1.0.5.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-netflix-turbine</artifactId>
@@ -23,6 +23,14 @@
<artifactId>turbine-core</artifactId>
<version>${turbine.version}</version>
<exclusions>
<exclusion>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>