diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java new file mode 100644 index 00000000..1098ea0b --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/DefaultFeignLoadBalancedConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.feign.ribbon; + +import feign.Client; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Spencer Gibb + */ +@Configuration +class DefaultFeignLoadBalancedConfiguration { + @Bean + @ConditionalOnMissingBean + public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, + SpringClientFactory clientFactory) { + return new LoadBalancerFeignClient(new Client.Default(null, null), + cachingFactory, clientFactory); + } +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java index 4210fa6c..72aa9c43 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClientAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,27 +16,22 @@ package org.springframework.cloud.netflix.feign.ribbon; -import org.apache.http.client.HttpClient; -import org.springframework.beans.factory.annotation.Autowired; 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.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; import com.netflix.loadbalancer.ILoadBalancer; -import feign.Client; import feign.Feign; import feign.Request; -import feign.httpclient.ApacheHttpClient; -import feign.okhttp.OkHttpClient; /** * Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a @@ -47,6 +42,11 @@ import feign.okhttp.OkHttpClient; @ConditionalOnClass({ ILoadBalancer.class, Feign.class }) @Configuration @AutoConfigureBefore(FeignAutoConfiguration.class) +//Order is important here, last should be the default, first should be optional +// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653 +@Import({ HttpClientFeignLoadBalancedConfiguration.class, + OkHttpFeignLoadBalancedConfiguration.class, + DefaultFeignLoadBalancedConfiguration.class }) public class FeignRibbonClientAutoConfiguration { @Bean @@ -65,63 +65,10 @@ public class FeignRibbonClientAutoConfiguration { return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, true); } - @Bean - @ConditionalOnMissingBean - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory) { - return new LoadBalancerFeignClient(new Client.Default(null, null), - cachingFactory, clientFactory); - } - @Bean @ConditionalOnMissingBean public Request.Options feignRequestOptions() { return LoadBalancerFeignClient.DEFAULT_OPTIONS; } - @Configuration - @ConditionalOnClass(ApacheHttpClient.class) - @ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true) - protected static class HttpClientFeignLoadBalancedConfiguration { - - @Autowired(required = false) - private HttpClient httpClient; - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory) { - ApacheHttpClient delegate; - if (this.httpClient != null) { - delegate = new ApacheHttpClient(this.httpClient); - } - else { - delegate = new ApacheHttpClient(); - } - return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); - } - } - - @Configuration - @ConditionalOnClass(OkHttpClient.class) - @ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true) - protected static class OkHttpFeignLoadBalancedConfiguration { - - @Autowired(required = false) - private okhttp3.OkHttpClient okHttpClient; - - @Bean - @ConditionalOnMissingBean(Client.class) - public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, - SpringClientFactory clientFactory) { - OkHttpClient delegate; - if (this.okHttpClient != null) { - delegate = new OkHttpClient(this.okHttpClient); - } - else { - delegate = new OkHttpClient(); - } - return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); - } - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java new file mode 100644 index 00000000..b8370c6a --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/HttpClientFeignLoadBalancedConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.feign.ribbon; + +import feign.Client; +import feign.httpclient.ApacheHttpClient; +import org.apache.http.client.HttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Spencer Gibb + */ +@Configuration +@ConditionalOnClass(ApacheHttpClient.class) +@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true) +class HttpClientFeignLoadBalancedConfiguration { + + @Autowired(required = false) + private HttpClient httpClient; + + @Bean + @ConditionalOnMissingBean(Client.class) + public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, + SpringClientFactory clientFactory) { + ApacheHttpClient delegate; + if (this.httpClient != null) { + delegate = new ApacheHttpClient(this.httpClient); + } else { + delegate = new ApacheHttpClient(); + } + return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); + } +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java new file mode 100644 index 00000000..1cc262ba --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/OkHttpFeignLoadBalancedConfiguration.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.feign.ribbon; + +import feign.Client; +import feign.okhttp.OkHttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Spencer Gibb + */ +@Configuration +@ConditionalOnClass(OkHttpClient.class) +@ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true) +class OkHttpFeignLoadBalancedConfiguration { + + @Autowired(required = false) + private okhttp3.OkHttpClient okHttpClient; + + @Bean + @ConditionalOnMissingBean(Client.class) + public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, + SpringClientFactory clientFactory) { + OkHttpClient delegate; + if (this.okHttpClient != null) { + delegate = new OkHttpClient(this.okHttpClient); + } else { + delegate = new OkHttpClient(); + } + return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); + } +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java index af0e64bd..60960d13 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java @@ -17,11 +17,6 @@ package org.springframework.cloud.netflix.ribbon.apache; -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.servo.monitor.Monitors; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -32,10 +27,17 @@ import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.netflix.client.AbstractLoadBalancerAwareClient; +import com.netflix.client.RetryHandler; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.servo.monitor.Monitors; + /** * @author Spencer Gibb */ @Configuration +@ConditionalOnClass(name = "org.apache.http.client.HttpClient") @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) public class HttpClientRibbonConfiguration { @Value("${ribbon.client.name}") diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java index 5b2d917f..01dee957 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignOkHttpTests.java @@ -63,7 +63,7 @@ import lombok.NoArgsConstructor; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = FeignOkHttpTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { "spring.application.name=feignclienttest", "feign.hystrix.enabled=false", - "feign.okhttp.enabled=true" }) + "feign.httpclient.enabled=false", "feign.okhttp.enabled=true" }) @DirtiesContext public class FeignOkHttpTests {