Merging PR #1689 into master
This commit is contained in:
@@ -1479,6 +1479,20 @@ The default HTTP client used by zuul is now backed by the Apache HTTP Client ins
|
||||
deprecated Ribbon `RestClient`. To use `RestClient` or to use the `okhttp3.OkHttpClient` set
|
||||
`ribbon.restclient.enabled=true` or `ribbon.okhttp.enabled=true` respectively.
|
||||
|
||||
==== Retrying Failed Requests
|
||||
|
||||
When using the Apache Http Client or the OK HTTP Client you can enable them to automatically
|
||||
retry failed requests by adding https://github.com/spring-projects/spring-retry[Spring Retry]
|
||||
to your application's classpath. When Zuul uses Ribbon, Zuul will honor some of the Ribbon
|
||||
configuration values related to retrying failed requests. The properties you can use are
|
||||
`client.ribbon.MaxAutoRetries`, `client.ribbon.MaxAutoRetriesNextServer`, and
|
||||
`client.ribbon.OkToRetryOnAllOperations`. See the https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties[Ribbon documentation]
|
||||
for a description of what there properties do.
|
||||
|
||||
You can turn off Zuul's retry functionality by setting `zuul.retryable` to `false`. You
|
||||
can also disable retry functionality on route by route basis by setting
|
||||
`zuul.routes.routename.retryable` to `false`.
|
||||
|
||||
=== Cookies and Sensitive Headers
|
||||
|
||||
It's OK to share headers between services in the same system, but you
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
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.actuator.HasFeatures;
|
||||
import org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration;
|
||||
@@ -38,11 +38,9 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFact
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
|
||||
import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.web.client.AsyncRestTemplate;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -90,6 +88,12 @@ public class RibbonAutoConfiguration {
|
||||
return new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
|
||||
public LoadBalancedRetryPolicyFactory neverRetryPolicyFactory() {
|
||||
return new LoadBalancedRetryPolicyFactory.NeverRetryFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public PropertiesFactory propertiesFactory() {
|
||||
|
||||
@@ -26,11 +26,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient;
|
||||
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
|
||||
import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient;
|
||||
import org.springframework.cloud.netflix.ribbon.okhttp.RetryableOkHttpLoadBalancingClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@@ -125,11 +128,26 @@ public class RibbonClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
|
||||
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
|
||||
public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient(
|
||||
IClientConfig config, ServerIntrospector serverIntrospector,
|
||||
ILoadBalancer loadBalancer, RetryHandler retryHandler) {
|
||||
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(
|
||||
config, serverIntrospector);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
client.setRetryHandler(retryHandler);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
|
||||
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
|
||||
public RetryableRibbonLoadBalancingHttpClient retryableRibbonLoadBalancingHttpClient(
|
||||
IClientConfig config, ServerIntrospector serverIntrospector,
|
||||
ILoadBalancer loadBalancer, RetryHandler retryHandler,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(
|
||||
RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient(
|
||||
config, serverIntrospector, loadBalancedRetryPolicyFactory);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
client.setRetryHandler(retryHandler);
|
||||
@@ -145,18 +163,37 @@ public class RibbonClientConfiguration {
|
||||
@Value("${ribbon.client.name}")
|
||||
private String name = "client";
|
||||
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
|
||||
public OkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config,
|
||||
ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer,
|
||||
RetryHandler retryHandler, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config,
|
||||
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
|
||||
public RetryableOkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config,
|
||||
ServerIntrospector serverIntrospector,
|
||||
ILoadBalancer loadBalancer,
|
||||
RetryHandler retryHandler,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient(config,
|
||||
serverIntrospector, loadBalancedRetryPolicyFactory);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
client.setRetryHandler(retryHandler);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
|
||||
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
|
||||
public OkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient(IClientConfig config,
|
||||
ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer,
|
||||
RetryHandler retryHandler) {
|
||||
OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config,
|
||||
serverIntrospector);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
client.setRetryHandler(retryHandler);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.ribbon.apache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.FeignRetryPolicy;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
import org.springframework.retry.RetryContext;
|
||||
import org.springframework.retry.policy.NeverRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import com.netflix.client.RequestSpecificRetryHandler;
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
/**
|
||||
* An Apache HTTP client which leverages Spring Retry to retry failed requests.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class RetryableRibbonLoadBalancingHttpClient extends RibbonLoadBalancingHttpClient implements ServiceInstanceChooser {
|
||||
private LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory =
|
||||
new LoadBalancedRetryPolicyFactory.NeverRetryFactory();
|
||||
public RetryableRibbonLoadBalancingHttpClient(IClientConfig config, ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
super(config, serverIntrospector);
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RibbonApacheHttpResponse execute(final RibbonApacheHttpRequest request, final IClientConfig configOverride) throws Exception {
|
||||
final RequestConfig.Builder builder = RequestConfig.custom();
|
||||
IClientConfig config = configOverride != null ? configOverride : this.config;
|
||||
builder.setConnectTimeout(config.get(
|
||||
CommonClientConfigKey.ConnectTimeout, this.connectTimeout));
|
||||
builder.setSocketTimeout(config.get(
|
||||
CommonClientConfigKey.ReadTimeout, this.readTimeout));
|
||||
builder.setRedirectsEnabled(config.get(
|
||||
CommonClientConfigKey.FollowRedirects, this.followRedirects));
|
||||
|
||||
final RequestConfig requestConfig = builder.build();
|
||||
return this.executeWithRetry(request, new RetryCallback() {
|
||||
@Override
|
||||
public RibbonApacheHttpResponse doWithRetry(RetryContext context) throws Exception {
|
||||
//on retries the policy will choose the server and set it in the context
|
||||
//extract the server and update the request being made
|
||||
RibbonApacheHttpRequest newRequest = request;
|
||||
if(context instanceof LoadBalancedRetryContext) {
|
||||
ServiceInstance service = ((LoadBalancedRetryContext)context).getServiceInstance();
|
||||
if(service != null) {
|
||||
//Reconstruct the request URI using the host and port set in the retry context
|
||||
newRequest = newRequest.withNewUri(new URI(service.getUri().getScheme(),
|
||||
newRequest.getURI().getUserInfo(), service.getHost(), service.getPort(),
|
||||
newRequest.getURI().getPath(), newRequest.getURI().getQuery(),
|
||||
newRequest.getURI().getFragment()));
|
||||
}
|
||||
}
|
||||
if (isSecure(configOverride)) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(newRequest.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
newRequest = newRequest.withNewUri(secureUri);
|
||||
}
|
||||
HttpUriRequest httpUriRequest = newRequest.toRequest(requestConfig);
|
||||
final HttpResponse httpResponse = RetryableRibbonLoadBalancingHttpClient.this.delegate.execute(httpUriRequest);
|
||||
return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private RibbonApacheHttpResponse executeWithRetry(RibbonApacheHttpRequest request, RetryCallback<RibbonApacheHttpResponse, IOException> callback) throws Exception {
|
||||
LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryPolicyFactory.create(this.getClientName(), this);
|
||||
RetryTemplate retryTemplate = new RetryTemplate();
|
||||
boolean retryable = request.getContext() == null ? true :
|
||||
BooleanUtils.toBooleanDefaultIfNull(request.getContext().getRetryable(), true);
|
||||
retryTemplate.setRetryPolicy(retryPolicy == null || !retryable ? new NeverRetryPolicy()
|
||||
: new RetryPolicy(request, retryPolicy, this, this.getClientName()));
|
||||
return retryTemplate.execute(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
Server server = this.getLoadBalancer().chooseServer(serviceId);
|
||||
return new RibbonLoadBalancerClient.RibbonServer(serviceId,
|
||||
server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(RibbonApacheHttpRequest request, IClientConfig requestConfig) {
|
||||
return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null);
|
||||
}
|
||||
|
||||
static class RetryPolicy extends FeignRetryPolicy {
|
||||
public RetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, ServiceInstanceChooser serviceInstanceChooser, String serviceName) {
|
||||
super(request, policy, serviceInstanceChooser, serviceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,14 +27,8 @@ import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient;
|
||||
import org.springframework.cloud.netflix.ribbon.support.RetryableLoadBalancingClient;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
import org.springframework.retry.RetryContext;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
@@ -46,8 +40,8 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
//TODO: rename (ie new class that extends this in Dalston) to ApacheHttpLoadBalancingClient
|
||||
public class RibbonLoadBalancingHttpClient
|
||||
extends RetryableLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse, HttpClient> {
|
||||
public class RibbonLoadBalancingHttpClient extends
|
||||
AbstractLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse, HttpClient> {
|
||||
|
||||
@Deprecated
|
||||
public RibbonLoadBalancingHttpClient() {
|
||||
@@ -67,11 +61,6 @@ public class RibbonLoadBalancingHttpClient
|
||||
super(delegate, config, serverIntrospector);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancingHttpClient(IClientConfig iClientConfig, ServerIntrospector serverIntrospector,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
super(iClientConfig, serverIntrospector, loadBalancedRetryPolicyFactory);
|
||||
}
|
||||
|
||||
protected HttpClient createDelegate(IClientConfig config) {
|
||||
return HttpClientBuilder.create()
|
||||
// already defaults to 0 in builder, so resetting to 0 won't hurt
|
||||
@@ -84,7 +73,7 @@ public class RibbonLoadBalancingHttpClient
|
||||
}
|
||||
|
||||
@Override
|
||||
public RibbonApacheHttpResponse execute(final RibbonApacheHttpRequest request,
|
||||
public RibbonApacheHttpResponse execute(RibbonApacheHttpRequest request,
|
||||
final IClientConfig configOverride) throws Exception {
|
||||
final RequestConfig.Builder builder = RequestConfig.custom();
|
||||
IClientConfig config = configOverride != null ? configOverride : this.config;
|
||||
@@ -96,32 +85,14 @@ public class RibbonLoadBalancingHttpClient
|
||||
CommonClientConfigKey.FollowRedirects, this.followRedirects));
|
||||
|
||||
final RequestConfig requestConfig = builder.build();
|
||||
return this.executeWithRetry(request, new RetryCallback() {
|
||||
@Override
|
||||
public RibbonApacheHttpResponse doWithRetry(RetryContext context) throws Exception {
|
||||
//on retries the policy will choose the server and set it in the context
|
||||
//extract the server and update the request being made
|
||||
RibbonApacheHttpRequest newRequest = request;
|
||||
if(context instanceof LoadBalancedRetryContext) {
|
||||
ServiceInstance service = ((LoadBalancedRetryContext)context).getServiceInstance();
|
||||
if(service != null) {
|
||||
//Reconstruct the request URI using the host and port set in the retry context
|
||||
newRequest = newRequest.withNewUri(new URI(service.getUri().getScheme(),
|
||||
newRequest.getURI().getUserInfo(), service.getHost(), service.getPort(),
|
||||
newRequest.getURI().getPath(), newRequest.getURI().getQuery(),
|
||||
newRequest.getURI().getFragment()));
|
||||
}
|
||||
}
|
||||
if (isSecure(configOverride)) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(newRequest.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
newRequest = newRequest.withNewUri(secureUri);
|
||||
}
|
||||
HttpUriRequest httpUriRequest = newRequest.toRequest(requestConfig);
|
||||
final HttpResponse httpResponse = RibbonLoadBalancingHttpClient.this.delegate.execute(httpUriRequest);
|
||||
return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI());
|
||||
}
|
||||
});
|
||||
if (isSecure(configOverride)) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(request.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
request = request.withNewUri(secureUri);
|
||||
}
|
||||
final HttpUriRequest httpUriRequest = request.toRequest(requestConfig);
|
||||
final HttpResponse httpResponse = this.delegate.execute(httpUriRequest);
|
||||
return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,4 +100,9 @@ public class RibbonLoadBalancingHttpClient
|
||||
URI uri = updateToHttpsIfNeeded(original, this.config, this.serverIntrospector, server);
|
||||
return super.reconstructURIWithServer(server, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(RibbonApacheHttpRequest request, IClientConfig requestConfig) {
|
||||
return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,8 @@ package org.springframework.cloud.netflix.ribbon.okhttp;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.support.RetryableLoadBalancingClient;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
import org.springframework.retry.RetryContext;
|
||||
import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
@@ -44,7 +39,7 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class OkHttpLoadBalancingClient
|
||||
extends RetryableLoadBalancingClient<OkHttpRibbonRequest, OkHttpRibbonResponse, OkHttpClient> {
|
||||
extends AbstractLoadBalancingClient<OkHttpRibbonRequest, OkHttpRibbonResponse, OkHttpClient> {
|
||||
|
||||
@Deprecated
|
||||
public OkHttpLoadBalancingClient() {
|
||||
@@ -61,12 +56,6 @@ public class OkHttpLoadBalancingClient
|
||||
super(config, serverIntrospector);
|
||||
}
|
||||
|
||||
public OkHttpLoadBalancingClient(IClientConfig config,
|
||||
ServerIntrospector serverIntrospector,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
super(config, serverIntrospector, loadBalancedRetryPolicyFactory);
|
||||
}
|
||||
|
||||
public OkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config,
|
||||
ServerIntrospector serverIntrospector) {
|
||||
super(delegate, config, serverIntrospector);
|
||||
@@ -78,36 +67,19 @@ public class OkHttpLoadBalancingClient
|
||||
}
|
||||
|
||||
@Override
|
||||
public OkHttpRibbonResponse execute(final OkHttpRibbonRequest ribbonRequest,
|
||||
public OkHttpRibbonResponse execute(OkHttpRibbonRequest ribbonRequest,
|
||||
final IClientConfig configOverride) throws Exception {
|
||||
return this.executeWithRetry(ribbonRequest, new RetryCallback() {
|
||||
@Override
|
||||
public OkHttpRibbonResponse doWithRetry(RetryContext context) throws Exception {
|
||||
//on retries the policy will choose the server and set it in the context
|
||||
//extract the server and update the request being made
|
||||
OkHttpRibbonRequest newRequest = ribbonRequest;
|
||||
if(context instanceof LoadBalancedRetryContext) {
|
||||
ServiceInstance service = ((LoadBalancedRetryContext)context).getServiceInstance();
|
||||
if(service != null) {
|
||||
//Reconstruct the request URI using the host and port set in the retry context
|
||||
newRequest = newRequest.withNewUri(new URI(service.getUri().getScheme(),
|
||||
newRequest.getURI().getUserInfo(), service.getHost(), service.getPort(),
|
||||
newRequest.getURI().getPath(), newRequest.getURI().getQuery(),
|
||||
newRequest.getURI().getFragment()));
|
||||
}
|
||||
}
|
||||
if (isSecure(configOverride)) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(newRequest.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
newRequest = newRequest.withNewUri(secureUri);
|
||||
}
|
||||
OkHttpClient httpClient = getOkHttpClient(configOverride, secure);
|
||||
boolean secure = isSecure(configOverride);
|
||||
if (secure) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(ribbonRequest.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
ribbonRequest = ribbonRequest.withNewUri(secureUri);
|
||||
}
|
||||
|
||||
final Request request = newRequest.toRequest();
|
||||
Response response = httpClient.newCall(request).execute();
|
||||
return new OkHttpRibbonResponse(response, newRequest.getUri());
|
||||
}
|
||||
});
|
||||
OkHttpClient httpClient = getOkHttpClient(configOverride, secure);
|
||||
final Request request = ribbonRequest.toRequest();
|
||||
Response response = httpClient.newCall(request).execute();
|
||||
return new OkHttpRibbonResponse(response, ribbonRequest.getUri());
|
||||
}
|
||||
|
||||
OkHttpClient getOkHttpClient(IClientConfig configOverride, boolean secure) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2013-2016 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.
|
||||
@@ -13,15 +12,18 @@
|
||||
* 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.ribbon.okhttp;
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.support;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
|
||||
@@ -30,57 +32,32 @@ import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.retry.RetryCallback;
|
||||
import org.springframework.retry.RetryContext;
|
||||
import org.springframework.retry.policy.NeverRetryPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import com.netflix.client.IResponse;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import com.netflix.client.RequestSpecificRetryHandler;
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
/**
|
||||
* A load balancing client which uses Spring Retry to retry failed requests.
|
||||
* An OK HTTP client which leverages Spring Retry to retry failed request.
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class RetryableLoadBalancingClient<S extends ContextAwareRequest, T extends IResponse, D>
|
||||
extends AbstractLoadBalancingClient<S, T, D> implements ServiceInstanceChooser {
|
||||
public class RetryableOkHttpLoadBalancingClient extends OkHttpLoadBalancingClient implements ServiceInstanceChooser {
|
||||
|
||||
protected LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory =
|
||||
new LoadBalancedRetryPolicyFactory.NeverRetryFactory();
|
||||
private LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
|
||||
|
||||
@Deprecated
|
||||
public RetryableLoadBalancingClient() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public RetryableLoadBalancingClient(final ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
|
||||
public RetryableLoadBalancingClient(IClientConfig config, ServerIntrospector serverIntrospector) {
|
||||
public RetryableOkHttpLoadBalancingClient(IClientConfig config, ServerIntrospector serverIntrospector,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
super(config, serverIntrospector);
|
||||
}
|
||||
|
||||
public RetryableLoadBalancingClient(D delegate, IClientConfig config, ServerIntrospector serverIntrospector) {
|
||||
super(delegate, config, serverIntrospector);
|
||||
}
|
||||
|
||||
public RetryableLoadBalancingClient(IClientConfig iClientConfig, ServerIntrospector serverIntrospector,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
this(iClientConfig, serverIntrospector);
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a {@link S} using Spring Retry.
|
||||
* @param request The request to execute.
|
||||
* @param callback The retry callback to use.
|
||||
* @return The response.
|
||||
* @throws Exception Thrown if there is an error making the request and a retry cannot be completed successfully.
|
||||
*/
|
||||
protected T executeWithRetry(S request, RetryCallback<T, IOException> callback) throws Exception {
|
||||
private OkHttpRibbonResponse executeWithRetry(OkHttpRibbonRequest request,
|
||||
RetryCallback<OkHttpRibbonResponse, IOException> callback)
|
||||
throws Exception {
|
||||
LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryPolicyFactory.create(this.getClientName(), this);
|
||||
RetryTemplate retryTemplate = new RetryTemplate();
|
||||
boolean retryable = request.getContext() == null ? true :
|
||||
@@ -90,6 +67,39 @@ public abstract class RetryableLoadBalancingClient<S extends ContextAwareRequest
|
||||
return retryTemplate.execute(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OkHttpRibbonResponse execute(final OkHttpRibbonRequest ribbonRequest,
|
||||
final IClientConfig configOverride) throws Exception {
|
||||
return this.executeWithRetry(ribbonRequest, new RetryCallback() {
|
||||
@Override
|
||||
public OkHttpRibbonResponse doWithRetry(RetryContext context) throws Exception {
|
||||
//on retries the policy will choose the server and set it in the context
|
||||
//extract the server and update the request being made
|
||||
OkHttpRibbonRequest newRequest = ribbonRequest;
|
||||
if(context instanceof LoadBalancedRetryContext) {
|
||||
ServiceInstance service = ((LoadBalancedRetryContext)context).getServiceInstance();
|
||||
if(service != null) {
|
||||
//Reconstruct the request URI using the host and port set in the retry context
|
||||
newRequest = newRequest.withNewUri(new URI(service.getUri().getScheme(),
|
||||
newRequest.getURI().getUserInfo(), service.getHost(), service.getPort(),
|
||||
newRequest.getURI().getPath(), newRequest.getURI().getQuery(),
|
||||
newRequest.getURI().getFragment()));
|
||||
}
|
||||
}
|
||||
if (isSecure(configOverride)) {
|
||||
final URI secureUri = UriComponentsBuilder.fromUri(newRequest.getUri())
|
||||
.scheme("https").build().toUri();
|
||||
newRequest = newRequest.withNewUri(secureUri);
|
||||
}
|
||||
OkHttpClient httpClient = getOkHttpClient(configOverride, secure);
|
||||
|
||||
final Request request = newRequest.toRequest();
|
||||
Response response = httpClient.newCall(request).execute();
|
||||
return new OkHttpRibbonResponse(response, newRequest.getUri());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
Server server = this.getLoadBalancer().chooseServer(serviceId);
|
||||
@@ -98,7 +108,7 @@ public abstract class RetryableLoadBalancingClient<S extends ContextAwareRequest
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(S request, IClientConfig requestConfig) {
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(OkHttpRibbonRequest request, IClientConfig requestConfig) {
|
||||
return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null);
|
||||
}
|
||||
|
||||
@@ -107,5 +117,4 @@ public abstract class RetryableLoadBalancingClient<S extends ContextAwareRequest
|
||||
super(request, policy, serviceInstanceChooser, serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,10 +28,12 @@ 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.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
@@ -45,7 +47,7 @@ public class SpringRetryDisabledTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new SpringApplicationBuilder().web(false)
|
||||
.sources(RibbonAutoConfiguration.class,LoadBalancerAutoConfiguration.class).run();
|
||||
.sources(RibbonAutoConfiguration.class,LoadBalancerAutoConfiguration.class, RibbonClientConfiguration.class).run();
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -58,6 +60,10 @@ public class SpringRetryDisabledTests {
|
||||
@Test
|
||||
public void testLoadBalancedRetryFactoryBean() throws Exception {
|
||||
Map<String, LoadBalancedRetryPolicyFactory> factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class);
|
||||
assertThat(factories.values(), hasSize(0));
|
||||
assertThat(factories.values(), hasSize(1));
|
||||
assertThat(factories.values().toArray()[0], instanceOf(LoadBalancedRetryPolicyFactory.NeverRetryFactory.class));
|
||||
Map<String, RibbonLoadBalancingHttpClient> clients = context.getBeansOfType(RibbonLoadBalancingHttpClient.class);
|
||||
assertThat(clients.values(), hasSize(1));
|
||||
assertThat(clients.values().toArray()[0], instanceOf(RibbonLoadBalancingHttpClient.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient;
|
||||
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -37,7 +39,7 @@ import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {RibbonAutoConfiguration.class, LoadBalancerAutoConfiguration.class})
|
||||
@ContextConfiguration(classes = {RibbonAutoConfiguration.class, RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class})
|
||||
public class SpringRetryEnabledTests implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
@@ -47,6 +49,9 @@ public class SpringRetryEnabledTests implements ApplicationContextAware {
|
||||
Map<String, LoadBalancedRetryPolicyFactory> factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class);
|
||||
assertThat(factories.values(), hasSize(1));
|
||||
assertThat(factories.values().toArray()[0], instanceOf(RibbonLoadBalancedRetryPolicyFactory.class));
|
||||
Map<String, RibbonLoadBalancingHttpClient> clients = context.getBeansOfType(RibbonLoadBalancingHttpClient.class);
|
||||
assertThat(clients.values(), hasSize(1));
|
||||
assertThat(clients.values().toArray()[0], instanceOf(RetryableRibbonLoadBalancingHttpClient.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -113,8 +113,8 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setApplicationContext(new AnnotationConfigApplicationContext(
|
||||
RibbonAutoConfiguration.class, Connections.class));
|
||||
RibbonLoadBalancingHttpClient client = factory.getClient("service",
|
||||
RibbonLoadBalancingHttpClient.class);
|
||||
RetryableRibbonLoadBalancingHttpClient client = factory.getClient("service",
|
||||
RetryableRibbonLoadBalancingHttpClient.class);
|
||||
|
||||
HttpClient delegate = client.getDelegate();
|
||||
PoolingHttpClientConnectionManager connManager = (PoolingHttpClientConnectionManager) ReflectionTestUtils.getField(delegate, "connManager");
|
||||
@@ -182,7 +182,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
}
|
||||
}
|
||||
|
||||
private RibbonLoadBalancingHttpClient setupClientForRetry(int retriesNextServer, int retriesSameServer,
|
||||
private RetryableRibbonLoadBalancingHttpClient setupClientForRetry(int retriesNextServer, int retriesSameServer,
|
||||
boolean retryable, boolean retryOnAllOps,
|
||||
String serviceName, String host, int port,
|
||||
HttpClient delegate, ILoadBalancer lb) throws Exception {
|
||||
@@ -198,7 +198,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName));
|
||||
LoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(clientConfig, introspector, factory);
|
||||
RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient(clientConfig, introspector, factory);
|
||||
client.setLoadBalancer(lb);
|
||||
ReflectionTestUtils.setField(client, "delegate", delegate);
|
||||
return client;
|
||||
@@ -219,7 +219,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
final HttpResponse response = mock(HttpResponse.class);
|
||||
doThrow(new IOException("boom")).doReturn(response).when(delegate).execute(any(HttpUriRequest.class));
|
||||
ILoadBalancer lb = mock(ILoadBalancer.class);
|
||||
RibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
serviceName, host, port, delegate, lb);
|
||||
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
|
||||
doReturn(uri).when(request).getURI();
|
||||
@@ -249,7 +249,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
doThrow(new IOException("boom")).doThrow(new IOException("boom again")).doReturn(response).
|
||||
when(delegate).execute(any(HttpUriRequest.class));
|
||||
ILoadBalancer lb = mock(ILoadBalancer.class);
|
||||
RibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
serviceName, host, port, delegate, lb);
|
||||
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
|
||||
doReturn(uri).when(request).getURI();
|
||||
@@ -279,7 +279,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
doThrow(new IOException("boom")).doThrow(new IOException("boom again")).doReturn(response).
|
||||
when(delegate).execute(any(HttpUriRequest.class));
|
||||
ILoadBalancer lb = mock(ILoadBalancer.class);
|
||||
RibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
serviceName, host, port, delegate, lb);
|
||||
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
|
||||
doReturn(method).when(request).getMethod();
|
||||
@@ -308,7 +308,7 @@ public class RibbonLoadBalancingHttpClientTests {
|
||||
doThrow(new IOException("boom")).doThrow(new IOException("boom again")).doReturn(response).
|
||||
when(delegate).execute(any(HttpUriRequest.class));
|
||||
ILoadBalancer lb = mock(ILoadBalancer.class);
|
||||
RibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry(retriesNextServer, retriesSameServer, retryable, retryOnAllOps,
|
||||
serviceName, host, port, delegate, lb);
|
||||
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
|
||||
doReturn(method).when(request).getMethod();
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.ribbon.okhttp;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
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.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(FilteredClassPathRunner.class)
|
||||
@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();
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadBalancedRetryFactoryBean() throws Exception {
|
||||
Map<String, LoadBalancedRetryPolicyFactory> factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class);
|
||||
assertThat(factories.values(), hasSize(1));
|
||||
assertThat(factories.values().toArray()[0], instanceOf(LoadBalancedRetryPolicyFactory.NeverRetryFactory.class));
|
||||
Map<String, OkHttpLoadBalancingClient> clients = context.getBeansOfType(OkHttpLoadBalancingClient.class);
|
||||
assertThat(clients.values(), hasSize(1));
|
||||
assertThat(clients.values().toArray()[0], instanceOf(OkHttpLoadBalancingClient.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.ribbon.okhttp;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
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.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
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})
|
||||
public class SpringRetryEnabledOkHttpClientTests implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testLoadBalancedRetryFactoryBean() throws Exception {
|
||||
Map<String, LoadBalancedRetryPolicyFactory> factories = context.getBeansOfType(LoadBalancedRetryPolicyFactory.class);
|
||||
assertThat(factories.values(), hasSize(1));
|
||||
assertThat(factories.values().toArray()[0], instanceOf(RibbonLoadBalancedRetryPolicyFactory.class));
|
||||
Map<String, OkHttpLoadBalancingClient> clients = context.getBeansOfType(OkHttpLoadBalancingClient.class);
|
||||
assertThat(clients.values(), hasSize(1));
|
||||
assertThat(clients.values().toArray()[0], instanceOf(RetryableOkHttpLoadBalancingClient.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,6 @@
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user