Implementing retry policy

This commit is contained in:
Ryan Baxter
2016-09-23 15:01:09 -04:00
parent 9eed249028
commit 7191e820a2
2 changed files with 61 additions and 14 deletions

View File

@@ -16,22 +16,24 @@
package org.springframework.cloud.netflix.ribbon;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.cloud.client.DefaultServiceInstance;
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.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.util.UriComponentsBuilder;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
/**
* @author Spencer Gibb
@@ -60,6 +62,33 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
return context.reconstructURIWithServer(server, uri);
}
@Override
public LoadBalancedRetryPolicy getRetryPolicy(String serviceId) {
final RibbonLoadBalancerContext lbContext = this.clientFactory
.getLoadBalancerContext(serviceId);
return new LoadBalancedRetryPolicy() {
@Override
public boolean canRetry(LoadBalancedRetryContext context) {
HttpMethod method = context.getRequest().getMethod();
if(HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations()) {
return true;
} else {
return false;
}
}
@Override
public void close(LoadBalancedRetryContext context) {
}
@Override
public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) {
}
};
}
@Override
public ServiceInstance choose(String serviceId) {
Server server = getServer(serviceId);
@@ -80,12 +109,24 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,
serviceId), serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}
public <T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException {
Server server = null;
if(serviceInstance instanceof RibbonServer) {
server = ((RibbonServer)serviceInstance).getServer();
}
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonLoadBalancerContext context = this.clientFactory
.getLoadBalancerContext(serviceId);
RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server);
try {
T returnVal = request.apply(ribbonServer);
T returnVal = request.apply(serviceInstance);
statsRecorder.recordStats(returnVal);
return returnVal;
}

View File

@@ -16,15 +16,14 @@
package org.springframework.cloud.netflix.ribbon;
import java.net.URI;
import java.net.URL;
import com.netflix.loadbalancer.Server;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
@@ -33,10 +32,12 @@ import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.support.HttpRequestWrapper;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.util.UriComponentsBuilder;
import com.netflix.loadbalancer.Server;
import java.net.URI;
import java.net.URL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -66,7 +67,7 @@ public class RibbonInterceptorTests {
@Test
public void testIntercept() throws Exception {
RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080));
LoadBalancerInterceptor interceptor = new LoadBalancerInterceptor(new MyClient(server));
LoadBalancerInterceptor interceptor = new LoadBalancerInterceptor(new MyClient(server), new RetryTemplate());
given(this.request.getURI()).willReturn(new URL("http://myservice").toURI());
given(this.execution.execute(isA(HttpRequest.class), isA(byte[].class)))
.willReturn(this.response);
@@ -111,6 +112,11 @@ public class RibbonInterceptorTests {
.port(instance.getPort()).build().toUri();
}
@Override
public LoadBalancedRetryPolicy getRetryPolicy(String serviceId) {
return null;
}
}
}