Moves Retry filter to new style configuration.
fixes gh-224
This commit is contained in:
@@ -17,8 +17,8 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -26,43 +26,20 @@ import reactor.retry.Repeat;
|
||||
import reactor.retry.RepeatContext;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatus.Series;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
public class RetryGatewayFilterFactory implements GatewayFilterFactory {
|
||||
@Override
|
||||
public GatewayFilter apply(Tuple args) {
|
||||
Retry retry = new Retry();
|
||||
public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory<RetryGatewayFilterFactory.Retry> {
|
||||
|
||||
if (args.hasFieldName("retries")) {
|
||||
retry.retries(args.getInt("retries"));
|
||||
}
|
||||
|
||||
// TODO: list of statusSeries
|
||||
if (args.hasFieldName("statusSeries")) {
|
||||
int statusSeries = args.getInt("statusSeries");
|
||||
retry.series(Series.valueOf(statusSeries));
|
||||
}
|
||||
|
||||
// TODO: list of status
|
||||
if (args.hasFieldName("status")) {
|
||||
retry.statuses(ServerWebExchangeUtils.parse(args.getRawString("status")));
|
||||
}
|
||||
|
||||
// TODO: list of methods
|
||||
if (args.hasFieldName("method")) {
|
||||
retry.methods(HttpMethod.resolve(args.getString("method").toUpperCase()));
|
||||
}
|
||||
|
||||
return apply(retry);
|
||||
public RetryGatewayFilterFactory() {
|
||||
super(Retry.class);
|
||||
}
|
||||
|
||||
public GatewayFilter apply(Retry retry) {
|
||||
@Override
|
||||
public GatewayFilter apply(Retry retry) {
|
||||
retry.validate();
|
||||
|
||||
Predicate<? super RepeatContext<ServerWebExchange>> predicate = context -> {
|
||||
@@ -93,37 +70,43 @@ public class RetryGatewayFilterFactory implements GatewayFilterFactory {
|
||||
repeat.withApplicationContext(exchange)).next();
|
||||
}
|
||||
|
||||
private static <T> List<T> toList(T item) {
|
||||
ArrayList<T> list = new ArrayList<>();
|
||||
list.add(item);
|
||||
return list;
|
||||
}
|
||||
|
||||
public static class Retry {
|
||||
private int retries = 3;
|
||||
|
||||
private List<Series> series = Collections.singletonList(Series.SERVER_ERROR);
|
||||
private List<Series> series = toList(Series.SERVER_ERROR);
|
||||
|
||||
private List<HttpStatus> statuses = Collections.emptyList();
|
||||
private List<HttpStatus> statuses = new ArrayList<>();
|
||||
|
||||
private List<HttpMethod> methods = Collections.singletonList(HttpMethod.GET);
|
||||
private List<HttpMethod> methods = toList(HttpMethod.GET);
|
||||
|
||||
public Retry retries(int retries) {
|
||||
public Retry setRetries(int retries) {
|
||||
this.retries = retries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Retry series(Series... series) {
|
||||
public Retry setSeries(Series... series) {
|
||||
this.series = Arrays.asList(series);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Retry statuses(HttpStatus... statuses) {
|
||||
public Retry setStatuses(HttpStatus... statuses) {
|
||||
this.statuses = Arrays.asList(statuses);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Retry methods(HttpMethod... methods) {
|
||||
public Retry setMethods(HttpMethod... methods) {
|
||||
this.methods = Arrays.asList(methods);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Retry allMethods() {
|
||||
return methods(HttpMethod.values());
|
||||
return setMethods(HttpMethod.values());
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
|
||||
@@ -196,24 +196,11 @@ public class GatewayFilterSpec extends UriSpec {
|
||||
*/
|
||||
public GatewayFilterSpec retry(int retries) {
|
||||
return filter(getBean(RetryGatewayFilterFactory.class)
|
||||
.apply(new RetryGatewayFilterFactory.Retry()
|
||||
.retries(retries)));
|
||||
.apply(retry -> retry.setRetries(retries)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retries max number of retries
|
||||
* @param httpStatusSeries the http status series that is retryable
|
||||
* @param httpMethod the http method that is retryable
|
||||
*/
|
||||
public GatewayFilterSpec retry(int retries, HttpStatus.Series httpStatusSeries, HttpMethod httpMethod) {
|
||||
return retry(new RetryGatewayFilterFactory.Retry()
|
||||
.retries(retries)
|
||||
.series(httpStatusSeries)
|
||||
.methods(httpMethod));
|
||||
}
|
||||
|
||||
public GatewayFilterSpec retry(RetryGatewayFilterFactory.Retry retry) {
|
||||
return filter(getBean(RetryGatewayFilterFactory.class).apply(retry));
|
||||
public GatewayFilterSpec retry(Consumer<RetryGatewayFilterFactory.Retry> retryConsumer) {
|
||||
return filter(getBean(RetryGatewayFilterFactory.class).apply(retryConsumer));
|
||||
}
|
||||
|
||||
public GatewayFilterSpec retry(Repeat<ServerWebExchange> repeat) {
|
||||
|
||||
@@ -25,15 +25,18 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||||
import org.springframework.cloud.gateway.test.BaseWebClientTests;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -54,6 +57,16 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
|
||||
.expectBody(String.class).isEqualTo("3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retryFilterGetJavaDsl() {
|
||||
testClient.get()
|
||||
.uri("/retry?key=getjava&count=2")
|
||||
.header(HttpHeaders.HOST, "www.retryjava.org")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
//TODO: support post
|
||||
public void retryFilterPost() {
|
||||
@@ -71,18 +84,32 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
|
||||
public static class TestConfig {
|
||||
Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Value("${test.uri}")
|
||||
private String uri;
|
||||
|
||||
ConcurrentHashMap<String, AtomicInteger> map = new ConcurrentHashMap<>();
|
||||
|
||||
@RequestMapping("/httpbin/retry")
|
||||
public String retry(@RequestParam("key") String key) {
|
||||
AtomicInteger count = map.computeIfAbsent(key, s -> new AtomicInteger());
|
||||
int i = count.incrementAndGet();
|
||||
public String retry(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) {
|
||||
AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger());
|
||||
int i = num.incrementAndGet();
|
||||
log.warn("Retry count: "+i);
|
||||
if (i < 3) {
|
||||
if (i < count) {
|
||||
throw new RuntimeException("temporarily broken");
|
||||
}
|
||||
return String.valueOf(i);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder) {
|
||||
return builder.routes()
|
||||
.route("retry_java", r -> r.host("**.retryjava.org")
|
||||
.filters(f -> f.prefixPath("/httpbin")
|
||||
.retry(config -> config.setRetries(2)))
|
||||
.uri(uri))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user