Adds typed apply() for better use in java dsl.

This commit is contained in:
Spencer Gibb
2017-11-29 00:34:52 -05:00
parent 46cddd90d4
commit af9319d2ab
25 changed files with 178 additions and 61 deletions

View File

@@ -38,7 +38,10 @@ public class AddRequestHeaderGatewayFilterFactory implements GatewayFilterFactor
public GatewayFilter apply(Tuple args) {
String name = args.getString(NAME_KEY);
String value = args.getString(VALUE_KEY);
return apply(name, value);
}
public GatewayFilter apply(String name, String value) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest().mutate()
.header(name, value)

View File

@@ -41,7 +41,10 @@ public class AddRequestParameterGatewayFilterFactory implements GatewayFilterFac
public GatewayFilter apply(Tuple args) {
String parameter = args.getString(NAME_KEY);
String value = args.getString(VALUE_KEY);
return apply(parameter, value);
}
public GatewayFilter apply(String parameter, String value) {
return (exchange, chain) -> {
URI uri = exchange.getRequest().getURI();

View File

@@ -37,7 +37,10 @@ public class AddResponseHeaderGatewayFilterFactory implements GatewayFilterFacto
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
final String value = args.getString(VALUE_KEY);
return apply(header, value);
}
public GatewayFilter apply(String header, String value) {
return (exchange, chain) -> {
exchange.getResponse().getHeaders().add(header, value);

View File

@@ -17,18 +17,16 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.tuple.Tuple;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import static org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory.STATUS_KEY;
import static org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactory.URL_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REGEXP_KEY;
import static org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory.REPLACEMENT_KEY;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory.NAME_KEY;
import static org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory.VALUE_KEY;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import com.netflix.hystrix.HystrixObservableCommand;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
@@ -39,28 +37,27 @@ public class GatewayFilters {
public static final Tuple EMPTY_TUPLE = tuple().build();
public static GatewayFilter addRequestHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddRequestHeaderGatewayFilterFactory().apply(args);
return new AddRequestHeaderGatewayFilterFactory().apply(headerName, headerValue);
}
public static GatewayFilter addRequestParameter(String param, String value) {
Tuple args = tuple().of(NAME_KEY, param, VALUE_KEY, value);
return new AddRequestParameterGatewayFilterFactory().apply(args);
return new AddRequestParameterGatewayFilterFactory().apply(param, value);
}
public static GatewayFilter addResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new AddResponseHeaderGatewayFilterFactory().apply(args);
return new AddResponseHeaderGatewayFilterFactory().apply(headerName, headerValue);
}
public static GatewayFilter hystrix(String commandName) {
Tuple args = tuple().of(NAME_KEY, commandName);
return new HystrixGatewayFilterFactory().apply(args);
return new HystrixGatewayFilterFactory().apply(commandName);
}
public static GatewayFilter hystrix(HystrixObservableCommand.Setter setter) {
return new HystrixGatewayFilterFactory().apply(setter);
}
public static GatewayFilter prefixPath(String prefix) {
Tuple args = tuple().of(PrefixPathGatewayFilterFactory.PREFIX_KEY, prefix);
return new PrefixPathGatewayFilterFactory().apply(args);
return new PrefixPathGatewayFilterFactory().apply(prefix);
}
public static GatewayFilter redirect(int status, URI url) {
@@ -76,8 +73,11 @@ public class GatewayFilters {
}
public static GatewayFilter redirect(String status, String url) {
Tuple args = tuple().of(STATUS_KEY, status, URL_KEY, url);
return new RedirectToGatewayFilterFactory().apply(args);
return new RedirectToGatewayFilterFactory().apply(status, url);
}
public static GatewayFilter redirect(HttpStatus status, URL url) {
return new RedirectToGatewayFilterFactory().apply(status, url);
}
public static GatewayFilter removeNonProxyHeaders(String... headersToRemove) {
@@ -87,18 +87,15 @@ public class GatewayFilters {
}
public static GatewayFilter removeRequestHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveRequestHeaderGatewayFilterFactory().apply(args);
return new RemoveRequestHeaderGatewayFilterFactory().apply(headerName);
}
public static GatewayFilter removeResponseHeader(String headerName) {
Tuple args = tuple().of(NAME_KEY, headerName);
return new RemoveResponseHeaderGatewayFilterFactory().apply(args);
return new RemoveResponseHeaderGatewayFilterFactory().apply(headerName);
}
public static GatewayFilter rewritePath(String regex, String replacement) {
Tuple args = tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement);
return new RewritePathGatewayFilterFactory().apply(args);
return new RewritePathGatewayFilterFactory().apply(regex, replacement);
}
public static GatewayFilter secureHeaders(SecureHeadersProperties properties) {
@@ -106,13 +103,11 @@ public class GatewayFilters {
}
public static GatewayFilter setPath(String template) {
Tuple args = tuple().of(SetPathGatewayFilterFactory.TEMPLATE_KEY, template);
return new SetPathGatewayFilterFactory().apply(args);
return new SetPathGatewayFilterFactory().apply(template);
}
public static GatewayFilter setResponseHeader(String headerName, String headerValue) {
Tuple args = tuple().of(NAME_KEY, headerName, VALUE_KEY, headerValue);
return new SetResponseHeaderGatewayFilterFactory().apply(args);
return new SetResponseHeaderGatewayFilterFactory().apply(headerName, headerValue);
}
public static GatewayFilter setStatus(int status) {
@@ -120,7 +115,10 @@ public class GatewayFilters {
}
public static GatewayFilter setStatus(String status) {
Tuple args = tuple().of(SetStatusGatewayFilterFactory.STATUS_KEY, status);
return new SetStatusGatewayFilterFactory().apply(args);
return new SetStatusGatewayFilterFactory().apply(status);
}
public static GatewayFilter setStatus(HttpStatus status) {
return new SetStatusGatewayFilterFactory().apply(status);
}
}

View File

@@ -21,15 +21,16 @@ import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.hystrix.HystrixObservableCommand.Setter;
import com.netflix.hystrix.exception.HystrixRuntimeException;
import static com.netflix.hystrix.exception.HystrixRuntimeException.FailureType.TIMEOUT;
@@ -54,13 +55,19 @@ public class HystrixGatewayFilterFactory implements GatewayFilterFactory {
public GatewayFilter apply(Tuple args) {
//TODO: if no name is supplied, generate one from command id (useful for default filter)
final String commandName = args.getString(NAME_KEY);
return apply(commandName);
}
public GatewayFilter apply(String commandName) {
final HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName());
final HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(commandName);
final HystrixObservableCommand.Setter setter = HystrixObservableCommand.Setter
.withGroupKey(groupKey)
final Setter setter = Setter.withGroupKey(groupKey)
.andCommandKey(commandKey);
return apply(setter);
}
public GatewayFilter apply(Setter setter) {
return (exchange, chain) -> {
RouteHystrixCommand command = new RouteHystrixCommand(setter, exchange, chain);

View File

@@ -44,10 +44,12 @@ public class PrefixPathGatewayFilterFactory implements GatewayFilterFactory {
}
@Override
@SuppressWarnings("unchecked")
public GatewayFilter apply(Tuple args) {
final String prefix = args.getString(PREFIX_KEY);
return apply(prefix);
}
public GatewayFilter apply(String prefix) {
return (exchange, chain) -> {
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());

View File

@@ -52,7 +52,10 @@ public class RedirectToGatewayFilterFactory implements GatewayFilterFactory {
public GatewayFilter apply(Tuple args) {
String statusString = args.getRawString(STATUS_KEY);
String urlString = args.getString(URL_KEY);
return apply(statusString, urlString);
}
public GatewayFilter apply(String statusString, String urlString) {
final HttpStatus httpStatus = parse(statusString);
Assert.isTrue(httpStatus.is3xxRedirection(), "status must be a 3xx code, but was " + statusString);
final URL url;
@@ -61,6 +64,10 @@ public class RedirectToGatewayFilterFactory implements GatewayFilterFactory {
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid url " + urlString, e);
}
return apply(httpStatus, url);
}
public GatewayFilter apply(HttpStatus httpStatus, URL url) {
return (exchange, chain) ->
chain.filter(exchange).then(Mono.defer(() -> {

View File

@@ -37,7 +37,10 @@ public class RemoveRequestHeaderGatewayFilterFactory implements GatewayFilterFac
@Override
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
return apply(header);
}
public GatewayFilter apply(String header) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> httpHeaders.remove(header))

View File

@@ -38,7 +38,10 @@ public class RemoveResponseHeaderGatewayFilterFactory implements GatewayFilterFa
@Override
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
return apply(header);
}
public GatewayFilter apply(String header) {
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {
exchange.getResponse().getHeaders().remove(header);
}));

View File

@@ -46,10 +46,13 @@ public class RequestRateLimiterGatewayFilterFactory implements GatewayFilterFact
KeyResolver keyResolver;
if (args.hasFieldName(KEY_RESOLVER_KEY)) {
keyResolver = args.getValue(KEY_RESOLVER_KEY, KeyResolver.class);
}
else {
} else {
keyResolver = defaultKeyResolver;
}
return apply(keyResolver, args);
}
public GatewayFilter apply(KeyResolver keyResolver, Tuple args) {
return (exchange, chain) -> keyResolver.resolve(exchange).flatMap(key ->
// TODO: if key is empty?

View File

@@ -44,7 +44,10 @@ public class RewritePathGatewayFilterFactory implements GatewayFilterFactory {
public GatewayFilter apply(Tuple args) {
final String regex = args.getString(REGEXP_KEY);
String replacement = args.getString(REPLACEMENT_KEY).replace("$\\", "$");
return apply(regex, replacement);
}
public GatewayFilter apply(String regex, String replacement) {
return (exchange, chain) -> {
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());

View File

@@ -50,6 +50,10 @@ public class SetPathGatewayFilterFactory implements GatewayFilterFactory {
@SuppressWarnings("unchecked")
public GatewayFilter apply(Tuple args) {
String template = args.getString(TEMPLATE_KEY);
return apply(template);
}
public GatewayFilter apply(String template) {
UriTemplate uriTemplate = new UriTemplate(template);
return (exchange, chain) -> {

View File

@@ -38,7 +38,10 @@ public class SetResponseHeaderGatewayFilterFactory implements GatewayFilterFacto
public GatewayFilter apply(Tuple args) {
final String header = args.getString(NAME_KEY);
final String value = args.getString(VALUE_KEY);
return apply(header, value);
}
public GatewayFilter apply(String header, String value) {
return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {
exchange.getResponse().getHeaders().set(header, value);
}));

View File

@@ -44,8 +44,15 @@ public class SetStatusGatewayFilterFactory implements GatewayFilterFactory {
@Override
public GatewayFilter apply(Tuple args) {
String status = args.getRawString(STATUS_KEY);
final HttpStatus httpStatus = ServerWebExchangeUtils.parse(status);
return apply(status);
}
public GatewayFilter apply(String status) {
final HttpStatus httpStatus = ServerWebExchangeUtils.parse(status);
return apply(httpStatus);
}
public GatewayFilter apply(HttpStatus httpStatus) {
return (exchange, chain) -> {
// option 1 (runs in filter order)

View File

@@ -41,7 +41,10 @@ public class AfterRoutePredicateFactory implements RoutePredicateFactory {
public Predicate<ServerWebExchange> apply(Tuple args) {
Object value = args.getValue(DATETIME_KEY);
final ZonedDateTime dateTime = BetweenRoutePredicateFactory.getZonedDateTime(value);
return apply(dateTime);
}
public Predicate<ServerWebExchange> apply(ZonedDateTime dateTime) {
return exchange -> {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(dateTime);

View File

@@ -43,7 +43,10 @@ public class BeforeRoutePredicateFactory implements RoutePredicateFactory {
public Predicate<ServerWebExchange> apply(Tuple args) {
Object value = args.getValue(DATETIME_KEY);
final ZonedDateTime dateTime = BetweenRoutePredicateFactory.getZonedDateTime(value);
return apply(dateTime);
}
public Predicate<ServerWebExchange> apply(ZonedDateTime dateTime) {
return exchange -> {
final ZonedDateTime now = ZonedDateTime.now();
return now.isBefore(dateTime);

View File

@@ -39,8 +39,12 @@ public class BetweenRoutePredicateFactory implements RoutePredicateFactory {
//TODO: is ZonedDateTime the right thing to use?
final ZonedDateTime dateTime1 = getZonedDateTime(args.getValue(DATETIME1_KEY));
final ZonedDateTime dateTime2 = getZonedDateTime(args.getValue(DATETIME2_KEY));
Assert.isTrue(dateTime1.isBefore(dateTime2), args.getValue(DATETIME1_KEY) +
" must be before " + args.getValue(DATETIME2_KEY));
return apply(dateTime1, dateTime2);
}
public Predicate<ServerWebExchange> apply(ZonedDateTime dateTime1, ZonedDateTime dateTime2) {
Assert.isTrue(dateTime1.isBefore(dateTime2), dateTime1 +
" must be before " + dateTime2);
return exchange -> {
final ZonedDateTime now = ZonedDateTime.now();

View File

@@ -42,7 +42,10 @@ public class CookieRoutePredicateFactory implements RoutePredicateFactory {
public Predicate<ServerWebExchange> apply(Tuple args) {
String name = args.getString(NAME_KEY);
String regexp = args.getString(REGEXP_KEY);
return apply(name, regexp);
}
public Predicate<ServerWebExchange> apply(String name, String regexp) {
return exchange -> {
List<HttpCookie> cookies = exchange.getRequest().getCookies().get(name);
for (HttpCookie cookie : cookies) {

View File

@@ -41,7 +41,10 @@ public class HeaderRoutePredicateFactory implements RoutePredicateFactory {
public Predicate<ServerWebExchange> apply(Tuple args) {
String header = args.getString(HEADER_KEY);
String regexp = args.getString(REGEXP_KEY);
return apply(header, regexp);
}
public Predicate<ServerWebExchange> apply(String header, String regexp) {
return exchange -> {
List<String> values = exchange.getRequest().getHeaders().get(header);
for (String value : values) {

View File

@@ -45,7 +45,10 @@ public class HostRoutePredicateFactory implements RoutePredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(Tuple args) {
String pattern = args.getString(PATTERN_KEY);
return apply(pattern);
}
public Predicate<ServerWebExchange> apply(String pattern) {
return exchange -> {
String host = exchange.getRequest().getHeaders().getFirst("Host");
return this.pathMatcher.match(pattern, host);

View File

@@ -40,9 +40,18 @@ public class MethodRoutePredicateFactory implements RoutePredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(Tuple args) {
String method = args.getString(METHOD_KEY);
return apply(method);
}
public Predicate<ServerWebExchange> apply(String method) {
HttpMethod httpMethod = HttpMethod.resolve(method);
return apply(httpMethod);
}
public Predicate<ServerWebExchange> apply(HttpMethod httpMethod) {
return exchange -> {
HttpMethod requestMethod = exchange.getRequest().getMethod();
return requestMethod.matches(method);
return requestMethod == httpMethod;
};
}
}

View File

@@ -51,6 +51,10 @@ public class PathRoutePredicateFactory implements RoutePredicateFactory {
@Override
public Predicate<ServerWebExchange> apply(Tuple args) {
String unparsedPattern = args.getString(PATTERN_KEY);
return apply(unparsedPattern);
}
public Predicate<ServerWebExchange> apply(String unparsedPattern) {
PathPattern pattern;
synchronized (this.pathPatternParser) {
pattern = this.pathPatternParser.parse(unparsedPattern);

View File

@@ -22,6 +22,7 @@ import java.util.List;
import java.util.function.Predicate;
import org.springframework.tuple.Tuple;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
/**
@@ -47,13 +48,23 @@ public class QueryRoutePredicateFactory implements RoutePredicateFactory {
validateMin(1, args);
String param = args.getString(PARAM_KEY);
final String regexp;
if (args.hasFieldName(REGEXP_KEY)) {
regexp = args.getString(REGEXP_KEY);
} else {
regexp = null;
}
return apply(param, regexp);
}
public Predicate<ServerWebExchange> apply(String param, String regexp) {
return exchange -> {
if (!args.hasFieldName(REGEXP_KEY)) {
if (!StringUtils.hasText(regexp)) {
// check existence of header
return exchange.getRequest().getQueryParams().containsKey(param);
}
String regexp = args.getString(REGEXP_KEY);
List<String> values = exchange.getRequest().getQueryParams().get(param);
for (String value : values) {

View File

@@ -26,6 +26,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.support.SubnetUtils;
import org.springframework.tuple.Tuple;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
/**
@@ -45,7 +46,20 @@ public class RemoteAddrRoutePredicateFactory implements RoutePredicateFactory {
addSource(sources, (String) arg);
}
}
return apply(sources);
}
public Predicate<ServerWebExchange> apply(String... addrs) {
Assert.notEmpty(addrs, "addrs must not be empty");
List<SubnetUtils> sources = new ArrayList<>();
for (String addr : addrs) {
addSource(sources, addr);
}
return apply(sources);
}
public Predicate<ServerWebExchange> apply(List<SubnetUtils> sources) {
return exchange -> {
InetSocketAddress remoteAddress = exchange.getRequest().getRemoteAddress();
if (remoteAddress != null) {

View File

@@ -24,6 +24,8 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.springframework.http.HttpMethod;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory.DATETIME1_KEY;
@@ -38,48 +40,57 @@ import static org.springframework.tuple.TupleBuilder.tuple;
public class RoutePredicates {
public static Predicate<ServerWebExchange> after(ZonedDateTime datetime) {
return new AfterRoutePredicateFactory().apply(tuple().of(AfterRoutePredicateFactory.DATETIME_KEY, datetime));
return new AfterRoutePredicateFactory().apply(datetime);
}
public static Predicate<ServerWebExchange> before(ZonedDateTime datetime) {
return new BeforeRoutePredicateFactory().apply(tuple().of(BeforeRoutePredicateFactory.DATETIME_KEY, datetime));
return new BeforeRoutePredicateFactory().apply(datetime);
}
public static Predicate<ServerWebExchange> between(ZonedDateTime datetime1, ZonedDateTime datetime2) {
return new BetweenRoutePredicateFactory().apply(tuple()
.of(DATETIME1_KEY, datetime1, DATETIME2_KEY, datetime2));
return new BetweenRoutePredicateFactory().apply(datetime1, datetime2);
}
public static Predicate<ServerWebExchange> cookie(String name, String regex) {
return new CookieRoutePredicateFactory().apply(tuple()
.of(CookieRoutePredicateFactory.NAME_KEY, name, CookieRoutePredicateFactory.REGEXP_KEY, regex));
return new CookieRoutePredicateFactory().apply(name, regex);
}
public static Predicate<ServerWebExchange> header(String header, String regex) {
return new HeaderRoutePredicateFactory().apply(tuple()
.of(HeaderRoutePredicateFactory.HEADER_KEY, header, HeaderRoutePredicateFactory.REGEXP_KEY, regex));
return new HeaderRoutePredicateFactory().apply(header, regex);
}
public static Predicate<ServerWebExchange> host(String pattern) {
return new HostRoutePredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
return new HostRoutePredicateFactory().apply(pattern);
}
public static Predicate<ServerWebExchange> host(String pattern, PathMatcher pathMatcher) {
HostRoutePredicateFactory predicateFactory = new HostRoutePredicateFactory();
predicateFactory.setPathMatcher(pathMatcher);
return predicateFactory.apply(pattern);
}
public static Predicate<ServerWebExchange> method(String method) {
return new MethodRoutePredicateFactory().apply(tuple().of(METHOD_KEY, method));
return new MethodRoutePredicateFactory().apply(method);
}
public static Predicate<ServerWebExchange> method(HttpMethod method) {
return new MethodRoutePredicateFactory().apply(method);
}
public static Predicate<ServerWebExchange> path(String pattern) {
return new PathRoutePredicateFactory().apply(tuple().of(PATTERN_KEY, pattern));
return new PathRoutePredicateFactory().apply(pattern);
}
public static Predicate<ServerWebExchange> query(String param, String regex) {
return new QueryRoutePredicateFactory().apply(tuple().
of(QueryRoutePredicateFactory.PARAM_KEY, param, QueryRoutePredicateFactory.REGEXP_KEY, regex));
return new QueryRoutePredicateFactory().apply(param, regex);
}
public static Predicate<ServerWebExchange> query(String param) {
return new QueryRoutePredicateFactory().apply(param, null);
}
public static Predicate<ServerWebExchange> remoteAddr(String... addrs) {
List<String> names = IntStream.range(0, addrs.length).mapToObj(i -> "addr" + i).collect(Collectors.toList());
return new RemoteAddrRoutePredicateFactory().apply(tuple().ofNamesAndValues(names, Arrays.asList(addrs)));
return new RemoteAddrRoutePredicateFactory().apply(addrs);
}
public static Predicate<ServerWebExchange> alwaysTrue() {