Extract ArgumentHints interface
This commit is contained in:
@@ -17,49 +17,23 @@
|
||||
|
||||
package org.springframework.cloud.gateway.filter.factory;
|
||||
|
||||
import org.springframework.cloud.gateway.support.ArgumentHints;
|
||||
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 {
|
||||
public interface WebFilterFactory extends ArgumentHints {
|
||||
|
||||
String NAME_KEY = "name";
|
||||
String VALUE_KEY = "value";
|
||||
|
||||
//TODO: move from String... to Tuple
|
||||
WebFilter apply(Tuple args);
|
||||
|
||||
default String name() {
|
||||
return NameUtils.normalizeFilterName(getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,19 +17,16 @@
|
||||
|
||||
package org.springframework.cloud.gateway.handler.predicate;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.gateway.support.ArgumentHints;
|
||||
import org.springframework.cloud.gateway.support.NameUtils;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicate;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RequestPredicateFactory {
|
||||
public interface RequestPredicateFactory extends ArgumentHints {
|
||||
|
||||
RequestPredicate apply(Tuple args);
|
||||
|
||||
@@ -37,25 +34,4 @@ public interface RequestPredicateFactory {
|
||||
return NameUtils.normalizePredicateName(getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hints about the number of args and the order for shortcut parsing.
|
||||
* @return
|
||||
*/
|
||||
default List<String> argNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 validateArgs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default void validate(int minimumSize, Tuple args) {
|
||||
Assert.isTrue(args != null && args.size() >= minimumSize,
|
||||
"args must have at least "+ minimumSize +" entry(s)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.gateway.model;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -73,6 +74,11 @@ public class Route {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder uri(String uri) {
|
||||
this.uri = URI.create(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder uri(URI uri) {
|
||||
this.uri = uri;
|
||||
return this;
|
||||
@@ -93,6 +99,11 @@ public class Route {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addAll(Collection<WebFilter> webFilter) {
|
||||
this.webFilters.addAll(webFilter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Route build() {
|
||||
Assert.notNull(this.id, "id can not be null");
|
||||
Assert.notNull(this.uri, "uri can not be null");
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.gateway.support;
|
||||
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface ArgumentHints {
|
||||
|
||||
/**
|
||||
* 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)");
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
.build();
|
||||
}
|
||||
|
||||
private Collection<WebFilter> loadFilters(List<GlobalFilter> filters) {
|
||||
public static Collection<WebFilter> loadFilters(List<GlobalFilter> filters) {
|
||||
return filters.stream()
|
||||
.map(filter -> {
|
||||
WebFilterAdapter webFilter = new WebFilterAdapter(filter);
|
||||
@@ -148,42 +148,7 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
logger.debug("RouteDefinition " + id + " applying filter " + args + " to " + definition.getName());
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Tuple tuple = getTuple(filter, args);
|
||||
|
||||
return filter.apply(tuple);
|
||||
})
|
||||
@@ -197,6 +162,45 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private Tuple getTuple(ArgumentHints hasArguments, Map<String, String> args) {
|
||||
TupleBuilder builder = TupleBuilder.tuple();
|
||||
|
||||
List<String> argNames = hasArguments.argNames();
|
||||
if (!argNames.isEmpty()) {
|
||||
// ensure size is the same for key replacement later
|
||||
if (hasArguments.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 (hasArguments.validateArgs()) {
|
||||
for (String name : argNames) {
|
||||
if (!tuple.hasFieldName(name)) {
|
||||
throw new IllegalArgumentException("Missing argument '" + name + "'. Given " + tuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tuple;
|
||||
}
|
||||
|
||||
private List<WebFilter> getFilters(RouteDefinition routeDefinition) {
|
||||
//TODO: probably a java 8 stream way of doing this
|
||||
List<WebFilter> combined = new ArrayList<>(loadFilters(this.globalFilters));
|
||||
@@ -238,43 +242,7 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
+ args + " to " + predicate.getName());
|
||||
}
|
||||
|
||||
TupleBuilder builder = TupleBuilder.tuple();
|
||||
|
||||
List<String> argNames = found.argNames();
|
||||
if (!argNames.isEmpty()) {
|
||||
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 + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (found.validateArgs()) {
|
||||
for (String name : argNames) {
|
||||
if (!tuple.hasFieldName(name)) {
|
||||
throw new IllegalArgumentException("Missing argument '" + name + "'. Given " + tuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
Tuple tuple = getTuple(found, args);
|
||||
|
||||
return found.apply(tuple);
|
||||
}
|
||||
@@ -302,7 +270,7 @@ public class RouteDefinitionRouteLocator implements RouteLocator {
|
||||
}
|
||||
}
|
||||
|
||||
public class OrderedWebFilter implements WebFilter, Ordered {
|
||||
public static class OrderedWebFilter implements WebFilter, Ordered {
|
||||
|
||||
private final WebFilter delegate;
|
||||
private final int order;
|
||||
|
||||
Reference in New Issue
Block a user