Skip to content

Commit

Permalink
Adds GatewayRequestPredicates.query()
Browse files Browse the repository at this point in the history
  • Loading branch information
spencergibb committed Dec 5, 2023
1 parent 7a419c8 commit 563a0ab
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,6 @@ Map<String, Object> uriVariables = MvcUtils.getUriTemplateVariables(request);
String segment = uriVariables.get("segment");
----

////
TODO: query predicate
[[query-request-predicate]]
== The Query Request Predicate

Expand All @@ -411,6 +409,26 @@ spring:
- Query=green
----

.GatewaySampleApplication.java
[source,java]
----
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.query;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsQuery() {
return route("query_route")
.route(query("green"), http("https://example.org"))
.build();
}
}
----

The preceding route matches if the request contained a `green` query parameter.

.application.yml
Expand All @@ -426,8 +444,29 @@ spring:
- Query=red, gree.
----

.GatewaySampleApplication.java
[source,java]
----
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.query;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsQuery() {
return route("query_route")
.route(query("red", "gree."), http("https://example.org"))
.build();
}
}
----

The preceding route matches if the request contained a `red` query parameter whose value matched the `gree.` regexp, so `green` and `greet` would match.

////
TODO: remoteAddr predicate
[[remoteaddr-request-predicate]]
== The RemoteAddr Request Predicate
Expand Down Expand Up @@ -511,7 +550,7 @@ RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
[[weight-request-predicate]]
== The Weight Request Predicate

The `Weight` route predicate factory takes two arguments: `group` and `weight` (an int). The weights are calculated per group.
The `Weight` route predicate factory takes two arguments: `group` and `weight` (an `int`). The weights are calculated per group.
The following example configures a weight route predicate:

.application.yml
Expand Down Expand Up @@ -554,7 +593,7 @@ class RouteConfiguration {
}
----

This route would forward ~80% of traffic to https://weighthigh.org and ~20% of traffic to https://weightlow.org
This route would forward ~80% of traffic to https://weighthigh.org and ~20% of traffic to https://weightlow.org.

////
TODO: XForwardedRemoteAddr predicate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ public ServerResponse handle(ServerRequest serverRequest) {
boolean encoded = containsEncodedQuery(serverRequest.uri());
// @formatter:off
URI url = UriComponentsBuilder.fromUri(serverRequest.uri())
// .uri(routeUri)
.scheme(uri.getScheme())
.host(uri.getHost())
.port(uri.getPort())
.queryParams(serverRequest.params())
.replaceQueryParams(serverRequest.params())
.build(encoded)
.toUri();
// @formatter:on
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,32 @@ public static RequestPredicate path(String... patterns) {
return requestPredicate;
}

/**
* Return a {@code RequestPredicate} that tests the presence of a request parameter.
* @param param the name of the query parameter
* @return a predicate that tests for the presence of a given param
*/
@Shortcut
public static RequestPredicate query(String param) {
return query(param, null);
}

/**
* Return a {@code RequestPredicate} that tests the presence of a request parameter if
* the regexp is empty, or, otherwise finds if any value of the parameter matches the
* regexp.
* @param param the name of the query parameter
* @param regexp an optional regular expression to match.
* @return a predicate that tests for the given param and regexp.
*/
@Shortcut
public static RequestPredicate query(String param, String regexp) {
if (!StringUtils.hasText(regexp)) {
return request -> request.param(param).isPresent();
}
return request -> request.param(param).stream().anyMatch(value -> value.matches(regexp));
}

public static <T> RequestPredicate readBody(Class<T> inClass, Predicate<T> predicate) {
return new ReadBodyPredicate<>(inClass, predicate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.cookie;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.header;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.query;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.readBody;
import static org.springframework.cloud.gateway.server.mvc.test.TestUtils.getMap;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
Expand Down Expand Up @@ -605,6 +606,19 @@ public void forwardNon200StatusWorks() {
.isEqualTo("hello2");
}

@Test
@SuppressWarnings("rawtypes")
public void queryParamWorks() {
restClient.get().uri("/get?foo=bar").exchange().expectStatus().isOk().expectBody(Map.class)
.consumeWith(result -> {
Map responseBody = result.getResponseBody();
assertThat(responseBody).containsKey("args");
Map args = getMap(responseBody, "args");
assertThat(args).containsKey("foo");
assertThat(args.get("foo")).isEqualTo("bar");
});
}

@SpringBootConfiguration
@EnableAutoConfiguration
@LoadBalancerClient(name = "httpbin", configuration = TestLoadBalancerConfig.Httpbin.class)
Expand Down Expand Up @@ -1126,6 +1140,16 @@ public RouterFunction<ServerResponse> gatewayRouterFunctionsForwardNon200Status(
// @formatter:on
}

@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsQuery() {
// @formatter:off
return route("testqueryparam")
.route(query("foo", "bar"), http())
.before(new HttpbinUriResolver())
.build();
// @formatter:on
}

private Predicate<Event> eventPredicate(String foo) {
return new Predicate<>() {
@Override
Expand Down

0 comments on commit 563a0ab

Please sign in to comment.