From b2f608b884d3be6077ec6ec9bb2cf8af1ba0ccee Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Fri, 7 Jul 2017 10:10:53 -0400 Subject: [PATCH] OK HTTP Client changes --- .../main/asciidoc/spring-cloud-netflix.adoc | 2 +- .../netflix/feign/FeignAutoConfiguration.java | 49 +++++- .../FeignRibbonClientAutoConfiguration.java | 52 ++++-- .../ribbon/RibbonClientConfiguration.java | 81 ++++++++- .../okhttp/OkHttpLoadBalancingClient.java | 10 -- .../RetryableOkHttpLoadBalancingClient.java | 4 +- .../RibbonCommandFactoryConfiguration.java | 16 +- .../java/OkHttpClientConfigurationTests.java | 160 ++++++++++++++++++ ...> ApacheHttpClientConfigurationTests.java} | 12 +- .../netflix/feign/valid/FeignOkHttpTests.java | 2 +- .../RibbonClientConfigurationTests.java | 15 +- .../OkHttpLoadBalancingClientTests.java | 17 +- .../SpringRetryDisableOkHttpClientTests.java | 27 ++- .../SpringRetryEnabledOkHttpClientTests.java | 19 ++- .../zuul/ZuulProxyConfigurationTests.java | 7 +- .../OkHttpRibbonCommandIntegrationTests.java | 20 +++ .../OkHttpRibbonRetryIntegrationTests.java | 4 +- 17 files changed, 409 insertions(+), 88 deletions(-) create mode 100644 spring-cloud-netflix-core/src/test/java/OkHttpClientConfigurationTests.java rename spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/{HttpClientConfigurationTests.java => ApacheHttpClientConfigurationTests.java} (93%) diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 3b0dd846..eb42bb06 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1514,7 +1514,7 @@ path rendering the `users` path unreachable. The default HTTP client used by zuul is now backed by the Apache HTTP Client instead of the deprecated Ribbon `RestClient`. To use `RestClient` or to use the `okhttp3.OkHttpClient` set -`ribbon.restclient.enabled=true` or `ribbon.okhttp.enabled=true` respectively. +`ribbon.restclient.enabled=true` or `spring.cloud.httpclient.ok.enabled=true` respectively. === Cookies and Sensitive Headers diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java index 44f1ec7b..5294a603 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.TimeUnit; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; @@ -35,6 +36,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,6 +46,7 @@ import feign.Client; import feign.Feign; import feign.httpclient.ApacheHttpClient; import feign.okhttp.OkHttpClient; +import okhttp3.ConnectionPool; import javax.annotation.PreDestroy; @@ -108,6 +112,7 @@ public class FeignAutoConfiguration { private CloseableHttpClient httpClient; @Bean + @ConditionalOnMissingBean(HttpClientConnectionManager.class) public HttpClientConnectionManager connectionManager( ApacheHttpClientConnectionManagerFactory connectionManagerFactory, FeignHttpClientProperties httpClientProperties) { @@ -126,6 +131,7 @@ public class FeignAutoConfiguration { } @Bean + @ConditionalOnMissingBean(CloseableHttpClient.class) public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager httpClientConnectionManager, FeignHttpClientProperties httpClientProperties) { @@ -147,26 +153,55 @@ public class FeignAutoConfiguration { @PreDestroy public void destroy() throws Exception { connectionManagerTimer.cancel(); - httpClient.close(); + if(httpClient != null) { + httpClient.close(); + } } } @Configuration @ConditionalOnClass(OkHttpClient.class) @ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer") - @ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true) + @ConditionalOnProperty(value = "feign.okhttp.enabled") protected static class OkHttpFeignConfiguration { - @Autowired(required = false) private okhttp3.OkHttpClient okHttpClient; + @Bean + @ConditionalOnMissingBean(ConnectionPool.class) + public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, + OkHttpClientConnectionPoolFactory connectionPoolFactory) { + Integer maxTotalConnections = httpClientProperties.getMaxConnections(); + Long timeToLive = httpClientProperties.getTimeToLive(); + TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit(); + return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); + } + + @Bean + @ConditionalOnMissingBean(okhttp3.OkHttpClient.class) + public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, + ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) { + Boolean followRedirects = httpClientProperties.isFollowRedirects(); + Integer connectTimeout = httpClientProperties.getConnectionTimeout(); + //TODO Remove read timeout constant after changing to builder pattern + this.okHttpClient = httpClientFactory.create(false, connectTimeout, TimeUnit.MILLISECONDS, + followRedirects, 2000, TimeUnit.MILLISECONDS, connectionPool, null, + null); + return this.okHttpClient; + } + + @PreDestroy + public void destroy() { + if(okHttpClient != null) { + okHttpClient.dispatcher().executorService().shutdown(); + okHttpClient.connectionPool().evictAll(); + } + } + @Bean @ConditionalOnMissingBean(Client.class) public Client feignClient() { - if (this.okHttpClient != null) { - return new OkHttpClient(this.okHttpClient); - } - return new OkHttpClient(); + return new OkHttpClient(this.okHttpClient); } } 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 da4baaf4..c946a0c5 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 @@ -31,6 +31,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; @@ -45,9 +47,11 @@ import feign.Feign; import feign.Request; import feign.httpclient.ApacheHttpClient; import feign.okhttp.OkHttpClient; +import okhttp3.ConnectionPool; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.TimeUnit; import javax.annotation.PreDestroy; /** @@ -107,6 +111,7 @@ public class FeignRibbonClientAutoConfiguration { private RegistryBuilder registryBuilder; @Bean + @ConditionalOnMissingBean(HttpClientConnectionManager.class) public HttpClientConnectionManager connectionManager( ApacheHttpClientConnectionManagerFactory connectionManagerFactory, FeignHttpClientProperties httpClientProperties) { @@ -125,6 +130,7 @@ public class FeignRibbonClientAutoConfiguration { } @Bean + @ConditionalOnMissingBean(CloseableHttpClient.class) public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager httpClientConnectionManager, FeignHttpClientProperties httpClientProperties) { @@ -148,29 +154,55 @@ public class FeignRibbonClientAutoConfiguration { @PreDestroy public void destroy() throws Exception { connectionManagerTimer.cancel(); - httpClient.close(); + if(httpClient != null) { + httpClient.close(); + } } } @Configuration @ConditionalOnClass(OkHttpClient.class) - @ConditionalOnProperty(value = "feign.okhttp.enabled", matchIfMissing = true) + @ConditionalOnProperty(value = "feign.okhttp.enabled") protected static class OkHttpFeignLoadBalancedConfiguration { - @Autowired(required = false) private okhttp3.OkHttpClient okHttpClient; + @Bean + @ConditionalOnMissingBean(ConnectionPool.class) + public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, + OkHttpClientConnectionPoolFactory connectionPoolFactory) { + Integer maxTotalConnections = httpClientProperties.getMaxConnections(); + Long timeToLive = httpClientProperties.getTimeToLive(); + TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit(); + return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); + } + + @Bean + @ConditionalOnMissingBean(okhttp3.OkHttpClient.class) + public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, + ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) { + Boolean followRedirects = httpClientProperties.isFollowRedirects(); + Integer connectTimeout = httpClientProperties.getConnectionTimeout(); + this.okHttpClient = httpClientFactory.create(false, connectTimeout, TimeUnit.MILLISECONDS, + //TODO Remove read timeout constant after changing to builder pattern + followRedirects, 2000, TimeUnit.MILLISECONDS, connectionPool, null, + null); + return this.okHttpClient; + } + + @PreDestroy + public void destroy() { + if(okHttpClient != null) { + okHttpClient.dispatcher().executorService().shutdown(); + okHttpClient.connectionPool().evictAll(); + } + } + @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(); - } + OkHttpClient delegate = new OkHttpClient(this.okHttpClient); return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java index 8e8b4ba1..86188dae 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java @@ -16,6 +16,9 @@ package org.springframework.cloud.netflix.ribbon; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; + import java.net.URI; import java.util.Timer; import java.util.TimerTask; @@ -41,6 +44,8 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFact import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; +import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; @@ -136,7 +141,7 @@ public class RibbonClientConfiguration { } @Configuration - @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.httpclient.apache.enable", matchIfMissing = true) protected static class ApacheHttpClientConfiguration { private final Timer connectionManagerTimer = new Timer( "RibbonApacheHttpClientConfiguration.connectionManagerTimer", true); @@ -146,6 +151,7 @@ public class RibbonClientConfiguration { private RegistryBuilder registryBuilder; @Bean + @ConditionalOnMissingBean(HttpClientConnectionManager.class) public HttpClientConnectionManager httpClientConnectionManager( IClientConfig config, ApacheHttpClientConnectionManagerFactory connectionManagerFactory, @@ -184,6 +190,7 @@ public class RibbonClientConfiguration { } @Bean + @ConditionalOnMissingBean(CloseableHttpClient.class) public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager connectionManager, IClientConfig config) { Boolean followRedirects = config.getPropertyAsBoolean( @@ -203,12 +210,69 @@ public class RibbonClientConfiguration { @PreDestroy public void destroy() throws Exception { connectionManagerTimer.cancel(); - httpClient.close(); + if(httpClient != null) { + httpClient.close(); + } } } @Configuration - @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) + @ConditionalOnProperty("spring.cloud.httpclient.ok.enabled") + @ConditionalOnClass(name = "okhttp3.OkHttpClient") + protected static class OkHttpClientConfiguration { + private OkHttpClient httpClient; + + @Bean + @ConditionalOnMissingBean(ConnectionPool.class) + public ConnectionPool httpClientConnectionPool(IClientConfig config, + OkHttpClientConnectionPoolFactory connectionPoolFactory) { + Integer maxTotalConnections = config.getPropertyAsInteger( + CommonClientConfigKey.MaxTotalConnections, + DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS); + Object timeToLiveObj = config + .getProperty(CommonClientConfigKey.PoolKeepAliveTime); + Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME; + Object ttlUnitObj = config + .getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits); + TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS; + if (timeToLiveObj instanceof Long) { + timeToLive = (Long) timeToLiveObj; + } + if (ttlUnitObj instanceof TimeUnit) { + ttlUnit = (TimeUnit) ttlUnitObj; + } + return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); + } + + @Bean + @ConditionalOnMissingBean(OkHttpClient.class) + public OkHttpClient client(OkHttpClientFactory httpClientFactory, + ConnectionPool connectionPool, IClientConfig config) { + Boolean followRedirects = config.getPropertyAsBoolean( + CommonClientConfigKey.FollowRedirects, + DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS); + Integer connectTimeout = config.getPropertyAsInteger( + CommonClientConfigKey.ConnectTimeout, + DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT); + Integer readTimeout = config.getPropertyAsInteger(CommonClientConfigKey.ReadTimeout, + DefaultClientConfigImpl.DEFAULT_READ_TIMEOUT); + this.httpClient = httpClientFactory.create(false, connectTimeout, TimeUnit.MILLISECONDS, + followRedirects, readTimeout, TimeUnit.MILLISECONDS, connectionPool, null, + null); + return this.httpClient; + } + + @PreDestroy + public void destroy() { + if(httpClient != null) { + httpClient.dispatcher().executorService().shutdown(); + httpClient.connectionPool().evictAll(); + } + } + } + + @Configuration + @ConditionalOnProperty(name = "spring.cloud.httpclient.apache.enable", matchIfMissing = true) protected static class HttpClientRibbonConfiguration { @Value("${ribbon.client.name}") private String name = "client"; @@ -247,7 +311,7 @@ public class RibbonClientConfiguration { } @Configuration - @ConditionalOnProperty("ribbon.okhttp.enabled") + @ConditionalOnProperty("spring.cloud.httpclient.ok.enabled") @ConditionalOnClass(name = "okhttp3.OkHttpClient") protected static class OkHttpRibbonConfiguration { @Value("${ribbon.client.name}") @@ -259,9 +323,10 @@ public class RibbonClientConfiguration { public RetryableOkHttpLoadBalancingClient okHttpLoadBalancingClient( IClientConfig config, ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer, RetryHandler retryHandler, - LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) { + LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, + OkHttpClient delegate) { RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient( - config, serverIntrospector, loadBalancedRetryPolicyFactory); + delegate, config, serverIntrospector, loadBalancedRetryPolicyFactory); client.setLoadBalancer(loadBalancer); client.setRetryHandler(retryHandler); Monitors.registerObject("Client_" + this.name, client); @@ -273,8 +338,8 @@ public class RibbonClientConfiguration { @ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate") public OkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient( IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler) { - OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config, + ILoadBalancer loadBalancer, RetryHandler retryHandler, OkHttpClient delegate) { + OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(delegate, config, serverIntrospector); client.setLoadBalancer(loadBalancer); client.setRetryHandler(retryHandler); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java index 70d7eeb3..ae319d2d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java @@ -41,16 +41,6 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps public class OkHttpLoadBalancingClient extends AbstractLoadBalancingClient { - @Deprecated - public OkHttpLoadBalancingClient() { - super(); - } - - @Deprecated - public OkHttpLoadBalancingClient(final ILoadBalancer lb) { - super(lb); - } - public OkHttpLoadBalancingClient(IClientConfig config, ServerIntrospector serverIntrospector) { super(config, serverIntrospector); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java index 170c275a..3fd53528 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java @@ -49,9 +49,9 @@ public class RetryableOkHttpLoadBalancingClient extends OkHttpLoadBalancingClien private LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory; - public RetryableOkHttpLoadBalancingClient(IClientConfig config, ServerIntrospector serverIntrospector, + public RetryableOkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config, ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) { - super(config, serverIntrospector); + super(delegate, config, serverIntrospector); this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory; } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java index 95741603..21b1a246 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java @@ -105,11 +105,7 @@ public class RibbonCommandFactoryConfiguration { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @Deprecated //remove in Edgware" - @ConditionalOnProperty(name = "zuul.ribbon.httpclient.enabled", matchIfMissing = true) - static class ZuulProperty {} - - @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.httpclient.apache.enable", matchIfMissing = true) static class RibbonProperty {} } @@ -124,11 +120,7 @@ public class RibbonCommandFactoryConfiguration { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @Deprecated //remove in Edgware" - @ConditionalOnProperty("zuul.ribbon.okhttp.enabled") - static class ZuulProperty {} - - @ConditionalOnProperty("ribbon.okhttp.enabled") + @ConditionalOnProperty("spring.cloud.httpclient.ok.enabled") static class RibbonProperty {} } @@ -143,10 +135,6 @@ public class RibbonCommandFactoryConfiguration { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @Deprecated //remove in Edgware" - @ConditionalOnProperty("zuul.ribbon.restclient.enabled") - static class ZuulProperty {} - @ConditionalOnProperty("ribbon.restclient.enabled") static class RibbonProperty {} } diff --git a/spring-cloud-netflix-core/src/test/java/OkHttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/OkHttpClientConfigurationTests.java new file mode 100644 index 00000000..3e5e2bdf --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/OkHttpClientConfigurationTests.java @@ -0,0 +1,160 @@ +/* + * + * * Copyright 2013-2016 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. + * + */ + +import feign.Client; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockingDetails; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.commons.httpclient.DefaultOkHttpClientConnectionPoolFactory; +import org.springframework.cloud.commons.httpclient.DefaultOkHttpClientFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; +import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; +import org.springframework.cloud.netflix.feign.FeignClient; +import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient; +import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; +import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; +import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext; +import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommand; +import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockingDetails; + +/** + * @author Ryan Baxter + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = OkHttpClientConfigurationTestApp.class, value = {"feign.okhttp.enabled: true", + "spring.cloud.httpclient.ok.enabled: true", "ribbon.eureka.enabled = false"}) +@DirtiesContext +public class OkHttpClientConfigurationTests { + + @Autowired + OkHttpClientFactory okHttpClientFactory; + + @Autowired + OkHttpClientConnectionPoolFactory connectionPoolFactory; + + @Autowired + LoadBalancerFeignClient feignClient; + + @Autowired + OkHttpRibbonCommandFactory okHttpRibbonCommandFactory; + + @Test + public void testFactories() { + assertTrue(OkHttpClientConnectionPoolFactory.class.isInstance(connectionPoolFactory)); + assertTrue(OkHttpClientConfigurationTestApp.MyOkHttpClientConnectionPoolFactory.class.isInstance(connectionPoolFactory)); + assertTrue(OkHttpClientFactory.class.isInstance(okHttpClientFactory)); + assertTrue(OkHttpClientConfigurationTestApp.MyOkHttpClientFactory.class.isInstance(okHttpClientFactory)); + } + + @Test + public void testHttpClientWithFeign() { + Client delegate = feignClient.getDelegate(); + assertTrue(feign.okhttp.OkHttpClient.class.isInstance(delegate)); + feign.okhttp.OkHttpClient okHttpClient = (feign.okhttp.OkHttpClient)delegate; + OkHttpClient httpClient = getField(okHttpClient, "delegate"); + MockingDetails httpClientDetails = mockingDetails(httpClient); + assertTrue(httpClientDetails.isMock()); + } + + @Test + public void testOkHttpLoadBalancingHttpClient() { + RibbonCommandContext context = new RibbonCommandContext("foo"," GET", "http://localhost", + false, new LinkedMultiValueMap(), new LinkedMultiValueMap(), + null, new ArrayList(), 0l); + OkHttpRibbonCommand command = okHttpRibbonCommandFactory.create(context); + OkHttpLoadBalancingClient ribbonClient = command.getClient(); + OkHttpClient httpClient = getField(ribbonClient, "delegate"); + MockingDetails httpClientDetails = mockingDetails(httpClient); + assertTrue(httpClientDetails.isMock()); + } + + protected T getField(Object target, String name) { + Field field = ReflectionUtils.findField(target.getClass(), name); + ReflectionUtils.makeAccessible(field); + Object value = ReflectionUtils.getField(field, target); + return (T)value; + } +} + +@Configuration +@EnableAutoConfiguration +@RestController +//@EnableFeignClients(clients = {}) +@EnableZuulProxy +class OkHttpClientConfigurationTestApp { + + @RequestMapping + public String index() { + return "hello"; + } + + static class MyOkHttpClientConnectionPoolFactory extends DefaultOkHttpClientConnectionPoolFactory { + @Override + public ConnectionPool create(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) { + return new ConnectionPool(); + } + } + + static class MyOkHttpClientFactory extends DefaultOkHttpClientFactory { + @Override + public OkHttpClient create(boolean disableSslValidation, long connectTimeout, TimeUnit connectTimeoutUnit, boolean followRedirects, long readTimeout, TimeUnit readTimeoutUnit, ConnectionPool connectionPool, SSLSocketFactory sslSocketFactory, X509TrustManager x509TrustManager) { + return mock(OkHttpClient.class); + } + } + + @Configuration + static class MyConfig { + @Bean + public OkHttpClientConnectionPoolFactory connectionPoolFactory() { + return new MyOkHttpClientConnectionPoolFactory(); + } + + @Bean + public OkHttpClientFactory clientFactory() { + return new MyOkHttpClientFactory(); + } + + } + + @FeignClient(name="foo", serviceId = "foo") + static interface FooClient {} +} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/HttpClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ApacheHttpClientConfigurationTests.java similarity index 93% rename from spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/HttpClientConfigurationTests.java rename to spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ApacheHttpClientConfigurationTests.java index 7468f109..aca8c6cf 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/HttpClientConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ApacheHttpClientConfigurationTests.java @@ -75,10 +75,10 @@ import static org.mockito.Mockito.mockingDetails; * @author Ryan Baxter */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = HttpClientConfigurationTestApp.class, value = {"feign.okhttp.enabled: false", +@SpringBootTest(classes = ApacheHttpClientConfigurationTestApp.class, value = {"feign.okhttp.enabled: false", "ribbon.eureka.enabled = false"}) @DirtiesContext -public class HttpClientConfigurationTests { +public class ApacheHttpClientConfigurationTests { @Autowired ApacheHttpClientConnectionManagerFactory connectionManagerFactory; @@ -98,9 +98,9 @@ public class HttpClientConfigurationTests { @Test public void testFactories() { assertTrue(ApacheHttpClientConnectionManagerFactory.class.isInstance(connectionManagerFactory)); - assertTrue(HttpClientConfigurationTestApp.MyApacheHttpClientConnectionManagerFactory.class.isInstance(connectionManagerFactory)); + assertTrue(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientConnectionManagerFactory.class.isInstance(connectionManagerFactory)); assertTrue(ApacheHttpClientFactory.class.isInstance(httpClientFactory)); - assertTrue(HttpClientConfigurationTestApp.MyApacheHttpClientFactory.class.isInstance(httpClientFactory)); + assertTrue(ApacheHttpClientConfigurationTestApp.MyApacheHttpClientFactory.class.isInstance(httpClientFactory)); } @Test @@ -146,9 +146,9 @@ public class HttpClientConfigurationTests { @Configuration @EnableAutoConfiguration @RestController -@EnableFeignClients(clients = {HttpClientConfigurationTestApp.FooClient.class}) +@EnableFeignClients(clients = {ApacheHttpClientConfigurationTestApp.FooClient.class}) @EnableZuulProxy -class HttpClientConfigurationTestApp { +class ApacheHttpClientConfigurationTestApp { @RequestMapping public String index() { 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..ffd7c6ca 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.okhttp.enabled=true", "spring.cloud.httpclient.ok.enabled=true" }) @DirtiesContext public class FeignOkHttpTests { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java index efdac8ac..21c333a9 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java @@ -28,6 +28,7 @@ import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.OverrideRestClient; import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; @@ -151,27 +152,27 @@ public class RibbonClientConfigurationTests { @Test public void testDefaultsToApacheHttpClient() { testClient(RibbonLoadBalancingHttpClient.class, null, RestClient.class, OkHttpLoadBalancingClient.class); - testClient(RibbonLoadBalancingHttpClient.class, "ribbon.httpclient.enabled", RestClient.class, OkHttpLoadBalancingClient.class); + testClient(RibbonLoadBalancingHttpClient.class, new String[]{"spring.cloud.httpclient.apache.enable"}, RestClient.class, OkHttpLoadBalancingClient.class); } @Test public void testEnableRestClient() { - testClient(RestClient.class, "ribbon.restclient.enabled", RibbonLoadBalancingHttpClient.class, + testClient(RestClient.class, new String[]{"ribbon.restclient.enabled"}, RibbonLoadBalancingHttpClient.class, OkHttpLoadBalancingClient.class); } @Test public void testEnableOkHttpClient() { - testClient(OkHttpLoadBalancingClient.class, "ribbon.okhttp.enabled", RibbonLoadBalancingHttpClient.class, + testClient(OkHttpLoadBalancingClient.class, new String[]{"spring.cloud.httpclient.ok.enabled"}, RibbonLoadBalancingHttpClient.class, RestClient.class); } - void testClient(Class clientType, String property, Class... excludedTypes) { + void testClient(Class clientType, String[] properties, Class... excludedTypes) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(RibbonAutoConfiguration.class, + context.register(HttpClientConfiguration.class, RibbonAutoConfiguration.class, RibbonClientConfiguration.class); - if (property != null) { - EnvironmentTestUtils.addEnvironment(context, property); + if (properties != null) { + EnvironmentTestUtils.addEnvironment(context, properties); } context.refresh(); context.getBean(clientType); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java index 2411d0bf..eb622957 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java @@ -20,6 +20,8 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -124,7 +126,7 @@ public class OkHttpLoadBalancingClientTests { IClientConfig configOverride, SpringClientFactory factory) throws Exception { factory.setApplicationContext(new AnnotationConfigApplicationContext( - RibbonAutoConfiguration.class, defaultConfigurationClass)); + RibbonAutoConfiguration.class, OkHttpClientConfiguration.class, defaultConfigurationClass)); OkHttpLoadBalancingClient client = factory.getClient("service", OkHttpLoadBalancingClient.class); @@ -132,6 +134,19 @@ public class OkHttpLoadBalancingClientTests { return client.getOkHttpClient(configOverride, false); } + @Configuration + protected static class OkHttpClientConfiguration { + @Autowired(required = false) + IClientConfig clientConfig; + @Bean + public OkHttpLoadBalancingClient okHttpLoadBalancingClient() { + if(clientConfig == null) { + clientConfig = new DefaultClientConfigImpl(); + } + return new OkHttpLoadBalancingClient(new OkHttpClient(), clientConfig, new DefaultServerIntrospector()); + } + } + @Configuration protected static class UseDefaults { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java index ec5a4b9d..bb69994b 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java @@ -25,6 +25,7 @@ import org.springframework.cloud.ClassPathExclusions; import org.springframework.cloud.FilteredClassPathRunner; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; +import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; import org.springframework.context.ConfigurableApplicationContext; @@ -37,32 +38,42 @@ import static org.hamcrest.Matchers.instanceOf; * @author Ryan Baxter */ @RunWith(FilteredClassPathRunner.class) -@ClassPathExclusions({"spring-retry-*.jar", "spring-boot-starter-aop-*.jar"}) +@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) public class SpringRetryDisableOkHttpClientTests { private ConfigurableApplicationContext context; @Before public void setUp() { - context = new SpringApplicationBuilder().web(false).properties("ribbon.okhttp.enabled=true") - .sources(RibbonAutoConfiguration.class,LoadBalancerAutoConfiguration.class, RibbonClientConfiguration.class).run(); + context = new SpringApplicationBuilder().web(false) + .properties("spring.cloud.httpclient.ok.enabled=true") + .sources(RibbonAutoConfiguration.class, + LoadBalancerAutoConfiguration.class, + HttpClientConfiguration.class, + OkHttpLoadBalancingClientTests.OkHttpClientConfiguration.class, + RibbonClientConfiguration.class) + .run(); } @After public void tearDown() { - if(context != null) { + if (context != null) { context.close(); } } @Test public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class); + Map factories = context + .getBeansOfType(LoadBalancedRetryPolicyFactory.class); assertThat(factories.values(), hasSize(1)); - assertThat(factories.values().toArray()[0], instanceOf(LoadBalancedRetryPolicyFactory.NeverRetryFactory.class)); - Map clients = context.getBeansOfType(OkHttpLoadBalancingClient.class); + assertThat(factories.values().toArray()[0], + instanceOf(LoadBalancedRetryPolicyFactory.NeverRetryFactory.class)); + Map clients = context + .getBeansOfType(OkHttpLoadBalancingClient.class); assertThat(clients.values(), hasSize(1)); - assertThat(clients.values().toArray()[0], instanceOf(OkHttpLoadBalancingClient.class)); + assertThat(clients.values().toArray()[0], + instanceOf(OkHttpLoadBalancingClient.class)); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java index c8b3dcab..a9006634 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java @@ -22,6 +22,7 @@ import org.springframework.beans.BeansException; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory; import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; +import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory; @@ -38,20 +39,26 @@ import static org.hamcrest.Matchers.instanceOf; * @author Ryan Baxter */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(value = {"ribbon.okhttp.enabled: true"}) -@ContextConfiguration(classes = {RibbonAutoConfiguration.class, RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class}) +@SpringBootTest(value = { "spring.cloud.httpclient.ok.enabled: true" }) +@ContextConfiguration(classes = { RibbonAutoConfiguration.class, + HttpClientConfiguration.class, RibbonClientConfiguration.class, + LoadBalancerAutoConfiguration.class }) public class SpringRetryEnabledOkHttpClientTests implements ApplicationContextAware { private ApplicationContext context; @Test public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class); + Map factories = context + .getBeansOfType(LoadBalancedRetryPolicyFactory.class); assertThat(factories.values(), hasSize(1)); - assertThat(factories.values().toArray()[0], instanceOf(RibbonLoadBalancedRetryPolicyFactory.class)); - Map clients = context.getBeansOfType(OkHttpLoadBalancingClient.class); + assertThat(factories.values().toArray()[0], + instanceOf(RibbonLoadBalancedRetryPolicyFactory.class)); + Map clients = context + .getBeansOfType(OkHttpLoadBalancingClient.class); assertThat(clients.values(), hasSize(1)); - assertThat(clients.values().toArray()[0], instanceOf(RetryableOkHttpLoadBalancingClient.class)); + assertThat(clients.values().toArray()[0], + instanceOf(RetryableOkHttpLoadBalancingClient.class)); } @Override diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java index 48ca7300..81e92b83 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java @@ -43,20 +43,17 @@ public class ZuulProxyConfigurationTests { @Test public void testDefaultsToApacheHttpClient() { testClient(HttpClientRibbonCommandFactory.class, null); - testClient(HttpClientRibbonCommandFactory.class, "zuul.ribbon.httpclient.enabled=true"); - testClient(HttpClientRibbonCommandFactory.class, "ribbon.httpclient.enabled=true"); + testClient(HttpClientRibbonCommandFactory.class, "spring.cloud.httpclient.apache.enable=true"); } @Test public void testEnableRestClient() { - testClient(RestClientRibbonCommandFactory.class, "zuul.ribbon.restclient.enabled=true"); testClient(RestClientRibbonCommandFactory.class, "ribbon.restclient.enabled=true"); } @Test public void testEnableOkHttpClient() { - testClient(OkHttpRibbonCommandFactory.class, "zuul.ribbon.okhttp.enabled=true"); - testClient(OkHttpRibbonCommandFactory.class, "ribbon.okhttp.enabled=true"); + testClient(OkHttpRibbonCommandFactory.class, "spring.cloud.httpclient.ok.enabled=true"); } void testClient(Class clientType, String property) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java index bfd5b7ea..ff221ec3 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java @@ -32,9 +32,12 @@ import org.springframework.boot.autoconfigure.web.ErrorAttributes; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; +import org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; @@ -49,6 +52,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.web.bind.annotation.RestController; +import com.netflix.client.DefaultLoadBalancerRetryHandler; +import com.netflix.client.config.DefaultClientConfigImpl; +import com.netflix.client.config.IClientConfig; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = OkHttpRibbonCommandIntegrationTests.TestConfig.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { @@ -119,5 +125,19 @@ public class OkHttpRibbonCommandIntegrationTests extends ZuulProxyTestBase { public MyErrorController myErrorController(ErrorAttributes errorAttributes) { return new MyErrorController(errorAttributes); } + + @Bean + public IClientConfig config() { + return new DefaultClientConfigImpl(); + } + + @Bean + public OkHttpLoadBalancingClient okClient(IClientConfig config) { + final OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config, + new DefaultServerIntrospector()); + client.setLoadBalancer(new TestLoadBalancer<>()); + client.setRetryHandler(new DefaultLoadBalancerRetryHandler()); + return client; + } } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java index e8c39e3d..570f1323 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java @@ -30,7 +30,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = RibbonRetryIntegrationTestBase.RetryableTestConfig.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = { "zuul.retryable: false", /* Disable retry by default, have each route enable it */ - "ribbon.okhttp.enabled: true", "hystrix.command.default.execution.timeout.enabled: false", /* Disable hystrix so its timeout doesnt get in the way */ "ribbon.ReadTimeout: 1000", /* Make sure ribbon will timeout before the thread is done sleeping */ "zuul.routes.retryable: /retryable/**", @@ -49,7 +48,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; "disableretry.ribbon.MaxAutoRetriesNextServer: 1", "zuul.routes.globalretrydisabled: /globalretrydisabled/**", "globalretrydisabled.ribbon.MaxAutoRetries: 1", - "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1" + "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1", + "spring.cloud.httpclient.ok.enabled: true" }) @DirtiesContext public class OkHttpRibbonRetryIntegrationTests extends RibbonRetryIntegrationTestBase {