Removes tuple

fixes gh-274
This commit is contained in:
Spencer Gibb
2018-04-10 17:53:09 -04:00
parent fa6a7ff41f
commit ecc221b45d
19 changed files with 29 additions and 491 deletions

16
pom.xml
View File

@@ -50,7 +50,6 @@
<java.version>1.8</java.version>
<spring-cloud-commons.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-netflix.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-netflix.version>
<spring-tuple.version>1.0.0.RELEASE</spring-tuple.version>
</properties>
<dependencyManagement>
@@ -112,21 +111,6 @@
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tuple</artifactId>
<version>${spring-tuple.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -52,10 +52,6 @@
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tuple</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>

View File

@@ -17,9 +17,7 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.support.AbstractConfigurable;
import org.springframework.tuple.Tuple;
public abstract class AbstractGatewayFilterFactory<C>
extends AbstractConfigurable<C> implements GatewayFilterFactory<C> {
@@ -33,16 +31,6 @@ public abstract class AbstractGatewayFilterFactory<C>
super(configClass);
}
@Override
public boolean isConfigurable() {
return true;
}
@Override
public GatewayFilter apply(Tuple args) {
throw new UnsupportedOperationException("apply(Tuple) not supported");
}
public static class NameConfig {
private String name;

View File

@@ -17,14 +17,13 @@
package org.springframework.cloud.gateway.filter.factory;
import java.util.function.Consumer;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.cloud.gateway.support.Configurable;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
import java.util.function.Consumer;
/**
* @author Spencer Gibb
@@ -35,11 +34,6 @@ public interface GatewayFilterFactory<C> extends ShortcutConfigurable, Configura
String NAME_KEY = "name";
String VALUE_KEY = "value";
@Deprecated //TODO: remove when apply(Tuple) is removed
default boolean isConfigurable() {
return false;
}
// useful for javadsl
default GatewayFilter apply(Consumer<C> consumer) {
C config = newConfig();
@@ -47,25 +41,16 @@ public interface GatewayFilterFactory<C> extends ShortcutConfigurable, Configura
return apply(config);
}
//TODO: remove after apply(Tuple) removed
@Override
default Class<C> getConfigClass() {
throw new UnsupportedOperationException("getConfigClass() not implemented");
}
//TODO: remove after apply(Tuple) removed
@Override
default C newConfig() {
throw new UnsupportedOperationException("newConfig() not implemented");
}
//TODO: remove default impl after apply(Tuple) removed
default GatewayFilter apply(C config) {
throw new UnsupportedOperationException("apply(C config) not implemented");
}
@Deprecated
GatewayFilter apply(Tuple args);
GatewayFilter apply(C config);
default String name() {
//TODO: deal with proxys

View File

@@ -18,21 +18,19 @@
package org.springframework.cloud.gateway.filter.factory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.tuple.Tuple;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE;
/**
* @author Spencer Gibb
*/
public class PreserveHostHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public GatewayFilter apply(Tuple args) {
return apply();
}
public class PreserveHostHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory {
public GatewayFilter apply() {
return apply(o -> {});
}
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
exchange.getAttributes().put(PRESERVE_HOST_HEADER_ATTRIBUTE, true);
return chain.filter(exchange);

View File

@@ -18,10 +18,6 @@
package org.springframework.cloud.gateway.handler.predicate;
import org.springframework.cloud.gateway.support.AbstractConfigurable;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.ServerWebExchange;
import java.util.function.Predicate;
public abstract class AbstractRoutePredicateFactory<C> extends AbstractConfigurable<C>
implements RoutePredicateFactory<C> {
@@ -30,13 +26,4 @@ public abstract class AbstractRoutePredicateFactory<C> extends AbstractConfigura
super(configClass);
}
@Override
public boolean isConfigurable() {
return true;
}
@Override
public Predicate<ServerWebExchange> apply(Tuple args) {
throw new UnsupportedOperationException("apply(Tuple) not supported");
}
}

View File

@@ -44,11 +44,6 @@ public class QueryRoutePredicateFactory extends AbstractRoutePredicateFactory<Qu
return Arrays.asList(PARAM_KEY, REGEXP_KEY);
}
@Override
public boolean validateFieldsExist() {
return false;
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {

View File

@@ -23,7 +23,6 @@ import java.util.function.Predicate;
import org.springframework.cloud.gateway.support.Configurable;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.tuple.Tuple;
import org.springframework.web.server.ServerWebExchange;
/**
@@ -33,11 +32,6 @@ import org.springframework.web.server.ServerWebExchange;
public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configurable<C> {
String PATTERN_KEY = "pattern";
@Deprecated //TODO: remove when apply(Tuple) is removed
default boolean isConfigurable() {
return false;
}
// useful for javadsl
default Predicate<ServerWebExchange> apply(Consumer<C> consumer) {
C config = newConfig();
@@ -46,27 +40,18 @@ public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configur
return apply(config);
}
default void beforeApply(C config) {}
//TODO: remove after apply(Tuple) removed
@Override
default Class<C> getConfigClass() {
throw new UnsupportedOperationException("getConfigClass() not implemented");
}
//TODO: remove after apply(Tuple) removed
@Override
default C newConfig() {
throw new UnsupportedOperationException("newConfig() not implemented");
}
//TODO: remove default impl after apply(Tuple) removed
default Predicate<ServerWebExchange> apply(C config) {
throw new UnsupportedOperationException("apply(C config) not implemented");
}
default void beforeApply(C config) {}
@Deprecated
Predicate<ServerWebExchange> apply(Tuple args);
Predicate<ServerWebExchange> apply(C config);
default String name() {
return NameUtils.normalizeRoutePredicateName(getClass());

View File

@@ -41,19 +41,13 @@ import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
import org.springframework.cloud.gateway.support.ConfigurationUtils;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.tuple.Tuple;
import org.springframework.tuple.TupleBuilder;
import org.springframework.validation.Validator;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.ShortcutConfigurable.getValue;
import static org.springframework.cloud.gateway.support.ShortcutConfigurable.normalizeKey;
import reactor.core.publisher.Flux;
/**
@@ -151,23 +145,18 @@ public class RouteDefinitionRouteLocator implements RouteLocator, BeanFactoryAwa
logger.debug("RouteDefinition " + id + " applying filter " + args + " to " + definition.getName());
}
if (factory.isConfigurable()) {
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
Object configuration = factory.newConfig();
Object configuration = factory.newConfig();
ConfigurationUtils.bind(configuration, properties,
factory.shortcutFieldPrefix(), definition.getName(), validator);
ConfigurationUtils.bind(configuration, properties,
factory.shortcutFieldPrefix(), definition.getName(), validator);
GatewayFilter gatewayFilter = factory.apply(configuration);
if (this.publisher != null) {
this.publisher.publishEvent(new FilterArgsEvent(this, id, properties));
}
return gatewayFilter;
} else {
Tuple tuple = getTuple(factory, args, this.parser, this.beanFactory);
return factory.apply(tuple);
GatewayFilter gatewayFilter = factory.apply(configuration);
if (this.publisher != null) {
this.publisher.publishEvent(new FilterArgsEvent(this, id, properties));
}
return gatewayFilter;
})
.collect(Collectors.toList());
@@ -179,41 +168,6 @@ public class RouteDefinitionRouteLocator implements RouteLocator, BeanFactoryAwa
return ordered;
}
@SuppressWarnings("Duplicates")
@Deprecated //TODO: remove after Tuple is removed
/* for testing */ static Tuple getTuple(ShortcutConfigurable shortcutConf, Map<String, String> args, SpelExpressionParser parser, BeanFactory beanFactory) {
TupleBuilder builder = TupleBuilder.tuple();
List<String> argNames = shortcutConf.shortcutFieldOrder();
if (!argNames.isEmpty()) {
// ensure size is the same for key replacement later
if (shortcutConf.validateFieldsExist() && 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 = normalizeKey(entry.getKey(), entryIdx, shortcutConf, args);
Object value = getValue(parser, beanFactory, entry.getValue());
builder.put(key, value);
entryIdx++;
}
Tuple tuple = builder.build();
if (shortcutConf.validateFieldsExist()) {
for (String name : argNames) {
if (!tuple.hasFieldName(name)) {
throw new IllegalArgumentException("Missing argument '" + name + "'. Given " + tuple);
}
}
}
return tuple;
}
private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
List<GatewayFilter> filters = new ArrayList<>();
@@ -255,18 +209,13 @@ public class RouteDefinitionRouteLocator implements RouteLocator, BeanFactoryAwa
+ args + " to " + predicate.getName());
}
if (!factory.isConfigurable()) {
Tuple tuple = getTuple(factory, args, this.parser, this.beanFactory);
return factory.apply(tuple);
} else {
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
Object config = factory.newConfig();
ConfigurationUtils.bind(config, properties,
factory.shortcutFieldPrefix(), predicate.getName(), validator);
if (this.publisher != null) {
this.publisher.publishEvent(new PredicateArgsEvent(this, route.getId(), properties));
}
return factory.apply(config);
}
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
Object config = factory.newConfig();
ConfigurationUtils.bind(config, properties,
factory.shortcutFieldPrefix(), predicate.getName(), validator);
if (this.publisher != null) {
this.publisher.publishEvent(new PredicateArgsEvent(this, route.getId(), properties));
}
return factory.apply(config);
}
}

