Browse Source

Merge branch '2.0.x'

pull/720/head
Spencer Gibb 6 years ago
parent
commit
4d94650896
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 6
      docs/src/main/asciidoc/spring-cloud-gateway.adoc
  2. 4
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactory.java
  3. 2
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HostRoutePredicateFactory.java
  4. 6
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java
  5. 25
      spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java
  6. 13
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryIntegrationTests.java
  7. 23
      spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java
  8. 8
      spring-cloud-gateway-core/src/test/resources/application.yml

6
docs/src/main/asciidoc/spring-cloud-gateway.adoc

@ -149,8 +149,12 @@ spring: @@ -149,8 +149,12 @@ spring:
- Host=**.somehost.org,**.anotherhost.org
----
URI template variables are supported as well, such as `{sub}.myhost.org`.
This route would match if the request has a `Host` header has the value `www.somehost.org` or `beta.somehost.org` or `www.anotherhost.org`.
This predicate extracts the URI template variables (like `sub` defined in the example above) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE`. Those values are then available for use by <<gateway-route-filters,GatewayFilter Factories>>
=== Method Route Predicate Factory
The Method Route Predicate Factory takes one parameter: the HTTP method to match.
@ -188,7 +192,7 @@ spring: @@ -188,7 +192,7 @@ spring:
This route would match if the request path was, for example: `/foo/1` or `/foo/bar` or `/bar/baz`.
This predicate extracts the URI template variables (like `segment` defined in the example above) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `PathRoutePredicate.URL_PREDICATE_VARS_ATTR`. Those values are then available for use by <<gateway-route-filters,GatewayFilter Factories>>
This predicate extracts the URI template variables (like `segment` defined in the example above) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE`. Those values are then available for use by <<gateway-route-filters,GatewayFilter Factories>>
A utility method is available to make access to these variables easier.

4
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactory.java

