Moves to named Tuple args
Moves WebFilterFactory used to named Tuple arguments rather than a String array.
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
package org.springframework.cloud.gateway.discovery;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.gateway.api.RouteLocator;
|
||||
@@ -28,6 +27,8 @@ import org.springframework.cloud.gateway.model.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.model.PredicateDefinition;
|
||||
import org.springframework.cloud.gateway.model.Route;
|
||||
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REGEXP_KEY;
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REPLACEMENT_KEY;
|
||||
import static org.springframework.cloud.gateway.handler.predicate.PathRequestPredicateFactory.PATTERN_KEY;
|
||||
import static org.springframework.cloud.gateway.support.NameUtils.normalizeFilterName;
|
||||
import static org.springframework.cloud.gateway.support.NameUtils.normalizePredicateName;
|
||||
@@ -59,7 +60,7 @@ public class DiscoveryClientRouteLocator implements RouteLocator {
|
||||
// add a predicate that matches the url at /serviceId/**
|
||||
PredicateDefinition predicate = new PredicateDefinition();
|
||||
predicate.setName(normalizePredicateName(PathRequestPredicateFactory.class));
|
||||
predicate.setArgs(Collections.singletonMap(PATTERN_KEY, "/" + serviceId + "/**"));
|
||||
predicate.addArg(PATTERN_KEY, "/" + serviceId + "/**");
|
||||
route.getPredicates().add(predicate);
|
||||
|
||||
//TODO: support for other default predicates
|
||||
@@ -69,7 +70,8 @@ public class DiscoveryClientRouteLocator implements RouteLocator {
|
||||
filter.setName(normalizeFilterName(RewritePathWebFilterFactory.class));
|
||||
String regex = "/" + serviceId + "/(?<remaining>.*)";
|
||||
String replacement = "/${remaining}";
|
||||
filter.setArgs(regex, replacement);
|
||||
filter.addArg(REGEXP_KEY, regex);
|
||||
filter.addArg(REPLACEMENT_KEY, replacement);
|
||||
route.getFilters().add(filter);
|
||||
|
||||
//TODO: support for default filters
|
||||
|
||||
@@ -17,21 +17,31 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AddRequestHeaderWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY, VALUE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
String name = args.getString(NAME_KEY);
|
||||
String value = args.getString(VALUE_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest().mutate()
|
||||
.header(args[0], args[1])
|
||||
.header(name, value)
|
||||
.build();
|
||||
|
||||
return chain.filter(exchange.mutate().request(request).build());
|
||||
|
||||
@@ -19,11 +19,14 @@ package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
@@ -34,10 +37,14 @@ import org.springframework.web.server.WebFilter;
|
||||
public class AddRequestParameterWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
String parameter = args[0];
|
||||
String value = args[1];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY, VALUE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
String parameter = args.getString(NAME_KEY);
|
||||
String value = args.getString(VALUE_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
|
||||
|
||||
@@ -17,18 +17,26 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AddResponseHeaderWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
final String header = args[0];
|
||||
final String value = args[1];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY, VALUE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String header = args.getString(NAME_KEY);
|
||||
final String value = args.getString(VALUE_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
exchange.getResponse().getHeaders().add(header, value);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
@@ -30,15 +31,22 @@ import rx.Observable;
|
||||
import rx.RxReactiveStreams;
|
||||
import rx.Subscription;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HystrixWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
final String commandName = args[0];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String commandName = args.getString(NAME_KEY);
|
||||
final HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName());
|
||||
final HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(commandName);
|
||||
|
||||
|
||||
@@ -18,18 +18,28 @@
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class PrefixPathWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
public static final String PREFIX_KEY = "prefix";
|
||||
|
||||
@Override
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(PREFIX_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
final String prefix = args[0];
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String prefix = args.getString(PREFIX_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest req = exchange.getRequest();
|
||||
|
||||
@@ -20,10 +20,13 @@ package org.springframework.cloud.gateway.filter.factory;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.parse;
|
||||
@@ -35,18 +38,26 @@ import reactor.core.publisher.Mono;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RedirectToWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
public static final String STATUS_KEY = "status";
|
||||
public static final String URL_KEY = "url";
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
final String statusString = args[0];
|
||||
final String uri = args[1];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(STATUS_KEY, URL_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
String statusString = args.getRawString(STATUS_KEY);
|
||||
String urlString = args.getString(URL_KEY);
|
||||
|
||||
final HttpStatus httpStatus = parse(statusString);
|
||||
final URL url;
|
||||
try {
|
||||
url = URI.create(uri).toURL();
|
||||
url = URI.create(urlString).toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException("Invalid url " + uri, e);
|
||||
throw new IllegalArgumentException("Invalid url " + urlString, e);
|
||||
}
|
||||
|
||||
return (exchange, chain) ->
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -61,7 +62,7 @@ public class RemoveNonProxyHeadersWebFilterFactory implements WebFilterFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
public WebFilter apply(Tuple args) {
|
||||
//TODO: support filter args
|
||||
|
||||
return (exchange, chain) -> {
|
||||
|
||||
@@ -17,9 +17,13 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -28,9 +32,13 @@ public class RemoveRequestHeaderWebFilterFactory implements WebFilterFactory {
|
||||
private static final String FAKE_HEADER = "_______force_______";
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
final String header = args[0];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String header = args.getString(NAME_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest().mutate()
|
||||
|
||||
@@ -17,17 +17,25 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RemoveResponseHeaderWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
final String header = args[0];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String header = args.getString(NAME_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
exchange.getResponse().getHeaders().remove(header);
|
||||
|
||||
@@ -17,19 +17,30 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RewritePathWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
public static final String REGEXP_KEY = "regexp";
|
||||
public static final String REPLACEMENT_KEY = "replacement";
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
final String regex = args[0];
|
||||
String replacement = args[1].replace("$\\", "$");
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(REGEXP_KEY, REPLACEMENT_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String regex = args.getString(REGEXP_KEY);
|
||||
String replacement = args.getString(REPLACEMENT_KEY).replace("$\\", "$");
|
||||
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest req = exchange.getRequest();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,7 @@ public class SecureHeadersWebFilterFactory implements WebFilterFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
public WebFilter apply(Tuple args) {
|
||||
//TODO: allow args to override properties
|
||||
|
||||
return (exchange, chain) -> {
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
@@ -32,11 +35,18 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.U
|
||||
*/
|
||||
public class SetPathWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
public static final String TEMPLATE_KEY = "template";
|
||||
|
||||
@Override
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(TEMPLATE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
UriTemplate uriTemplate = new UriTemplate(args[0]);
|
||||
public WebFilter apply(Tuple args) {
|
||||
String template = args.getString(TEMPLATE_KEY);
|
||||
UriTemplate uriTemplate = new UriTemplate(template);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
Map<String, String> variables = getAttribute(exchange, URI_TEMPLATE_VARIABLES_ATTRIBUTE, Map.class);
|
||||
|
||||
@@ -17,18 +17,26 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SetResponseHeaderWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(2, args);
|
||||
final String header = args[0];
|
||||
final String value = args[1];
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(NAME_KEY, VALUE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
final String header = args.getString(NAME_KEY);
|
||||
final String value = args.getString(VALUE_KEY);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
exchange.getResponse().getHeaders().set(header, value);
|
||||
|
||||
@@ -19,21 +19,32 @@ package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setResponseStatus;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SetStatusWebFilterFactory implements WebFilterFactory {
|
||||
|
||||
public static final String STATUS_KEY = "status";
|
||||
|
||||
@Override
|
||||
public WebFilter apply(String... args) {
|
||||
validate(1, args);
|
||||
final HttpStatus httpStatus = ServerWebExchangeUtils.parse(args[0]);
|
||||
public List<String> argNames() {
|
||||
return Arrays.asList(STATUS_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebFilter apply(Tuple args) {
|
||||
String status = args.getRawString(STATUS_KEY);
|
||||
final HttpStatus httpStatus = ServerWebExchangeUtils.parse(status);
|
||||
|
||||
return (exchange, chain) -> {
|
||||
|
||||
|
||||
@@ -18,24 +18,48 @@
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface WebFilterFactory {
|
||||
|
||||
String NAME_KEY = "name";
|
||||
String VALUE_KEY = "value";
|
||||
|
||||
//TODO: move from String... to Tuple
|
||||
WebFilter apply(String... args);
|
||||
WebFilter apply(Tuple args);
|
||||
|
||||
default String name() {
|
||||
return NameUtils.normalizeFilterName(getClass());
|
||||
}
|
||||
|
||||
default void validate(int requiredSize, String... args) {
|
||||
Assert.isTrue(args != null && args.length == requiredSize,
|
||||
/**
|
||||
* Returns hints about the number of args and the order for shortcut parsing.
|
||||
* @return
|
||||
*/
|
||||
default List<String> argNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate supplied argument size against {@see #argNames} size.
|
||||
* Useful for variable arg predicates.
|
||||
* @return
|
||||
*/
|
||||
default boolean validateArgs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default void validate(int requiredSize, Tuple args) {
|
||||
Assert.isTrue(args != null && args.size() == requiredSize,
|
||||
"args must have "+ requiredSize +" entry(s)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package org.springframework.cloud.gateway.handler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -36,10 +35,13 @@ import org.springframework.cloud.gateway.model.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.model.Route;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.cloud.gateway.support.RefreshRoutesEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.tuple.TupleBuilder;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
@@ -153,16 +155,49 @@ public class FilteringWebHandler extends WebHandlerDecorator {
|
||||
if (filter == null) {
|
||||
throw new IllegalArgumentException("Unable to find WebFilterFactory with name " + definition.getName());
|
||||
}
|
||||
Map<String, String> args = definition.getArgs();
|
||||
if (logger.isDebugEnabled()) {
|
||||
List<String> args;
|
||||
if (definition.getArgs() != null) {
|
||||
args = Arrays.asList(definition.getArgs());
|
||||
} else {
|
||||
args = Collections.emptyList();
|
||||
}
|
||||
logger.debug("Route " + id + " applying filter " + args + " to " + definition.getName());
|
||||
}
|
||||
return filter.apply(definition.getArgs());
|
||||
|
||||
//TODO: move Tuple building to common class, see RequestPredicateFactory.lookup
|
||||
TupleBuilder builder = TupleBuilder.tuple();
|
||||
|
||||
List<String> argNames = filter.argNames();
|
||||
if (!argNames.isEmpty()) {
|
||||
// ensure size is the same for key replacement later
|
||||
if (filter.validateArgs() && args.size() != argNames.size()) {
|
||||
throw new IllegalArgumentException("Wrong number of arguments. Expected " + argNames
|
||||
+ " " + argNames + ". Found " + args.size() + " " + args + "'");
|
||||
}
|
||||
}
|
||||
|
||||
int entryIdx = 0;
|
||||
for (Map.Entry<String, String> entry : args.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
|
||||
// RequestPredicateFactory has name hints and this has a fake key name
|
||||
// replace with the matching key hint
|
||||
if (key.startsWith(NameUtils.GENERATED_NAME_PREFIX) && !argNames.isEmpty()
|
||||
&& entryIdx < args.size()) {
|
||||
key = argNames.get(entryIdx);
|
||||
}
|
||||
|
||||
builder.put(key, entry.getValue());
|
||||
entryIdx++;
|
||||
}
|
||||
|
||||
Tuple tuple = builder.build();
|
||||
|
||||
if (filter.validateArgs()) {
|
||||
for (String name : argNames) {
|
||||
if (!tuple.hasFieldName(name)) {
|
||||
throw new IllegalArgumentException("Missing argument '" + name + "'. Given " + tuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filter.apply(tuple);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -170,10 +170,12 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping {
|
||||
|
||||
List<String> argNames = found.argNames();
|
||||
if (!argNames.isEmpty()) {
|
||||
// ensure size is the same for key replacement later
|
||||
if (found.validateArgSize() && args.size() != argNames.size()) {
|
||||
throw new IllegalArgumentException("Wrong number of arguments. Expected " + argNames
|
||||
+ " " + argNames + ". Found "+ args.size() +" " + args +"'");
|
||||
if (!argNames.isEmpty()) {
|
||||
// ensure size is the same for key replacement later
|
||||
if (found.validateArgs() && args.size() != argNames.size()) {
|
||||
throw new IllegalArgumentException("Wrong number of arguments. Expected " + argNames
|
||||
+ " " + argNames + ". Found " + args.size() + " " + args + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +195,15 @@ public class RequestPredicateHandlerMapping extends AbstractHandlerMapping {
|
||||
}
|
||||
|
||||
Tuple tuple = builder.build();
|
||||
|
||||
if (found.validateArgs()) {
|
||||
for (String name : argNames) {
|
||||
if (!tuple.hasFieldName(name)) {
|
||||
throw new IllegalArgumentException("Missing argument '" + name + "'. Given " + tuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found.apply(tuple);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class QueryRequestPredicateFactory implements RequestPredicateFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateArgSize() {
|
||||
public boolean validateArgs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +46,11 @@ public interface RequestPredicateFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate supplied argument size against {@see #argNames} size.
|
||||
* Auto validate supplied argument size against {@see #argNames} size and that an arg for each key exists.
|
||||
* Useful for variable arg predicates.
|
||||
* @return
|
||||
*/
|
||||
default boolean validateArgSize() {
|
||||
default boolean validateArgs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
|
||||
package org.springframework.cloud.gateway.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
|
||||
import static org.springframework.util.StringUtils.tokenizeToStringArray;
|
||||
|
||||
/**
|
||||
@@ -30,7 +33,7 @@ import static org.springframework.util.StringUtils.tokenizeToStringArray;
|
||||
public class FilterDefinition {
|
||||
@NotNull
|
||||
private String name;
|
||||
private String[] args;
|
||||
private Map<String, String> args = new LinkedHashMap<>();
|
||||
|
||||
public FilterDefinition() {
|
||||
}
|
||||
@@ -45,7 +48,9 @@ public class FilterDefinition {
|
||||
|
||||
String[] args = tokenizeToStringArray(text.substring(eqIdx+1), ",");
|
||||
|
||||
setArgs(args);
|
||||
for (int i=0; i < args.length; i++) {
|
||||
this.args.put(NameUtils.generateName(i), args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -56,21 +61,25 @@ public class FilterDefinition {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String[] getArgs() {
|
||||
public Map<String, String> getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public void setArgs(String... args) {
|
||||
public void setArgs(Map<String, String> args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public void addArg(String key, String value) {
|
||||
this.args.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FilterDefinition that = (FilterDefinition) o;
|
||||
return Objects.equals(name, that.name) &&
|
||||
Arrays.equals(args, that.args);
|
||||
Objects.equals(args, that.args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +91,7 @@ public class FilterDefinition {
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("FilterDefinition{");
|
||||
sb.append("name='").append(name).append('\'');
|
||||
sb.append(", args=").append(Arrays.toString(args));
|
||||
sb.append(", args=").append(args);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ public class PredicateDefinition {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public void addArg(String key, String value) {
|
||||
this.args.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -20,16 +20,20 @@ package org.springframework.cloud.gateway.filter.factory;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REGEXP_KEY;
|
||||
import static org.springframework.cloud.gateway.filter.factory.RewritePathWebFilterFactory.REPLACEMENT_KEY;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -47,7 +51,7 @@ public class RewritePathWebFilterFactoryTests {
|
||||
}
|
||||
|
||||
private void testRewriteFilter(String regex, String replacement, String actualPath, String expectedPath) {
|
||||
WebFilter filter = new RewritePathWebFilterFactory().apply(regex, replacement);
|
||||
WebFilter filter = new RewritePathWebFilterFactory().apply(tuple().of(REGEXP_KEY, regex, REPLACEMENT_KEY, replacement));
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest
|
||||
.get("http://localhost"+ actualPath)
|
||||
|
||||
@@ -32,6 +32,8 @@ import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.gateway.filter.factory.SetPathWebFilterFactory.TEMPLATE_KEY;
|
||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -54,7 +56,7 @@ public class SetPathWebFilterFactoryTests {
|
||||
}
|
||||
|
||||
private void testRewriteFilter(String template, String actualPath, String expectedPath, HashMap<String, String> variables) {
|
||||
WebFilter filter = new SetPathWebFilterFactory().apply(new String[]{template});
|
||||
WebFilter filter = new SetPathWebFilterFactory().apply(tuple().of(TEMPLATE_KEY, template));
|
||||
|
||||
MockServerHttpRequest request = MockServerHttpRequest
|
||||
.get("http://localhost"+ actualPath)
|
||||
|
||||
@@ -151,7 +151,8 @@ spring:
|
||||
- Path=/headers
|
||||
filters:
|
||||
- name: SetStatus
|
||||
args: 401
|
||||
args:
|
||||
status: 401
|
||||
|
||||
# =====================================
|
||||
- id: set_status_string_test
|
||||
|
||||
Reference in New Issue
Block a user