View File

@@ -1,60 +0,0 @@
/*
* 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.List;
/**
* @author Spencer Gibb
* @deprecated Use {@link ShortcutConfigurable} instead
*/
@Deprecated
public interface ArgumentHints extends ShortcutConfigurable {
/**
* Returns hints about the number of args and the order for shortcut parsing.
* @return
*/
default List<String> argNames() {
return shortcutFieldOrder();
}
/**
* Validate supplied argument size against {@see #argNames} size.
* Useful for variable arg predicates.
* @return
*/
default boolean validateArgs() {
return validateFieldsExist();
}
@Deprecated
default void validate(int requiredSize, Tuple args) {
Assert.isTrue(args != null && args.size() == requiredSize,
"args must have "+ requiredSize +" entry(s)");
}
@Deprecated
default void validateMin(int minSize, Tuple args) {
Assert.isTrue(args != null && args.size() >= minSize,
"args must have at least "+ minSize +" entry(s)");
}
}

View File

@@ -1,211 +0,0 @@
package org.springframework.cloud.gateway.support;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.AbstractServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.SslInfo;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
/**
* Package-private default implementation of {@link ServerHttpRequest.Builder}.
*
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 5.0
*/
@Deprecated
public class GatewayServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private boolean encoded;
private URI uri;
private HttpHeaders httpHeaders;
private String httpMethodValue;
private final MultiValueMap<String, HttpCookie> cookies;
@Nullable
private String uriPath;
@Nullable
private String contextPath;
private Flux<DataBuffer> body;
private final ServerHttpRequest originalRequest;
public GatewayServerHttpRequestBuilder(ServerHttpRequest original) {
this(original, true);
}
public GatewayServerHttpRequestBuilder(ServerHttpRequest original, boolean encoded) {
Assert.notNull(original, "ServerHttpRequest is required");
this.uri = original.getURI();
this.httpMethodValue = original.getMethodValue();
this.body = original.getBody();
this.httpHeaders = new HttpHeaders();
copyMultiValueMap(original.getHeaders(), this.httpHeaders);
this.cookies = new LinkedMultiValueMap<>(original.getCookies().size());
copyMultiValueMap(original.getCookies(), this.cookies);
this.originalRequest = original;
this.encoded = encoded;
}
private static <K, V> void copyMultiValueMap(MultiValueMap<K,V> source,
MultiValueMap<K,V> destination) {
for (Map.Entry<K, List<V>> entry : source.entrySet()) {
K key = entry.getKey();
List<V> values = new LinkedList<>(entry.getValue());
destination.put(key, values);
}
}
@Override
public ServerHttpRequest.Builder method(HttpMethod httpMethod) {
this.httpMethodValue = httpMethod.name();
return this;
}
@Override
public ServerHttpRequest.Builder uri(URI uri) {
this.uri = uri;
return this;
}
@Override
public ServerHttpRequest.Builder path(String path) {
this.uriPath = path;
return this;
}
@Override
public ServerHttpRequest.Builder contextPath(String contextPath) {
this.contextPath = contextPath;
return this;
}
@Override
public ServerHttpRequest.Builder header(String key, String value) {
this.httpHeaders.add(key, value);
return this;
}
@Override
public ServerHttpRequest.Builder headers(Consumer<HttpHeaders> headersConsumer) {
Assert.notNull(headersConsumer, "'headersConsumer' must not be null");
headersConsumer.accept(this.httpHeaders);
return this;
}
@Override
public ServerHttpRequest build() {
URI uriToUse = getUriToUse();
return new GatewayServerHttpRequest(uriToUse, this.contextPath, this.httpHeaders,
this.httpMethodValue, this.cookies, this.body, this.originalRequest);
}
private URI getUriToUse() {
if (this.uriPath == null) {
return this.uri;
}
try {
return UriComponentsBuilder.fromUri(this.uri)
.replacePath(uriPath)
.build(encoded).toUri();
}
catch (RuntimeException ex) {
throw new IllegalStateException("Invalid URI path: \"" + this.uriPath + "\"");
}
}
private static class GatewayServerHttpRequest extends AbstractServerHttpRequest {
private final String methodValue;
private final MultiValueMap<String, HttpCookie> cookies;
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final SslInfo sslInfo;
private final Flux<DataBuffer> body;
private final ServerHttpRequest originalRequest;
public GatewayServerHttpRequest(URI uri, @Nullable String contextPath,
HttpHeaders headers, String methodValue, MultiValueMap<String, HttpCookie> cookies,
Flux<DataBuffer> body, ServerHttpRequest originalRequest) {
super(uri, contextPath, headers);
this.methodValue = methodValue;
this.cookies = cookies;
this.remoteAddress = originalRequest.getRemoteAddress();
this.sslInfo = originalRequest.getSslInfo();
this.body = body;
this.originalRequest = originalRequest;
}
@Override
public String getMethodValue() {
return this.methodValue;
}
@Override
protected MultiValueMap<String, HttpCookie> initCookies() {
return this.cookies;
}
@Nullable
@Override
public InetSocketAddress getRemoteAddress() {
return this.remoteAddress;
}
@Nullable
@Override
protected SslInfo initSslInfo() {
return this.sslInfo;
}
@Override
public Flux<DataBuffer> getBody() {
return this.body;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNativeRequest() {
return (T) this.originalRequest;
}
}
}

