Browse Source

Moves Retry filter to new style configuration.

fixes gh-224
pull/243/head
Spencer Gibb 7 years ago
parent
commit
2a567de251
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 57
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java
  2. 19
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java
  3. 39
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java

57
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactory.java

@ -17,8 +17,8 @@ @@ -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; @@ -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();
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()));
}
public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory<RetryGatewayFilterFactory.Retry> {
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 { @@ -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() {

19
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java

@ -196,24 +196,11 @@ public class GatewayFilterSpec extends UriSpec { @@ -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) {

39
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java

@ -25,15 +25,18 @@ import org.apache.commons.logging.LogFactory; @@ -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 @@ -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 @@ -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();
}
}
}

Loading…
Cancel
Save