Adds a method to nest boolean predicates

Spring Cloud Gateway supports complicated boolean predicates like:

    (query("a") || query("b")) && (host("x") || host("y))

But lacked a Java API to express this. This new methods allows the above:

    r.query("a").or().query("b").and().nested(p ->
      r.host("x").or().host("y")
    )

Fixes gh-2598
This commit is contained in:
Brian McKenna
2022-04-22 15:35:18 +10:00
committed by spencergibb
parent 2307cc71c8
commit 67f95244be
2 changed files with 37 additions and 0 deletions

View File

@@ -115,6 +115,10 @@ public class BooleanSpec extends UriSpec {
return fn.apply(new NotOpSpec(this.routeBuilder, this.builder, this.operator));
}
public BooleanSpec nested(Function<PredicateSpec, BooleanSpec> fn) {
return fn.apply(new NestedOpSpec(this.routeBuilder, this.builder, this.operator));
}
}
public static class NotOpSpec extends BooleanOpSpec {
@@ -131,4 +135,17 @@ public class BooleanSpec extends UriSpec {
}
public static class NestedOpSpec extends BooleanOpSpec {
NestedOpSpec(Route.AsyncBuilder routeBuilder, RouteLocatorBuilder.Builder builder, Operator operator) {
super(routeBuilder, builder, operator);
}
@Override
public BooleanSpec asyncPredicate(AsyncPredicate<ServerWebExchange> predicate) {
return super.asyncPredicate(predicate);
}
}
}

View File

@@ -94,6 +94,18 @@ public class RoutePredicateHandlerMappingIntegrationTests extends BaseWebClientT
.isEqualTo("hasquery");
}
@Test
public void andNestedOrQuery1() {
testClient.get().uri("/andnestedquery?query1=hasquery1").exchange().expectBody(String.class)
.isEqualTo("hasquery1,notsupplied");
}
@Test
public void andNestedOrQuery2() {
testClient.get().uri("/andnestedquery?query2=hasquery2").exchange().expectBody(String.class)
.isEqualTo("notsupplied,hasquery2");
}
@EnableAutoConfiguration
@SpringBootConfiguration
@Import(DefaultTestConfig.class)
@@ -108,6 +120,12 @@ public class RoutePredicateHandlerMappingIntegrationTests extends BaseWebClientT
return myquery;
}
@GetMapping("/httpbin/andnestedquery")
String andnotquery(@RequestParam(name = "query1", defaultValue = "notsupplied") String query1,
@RequestParam(name = "query2", defaultValue = "notsupplied") String query2) {
return query1 + "," + query2;
}
@GetMapping("/httpbin/hasquery")
String hasquery() {
return "hasquery";
@@ -128,6 +146,8 @@ public class RoutePredicateHandlerMappingIntegrationTests extends BaseWebClientT
.query("myquery")
.filters(f -> f.setPath("/httpbin/hasquery"))
.uri(uri))
.route("and_nested_query1_or_query2", r -> r.path("/andnestedquery").and().nested(p -> p.query("query1").or().query("query2"))
.filters(f -> f.prefixPath("/httpbin")).uri(uri))
.build();
}