View File

@@ -119,14 +119,4 @@ public interface ShortcutConfigurable {
return "";
}
/**
* Validate supplied argument size against {@see #shortcutFieldOrder} size.
* Useful for variable arg predicates.
* @return
*/
@Deprecated
default boolean validateFieldsExist() {
return true;
}
}

View File

@@ -24,12 +24,10 @@ import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.tuple.Tuple;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.tuple.TupleBuilder.tuple;
import reactor.core.publisher.Mono;
@@ -71,7 +69,6 @@ public class RequestRateLimiterGatewayFilterFactoryTests extends BaseWebClientTe
private void assertFilterFactory(KeyResolver keyResolver, String key, boolean allowed, HttpStatus expectedStatus) {
Tuple args = tuple().build();
when(rateLimiter.isAllowed("myroute", key))
.thenReturn(Mono.just(new Response(allowed, 1)));

View File

@@ -33,11 +33,8 @@ import org.springframework.web.util.UriComponentsBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
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.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.tuple.TupleBuilder.tuple;
import reactor.core.publisher.Mono;

View File

@@ -34,7 +34,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
* @author Ryan Baxter

View File

@@ -13,7 +13,6 @@ import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.tuple.Tuple;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;

View File

@@ -22,13 +22,11 @@ import org.junit.Test;
import java.time.ZonedDateTime;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory.DATETIME_KEY;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.getExchange;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHoursMillis;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
* @author Spencer Gibb

View File

@@ -22,13 +22,11 @@ import org.junit.Test;
import java.time.ZonedDateTime;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory.DATETIME_KEY;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.getExchange;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.minusHoursMillis;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHours;
import static org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactoryTests.plusHoursMillis;
import static org.springframework.tuple.TupleBuilder.tuple;
/**
* @author Spencer Gibb

View File

@@ -1,57 +1,21 @@
package org.springframework.cloud.gateway.route;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.context.annotation.Bean;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.tuple.Tuple;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RouteDefinitionRouteLocatorTests {
private SpelExpressionParser parser;
@Autowired
BeanFactory beanFactory;
@Test
public void testGetTupleWithSpel() {
parser = new SpelExpressionParser();
ShortcutConfigurable shortcutConfigurable = new ShortcutConfigurable() {
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("bean", "arg1");
}
};
Map<String, String> args = new HashMap<>();
args.put("bean", "#{@foo}");
args.put("arg1", "val1");
Tuple tuple = RouteDefinitionRouteLocator.getTuple(shortcutConfigurable, args, parser, this.beanFactory);
assertThat(tuple).isNotNull();
assertThat(tuple.getValue("bean", Integer.class)).isEqualTo(42);
assertThat(tuple.getString("arg1")).isEqualTo("val1");
public void contextLoads() {
}
@SpringBootConfiguration
protected static class TestConfig {
@Bean
public Integer foo() {
return 42;
}
}
}