@ -28,7 +28,7 @@ import org.springframework.web.util.UriTemplate; @@ -28,7 +28,7 @@ import org.springframework.web.util.UriTemplate;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getPathPredicateVariables;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getUriTemplateVariables;
/**
* @author Spencer Gibb
@ -54,7 +54,7 @@ public class SetPathGatewayFilterFactory extends AbstractGatewayFilterFactory<Se @@ -54,7 +54,7 @@ public class SetPathGatewayFilterFactory extends AbstractGatewayFilterFactory<Se
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());
Map<String, String> uriVariables = getPathPredicateVariables(exchange);
Map<String, String> uriVariables = getUriTemplateVariables(exchange);
URI uri = uriTemplate.expand(uriVariables);
String newPath = uri.getRawPath();

2
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/HostRoutePredicateFactory.java

@ -20,8 +20,10 @@ package org.springframework.cloud.gateway.handler.predicate; @@ -20,8 +20,10 @@ package org.springframework.cloud.gateway.handler.predicate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

6
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java

@ -35,7 +35,7 @@ import org.springframework.web.util.pattern.PathPattern; @@ -35,7 +35,7 @@ import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPattern.PathMatchInfo;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.putUriTemplateVariables;
import static org.springframework.http.server.PathContainer.parsePath;
/**
@ -85,8 +85,8 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat @@ -85,8 +85,8 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat
if (optionalPathPattern.isPresent()) {
PathPattern pathPattern = optionalPathPattern.get();
traceMatch("Pattern", pathPattern.getPatternString(), path, true);
PathMatchInfo uriTemplateVariables = pathPattern.matchAndExtract(path);
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
PathMatchInfo pathMatchInfo = pathPattern.matchAndExtract(path);
putUriTemplateVariables(exchange, pathMatchInfo.getUriVariables());
return true;
} else {
traceMatch("Pattern", config.getPatterns(), path, false);

25
spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
package org.springframework.cloud.gateway.support;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
@ -32,7 +32,6 @@ import org.springframework.cloud.gateway.handler.AsyncPredicate; @@ -32,7 +32,6 @@ import org.springframework.cloud.gateway.handler.AsyncPredicate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.AbstractServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
/**
* @author Spencer Gibb
@ -129,16 +128,20 @@ public class ServerWebExchangeUtils { @@ -129,16 +128,20 @@ public class ServerWebExchangeUtils {
return t -> Mono.just(predicate.test(t));
}
public static Map<String, String> getPathPredicateVariables(ServerWebExchange exchange) {
return getPathMatchVariables(exchange, URI_TEMPLATE_VARIABLES_ATTRIBUTE);
@SuppressWarnings("unchecked")
public static void putUriTemplateVariables(ServerWebExchange exchange, Map<String, String> uriVariables) {
if (exchange.getAttributes().containsKey(URI_TEMPLATE_VARIABLES_ATTRIBUTE)) {
Map<String, Object> existingVariables = (Map<String, Object>) exchange.getAttributes().get(URI_TEMPLATE_VARIABLES_ATTRIBUTE);
HashMap<String, Object> newVariables = new HashMap<>();
newVariables.putAll(existingVariables);
newVariables.putAll(uriVariables);
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, newVariables);
} else {
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriVariables);
}
public static Map<String, String> getPathMatchVariables(ServerWebExchange exchange, String attr) {
PathPattern.PathMatchInfo variables = exchange.getAttribute(URI_TEMPLATE_VARIABLES_ATTRIBUTE);
if (variables != null) {
return variables.getUriVariables();
}
return Collections.emptyMap();
public static Map<String, String> getUriTemplateVariables(ServerWebExchange exchange) {
return exchange.getAttributeOrDefault(URI_TEMPLATE_VARIABLES_ATTRIBUTE, new HashMap<>());
}
}

13
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryIntegrationTests.java

@ -40,7 +40,18 @@ public class SetPathGatewayFilterFactoryIntegrationTests extends BaseWebClientTe @@ -40,7 +40,18 @@ public class SetPathGatewayFilterFactoryIntegrationTests extends BaseWebClientTe
.uri("/foo/get")
.header("Host", "www.setpath.org")
.exchange()
.expectStatus().isOk();
.expectStatus().isOk()
.expectHeader().valueEquals(ROUTE_ID_HEADER, "set_path_test");
}
@Test
public void setPathViaHostFilterWork() {
testClient.get()
.uri("/")
.header("Host", "get.setpathhost.org")
.exchange()
.expectStatus().isOk()
.expectHeader().valueEquals(ROUTE_ID_HEADER, "set_path_host_test");
}
@EnableAutoConfiguration

23
spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SetPathGatewayFilterFactoryTests.java

@ -17,30 +17,25 @@ @@ -17,30 +17,25 @@
package org.springframework.cloud.gateway.filter.factory;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.util.pattern.PathPattern.PathMatchInfo;
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.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
@ -89,15 +84,7 @@ public class SetPathGatewayFilterFactoryTests { @@ -89,15 +84,7 @@ public class SetPathGatewayFilterFactoryTests {
.build();
ServerWebExchange exchange = MockServerWebExchange.from(request);
try {
Constructor<PathMatchInfo> constructor = ReflectionUtils.accessibleConstructor(PathMatchInfo.class, Map.class, Map.class);
constructor.setAccessible(true);
PathMatchInfo pathMatchInfo = constructor.newInstance(variables, Collections.emptyMap());
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, pathMatchInfo);
} catch (Exception e) {
ReflectionUtils.rethrowRuntimeException(e);
}
ServerWebExchangeUtils.putUriTemplateVariables(exchange, variables);
GatewayFilterChain filterChain = mock(GatewayFilterChain.class);

8
spring-cloud-gateway-core/src/test/resources/application.yml

@ -245,6 +245,14 @@ spring: @@ -245,6 +245,14 @@ spring:
filters:
- SetPath=/{segment}
# =====================================
- id: set_path_host_test
uri: ${test.uri}
predicates:
- Host={subdomain}.setpathhost.org
filters:
- SetPath=/{subdomain}
# =====================================
- id: strip_prefix_test
uri: ${test.uri}

Loading…
Cancel
Save