diff --git a/pom.xml b/pom.xml
index 69eeedce..583ad2db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -210,7 +210,7 @@
1.1.135
6.1.2
1.4.0-RC4
- 0.3.12
+ 0.3.13
0.4
1.0.24
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientAutoConfiguration.java
new file mode 100644
index 00000000..0265a7ba
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientAutoConfiguration.java
@@ -0,0 +1,24 @@
+package org.springframework.cloud.client;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Spencer Gibb
+ * TODO: move org.springframework.cloud.client to a spring-cloud-common project
+ */
+@Configuration
+@EnableConfigurationProperties
+@ConditionalOnExpression("${spring.cloud.client.enabled:true}")
+public class ClientAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean(ClientProperties.class)
+ public ClientProperties clientProperties() {
+ return new ClientProperties();
+ }
+
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientProperties.java
new file mode 100644
index 00000000..bad73134
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ClientProperties.java
@@ -0,0 +1,15 @@
+package org.springframework.cloud.client;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * @author Spencer Gibb
+ */
+@Data
+@ConfigurationProperties("spring.cloud.client")
+public class ClientProperties {
+ private List serviceIds;
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
index 2639e957..0126c7ec 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
@@ -19,6 +19,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.ClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -47,4 +48,9 @@ public class EurekaClientAutoConfiguration {
return new EurekaInstanceConfigBean();
}
+ @Bean
+ @ConditionalOnMissingBean(EurekaRibbonInitializer.class)
+ public EurekaRibbonInitializer eurekaRibbonInitializer(ClientProperties clientProperties) {
+ return new EurekaRibbonInitializer(clientProperties);
+ }
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRibbonInitializer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRibbonInitializer.java
new file mode 100644
index 00000000..6ae141ae
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRibbonInitializer.java
@@ -0,0 +1,28 @@
+package org.springframework.cloud.netflix.eureka;
+
+import com.netflix.config.ConfigurationManager;
+import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
+import org.springframework.cloud.client.ClientProperties;
+
+/**
+ * @author Spencer Gibb
+ */
+public class EurekaRibbonInitializer {
+
+ public EurekaRibbonInitializer(ClientProperties clientProperties) {
+ if (clientProperties.getServiceIds() != null) {
+ for (String serviceId : clientProperties.getServiceIds()) {
+ setServiceListClassAndVIP(serviceId);
+ }
+ }
+ }
+
+ public static void setServiceListClassAndVIP(String serviceId) {
+ setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
+ setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
+ }
+
+ private static void setProp(String serviceId, String suffix, String value) {
+ ConfigurationManager.getConfigInstance().setProperty(serviceId + ".ribbon." + suffix, value);
+ }
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfigurer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfigurer.java
index 6ed017c7..3cc25ca3 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfigurer.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfigurer.java
@@ -1,7 +1,5 @@
package org.springframework.cloud.netflix.feign;
-import com.netflix.config.ConfigurationManager;
-import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
import feign.Contract;
import feign.Feign;
import feign.Logger;
@@ -50,16 +48,7 @@ public class FeignConfigurer {
protected T loadBalance(Feign.Builder builder, Class type, String schemeName) {
String name = URI.create(schemeName).getHost();
- setServiceListClassAndVIP(name);
return builder.target(LoadBalancingTarget.create(type, schemeName));
}
- public static void setServiceListClassAndVIP(String serviceId) {
- setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
- setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
- }
-
- private static void setProp(String serviceId, String suffix, String value) {
- ConfigurationManager.getConfigInstance().setProperty(serviceId + ".ribbon." + suffix, value);
- }
}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
new file mode 100644
index 00000000..867c5141
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
@@ -0,0 +1,45 @@
+package org.springframework.cloud.netflix.ribbon;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
+import org.springframework.cloud.netflix.eureka.EurekaRibbonInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Spencer Gibb
+ */
+@Configuration
+@AutoConfigureAfter(EurekaClientAutoConfiguration.class)
+public class RibbonAutoConfiguration {
+
+ //TODO: why doesn't @AutoConfigureAfter(EurekaClientAutoConfiguration.class) do what the following does for order?
+ @Autowired
+ EurekaRibbonInitializer eurekaRibbonInitializer;
+
+ @Bean
+ @ConditionalOnMissingBean(RestTemplate.class)
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+ @Bean
+ public RibbonInterceptor ribbonInterceptor() {
+ return new RibbonInterceptor();
+ }
+
+ @PostConstruct
+ public void init() {
+ List list = new ArrayList<>();
+ list.add(ribbonInterceptor());
+ restTemplate().setInterceptors(list);
+ }
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java
new file mode 100644
index 00000000..2e5f119e
--- /dev/null
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java
@@ -0,0 +1,42 @@
+package org.springframework.cloud.netflix.ribbon;
+
+import com.netflix.client.ClientFactory;
+import com.netflix.loadbalancer.ILoadBalancer;
+import com.netflix.loadbalancer.Server;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.client.support.HttpRequestWrapper;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * @author Spencer Gibb
+ */
+public class RibbonInterceptor implements ClientHttpRequestInterceptor {
+ @Override
+ public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
+ HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
+ @Override
+ public URI getURI() {
+ URI originalUri = super.getURI();
+ String serviceName = originalUri.getHost();
+ ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceName);
+ Server server = loadBalancer.chooseServer(null);
+ if (server == null) {
+ throw new IllegalStateException("Unable to locate ILoadBalancer for service: "+ serviceName);
+ }
+ URI uri = UriComponentsBuilder.fromUri(originalUri)
+ .host(server.getHost())
+ .port(server.getPort())
+ .build()
+ .toUri();
+ return uri;
+ }
+ };
+ return execution.execute(wrapper, body);
+ }
+}
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
index 0cf9fd18..f8cd7b8a 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
@@ -1,6 +1,6 @@
package org.springframework.cloud.netflix.zuul.filters.route;
-import static org.springframework.cloud.netflix.feign.FeignConfigurer.setServiceListClassAndVIP;
+import static org.springframework.cloud.netflix.eureka.EurekaRibbonInitializer.setServiceListClassAndVIP;
import java.io.IOException;
import java.io.InputStream;
diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories
index ae83438b..73804c3e 100644
--- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.springframework.cloud.client.ClientAutoConfiguration,\
org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration,\
org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\
+org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,\
org.springframework.cloud.netflix.servo.ServoMetricsAutoConfiguration
\ No newline at end of file