Initial implementation of retry logic using Spring Retry

This commit is contained in:
Ryan Baxter
2017-02-09 09:58:25 -05:00
parent f304ab7101
commit 08ba0cc72b
8 changed files with 332 additions and 47 deletions
@@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient;
import org.springframework.context.annotation.Bean;
@@ -126,9 +127,10 @@ public class RibbonClientConfiguration {
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler) {
ILoadBalancer loadBalancer, RetryHandler retryHandler,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(
config, serverIntrospector);
config, serverIntrospector, loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
@@ -147,9 +149,9 @@ public class RibbonClientConfiguration {
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
public OkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config,
ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer,
RetryHandler retryHandler) {
RetryHandler retryHandler, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config,
serverIntrospector);
serverIntrospector, loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
@@ -23,12 +23,15 @@ 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 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.ILoadBalancer;
@@ -38,11 +41,11 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
/**
* @author Christian Lohmann
* @author Ryan Baxter
*/
//TODO: rename (ie new class that extends this in Dalston) to ApacheHttpLoadBalancingClient
public class RibbonLoadBalancingHttpClient
extends
AbstractLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse, HttpClient> {
extends RetryableLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse, HttpClient> {
@Deprecated
public RibbonLoadBalancingHttpClient() {
@@ -62,6 +65,11 @@ 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
@@ -74,7 +82,7 @@ public class RibbonLoadBalancingHttpClient
}
@Override
public RibbonApacheHttpResponse execute(RibbonApacheHttpRequest request,
public RibbonApacheHttpResponse execute(final RibbonApacheHttpRequest request,
final IClientConfig configOverride) throws Exception {
final RequestConfig.Builder builder = RequestConfig.custom();
IClientConfig config = configOverride != null ? configOverride : this.config;
@@ -86,16 +94,32 @@ public class RibbonLoadBalancingHttpClient
CommonClientConfigKey.FollowRedirects, this.followRedirects));
final RequestConfig requestConfig = builder.build();
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());
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());
}
});
}
@Override
@@ -103,10 +127,4 @@ 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,8 +19,13 @@ 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.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 com.netflix.client.config.CommonClientConfigKey;
@@ -36,9 +41,10 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
/**
* @author Spencer Gibb
* @author Ryan Baxter
*/
public class OkHttpLoadBalancingClient
extends AbstractLoadBalancingClient<OkHttpRibbonRequest, OkHttpRibbonResponse, OkHttpClient> {
extends RetryableLoadBalancingClient<OkHttpRibbonRequest, OkHttpRibbonResponse, OkHttpClient> {
@Deprecated
public OkHttpLoadBalancingClient() {
@@ -55,6 +61,12 @@ 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);
@@ -66,21 +78,36 @@ public class OkHttpLoadBalancingClient
}
@Override
public OkHttpRibbonResponse execute(OkHttpRibbonRequest ribbonRequest,
public OkHttpRibbonResponse execute(final OkHttpRibbonRequest ribbonRequest,
final IClientConfig configOverride) throws Exception {
boolean secure = isSecure(configOverride);
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);
if (secure) {
final URI secureUri = UriComponentsBuilder.fromUri(ribbonRequest.getUri())
.scheme("https").build().toUri();
ribbonRequest = ribbonRequest.withNewUri(secureUri);
}
OkHttpClient httpClient = getOkHttpClient(configOverride, secure);
final Request request = ribbonRequest.toRequest();
Response response = httpClient.newCall(request).execute();
return new OkHttpRibbonResponse(response, ribbonRequest.getUri());
final Request request = newRequest.toRequest();
Response response = httpClient.newCall(request).execute();
return new OkHttpRibbonResponse(response, newRequest.getUri());
}
});
}
OkHttpClient getOkHttpClient(IClientConfig configOverride, boolean secure) {
@@ -18,18 +18,29 @@
package org.springframework.cloud.netflix.ribbon.support;
import com.netflix.client.ClientRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext;
import org.springframework.util.MultiValueMap;
import java.net.URI;
/**
* @author Spencer Gibb
* @author Ryan Baxter
*/
public abstract class ContextAwareRequest extends ClientRequest {
public abstract class ContextAwareRequest extends ClientRequest implements HttpRequest {
protected final RibbonCommandContext context;
private HttpHeaders httpHeaders;
public ContextAwareRequest(RibbonCommandContext context) {
this.context = context;
MultiValueMap<String, String> headers = context.getHeaders();
this.httpHeaders = new HttpHeaders();
for(String key : headers.keySet()) {
this.httpHeaders.put(key, headers.get(key));
}
this.uri = context.uri();
this.isRetriable = context.getRetryable();
}
@@ -38,6 +49,21 @@ public abstract class ContextAwareRequest extends ClientRequest {
return context;
}
@Override
public HttpMethod getMethod() {
return HttpMethod.valueOf(context.getMethod());
}
@Override
public URI getURI() {
return this.getUri();
}
@Override
public HttpHeaders getHeaders() {
return httpHeaders;
}
protected RibbonCommandContext newContext(URI uri) {
RibbonCommandContext commandContext = new RibbonCommandContext(this.context.getServiceId(),
this.context.getMethod(), uri.toString(), this.context.getRetryable(),
@@ -16,36 +16,70 @@
package org.springframework.cloud.netflix.ribbon.apache;
import java.io.IOException;
import java.net.URI;
import org.apache.http.HttpResponse;
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.conn.PoolingHttpClientConnectionManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.test.util.ReflectionTestUtils;
import com.netflix.client.DefaultLoadBalancerRetryHandler;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Sébastien Nussbaumer
* @author Ryan Baxter
*/
public class RibbonLoadBalancingHttpClientTests {
private ILoadBalancer loadBalancer;
@Before
public void setup() {
loadBalancer = mock(AbstractLoadBalancer.class);
doReturn(new Server("foo.com", 8000)).when(loadBalancer).chooseServer(eq("default"));
doReturn(new Server("foo.com", 8000)).when(loadBalancer).chooseServer(eq("service"));
}
@After
public void teardown() {
loadBalancer = null;
}
@Test
public void testRequestConfigUseDefaultsNoOverride() throws Exception {
RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null);
@@ -129,6 +163,169 @@ public class RibbonLoadBalancingHttpClientTests {
assertThat(result.getSocketTimeout(), is (50));
}
@Test
public void testNeverRetry() throws Exception {
ServerIntrospector introspector = mock(ServerIntrospector.class);
HttpClient delegate = mock(HttpClient.class);
HttpResponse response = mock(HttpResponse.class);
doThrow(new IOException("boom")).when(delegate).execute(any(HttpUriRequest.class));
DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl();
clientConfig.setClientName("foo");
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(delegate, clientConfig,
introspector);
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
try {
client.execute(request, null);
fail("Expected IOException");
} catch(IOException e) {} finally {
verify(delegate, times(1)).execute(any(HttpUriRequest.class));
}
}
private RibbonLoadBalancingHttpClient setupClientForRetry(int retriesNextServer, int retriesSameServer,
boolean retryable, boolean retryOnAllOps,
String serviceName, String host, int port,
HttpClient delegate, ILoadBalancer lb) throws Exception {
ServerIntrospector introspector = mock(ServerIntrospector.class);
RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(retriesSameServer, retriesNextServer, retryable);
doReturn(new Server(host, port)).when(lb).chooseServer(eq(serviceName));
DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl();
clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, retryOnAllOps);
clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, retriesNextServer);
clientConfig.set(CommonClientConfigKey.MaxAutoRetries, retriesSameServer);
clientConfig.setClientName(serviceName);
RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, clientConfig, retryHandler);
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName));
LoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(clientConfig, introspector, factory);
client.setLoadBalancer(lb);
ReflectionTestUtils.setField(client, "delegate", delegate);
return client;
}
@Test
public void testRetrySameServerOnly() throws Exception {
int retriesNextServer = 0;
int retriesSameServer = 1;
boolean retryable = true;
boolean retryOnAllOps = false;
String serviceName = "foo";
String host = serviceName;
int port = 80;
HttpMethod method = HttpMethod.GET;
URI uri = new URI("http://" + host + ":" + port);
HttpClient delegate = mock(HttpClient.class);
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,
serviceName, host, port, delegate, lb);
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
doReturn(uri).when(request).getURI();
doReturn(method).when(request).getMethod();
doReturn(request).when(request).withNewUri(any(URI.class));
HttpUriRequest uriRequest = mock(HttpUriRequest.class);
doReturn(uri).when(uriRequest).getURI();
doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class));
RibbonApacheHttpResponse returnedResponse = client.execute(request, null);
verify(delegate, times(2)).execute(any(HttpUriRequest.class));
verify(lb, times(0)).chooseServer(eq(serviceName));
}
@Test
public void testRetryNextServer() throws Exception {
int retriesNextServer = 1;
int retriesSameServer = 1;
boolean retryable = true;
boolean retryOnAllOps = false;
String serviceName = "foo";
String host = serviceName;
int port = 80;
HttpMethod method = HttpMethod.GET;
URI uri = new URI("http://" + host + ":" + port);
HttpClient delegate = mock(HttpClient.class);
final HttpResponse response = mock(HttpResponse.class);
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,
serviceName, host, port, delegate, lb);
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
doReturn(uri).when(request).getURI();
doReturn(method).when(request).getMethod();
doReturn(request).when(request).withNewUri(any(URI.class));
HttpUriRequest uriRequest = mock(HttpUriRequest.class);
doReturn(uri).when(uriRequest).getURI();
doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class));
RibbonApacheHttpResponse returnedResponse = client.execute(request, null);
verify(delegate, times(3)).execute(any(HttpUriRequest.class));
verify(lb, times(1)).chooseServer(eq(serviceName));
}
@Test
public void testRetryOnPost() throws Exception {
int retriesNextServer = 1;
int retriesSameServer = 1;
boolean retryable = true;
boolean retryOnAllOps = true;
String serviceName = "foo";
String host = serviceName;
int port = 80;
HttpMethod method = HttpMethod.POST;
URI uri = new URI("http://" + host + ":" + port);
HttpClient delegate = mock(HttpClient.class);
final HttpResponse response = mock(HttpResponse.class);
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,
serviceName, host, port, delegate, lb);
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
doReturn(method).when(request).getMethod();
doReturn(uri).when(request).getURI();
doReturn(request).when(request).withNewUri(any(URI.class));
HttpUriRequest uriRequest = mock(HttpUriRequest.class);
doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class));
RibbonApacheHttpResponse returnedResponse = client.execute(request, null);
verify(delegate, times(3)).execute(any(HttpUriRequest.class));
verify(lb, times(1)).chooseServer(eq(serviceName));
}
@Test
public void testNoRetryOnPost() throws Exception {
int retriesNextServer = 1;
int retriesSameServer = 1;
boolean retryable = true;
boolean retryOnAllOps = false;
String serviceName = "foo";
String host = serviceName;
int port = 80;
HttpMethod method = HttpMethod.POST;
URI uri = new URI("http://" + host + ":" + port);
HttpClient delegate = mock(HttpClient.class);
final HttpResponse response = mock(HttpResponse.class);
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,
serviceName, host, port, delegate, lb);
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
doReturn(method).when(request).getMethod();
doReturn(uri).when(request).getURI();
doReturn(request).when(request).withNewUri(any(URI.class));
HttpUriRequest uriRequest = mock(HttpUriRequest.class);
doReturn(uri).when(uriRequest).getURI();
doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class));
try {
client.execute(request, null);
fail("Expected IOException");
} catch(IOException e) {} finally {
verify(delegate, times(1)).execute(any(HttpUriRequest.class));
verify(lb, times(0)).chooseServer(eq(serviceName));
}
}
@Configuration
protected static class UseDefaults {
@@ -188,14 +385,21 @@ public class RibbonLoadBalancingHttpClientTests {
factory.setApplicationContext(new AnnotationConfigApplicationContext(
RibbonAutoConfiguration.class, defaultConfigurationClass));
String serviceName = "foo";
String host = serviceName;
int port = 80;
URI uri = new URI("http://" + host + ":" + port);
HttpClient delegate = mock(HttpClient.class);
RibbonLoadBalancingHttpClient client = factory.getClient("service",
RibbonLoadBalancingHttpClient.class);
ReflectionTestUtils.setField(client, "delegate", delegate);
ReflectionTestUtils.setField(client, "lb", loadBalancer);
given(delegate.execute(any(HttpUriRequest.class))).willReturn(
mock(HttpResponse.class));
RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class);
doReturn(uri).when(request).getURI();
doReturn(request).when(request).withNewUri(any(URI.class));
given(request.toRequest(any(RequestConfig.class))).willReturn(
mock(HttpUriRequest.class));
@@ -203,7 +407,7 @@ public class RibbonLoadBalancingHttpClientTests {
ArgumentCaptor<RequestConfig> requestConfigCaptor = ArgumentCaptor
.forClass(RequestConfig.class);
verify(request).toRequest(requestConfigCaptor.capture());
verify(request, times(1)).toRequest(requestConfigCaptor.capture());
return requestConfigCaptor.getValue();
}
@@ -52,7 +52,6 @@ public abstract class RibbonCommandFallbackTests {
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + uri, HttpMethod.GET,
new HttpEntity<>((Void) null), String.class);
System.out.println("no fallback body: " + result.getBody());
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
}
}
@@ -375,7 +375,6 @@ public abstract class ZuulProxyTestBase {
e.printStackTrace();
}
return "slow";
}
@Bean
@@ -506,8 +505,8 @@ public abstract class ZuulProxyTestBase {
@Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server("localhost", this.port));
}
return new StaticServerList<>(new Server("localhost", this.port));
}
}
@@ -123,5 +123,15 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>