diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/BooleanSpec.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/BooleanSpec.java index 55491cd22..cdde8ce86 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/BooleanSpec.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/BooleanSpec.java @@ -28,6 +28,9 @@ import static org.springframework.cloud.gateway.route.builder.BooleanSpec.Operat import static org.springframework.cloud.gateway.route.builder.BooleanSpec.Operator.OR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.toAsyncPredicate; +/** + * A spec used to apply logical operators. + */ public class BooleanSpec extends UriSpec { enum Operator { AND, OR, NEGATE } @@ -40,19 +43,36 @@ public class BooleanSpec extends UriSpec { predicate = routeBuilder.getPredicate(); } + /** + * Apply logical {@code and} operator. + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanOpSpec and() { return new BooleanOpSpec(routeBuilder, builder, AND); } + /** + * Apply logical {@code or} operator. + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanOpSpec or() { return new BooleanOpSpec(routeBuilder, builder, OR); } + /** + * Negate the logical operator. + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec negate() { this.routeBuilder.negate(); return new BooleanSpec(routeBuilder, builder); } + /** + * Add filters to the route definition. + * @param fn A {@link Function} that takes in a {@link GatewayFilterSpec} and returns a {@link UriSpec} + * @return a {@link UriSpec} + */ public UriSpec filters(Function fn) { return fn.apply(new GatewayFilterSpec(routeBuilder, builder)); } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/PredicateSpec.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/PredicateSpec.java index 63c22a9fd..0c49b4923 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/PredicateSpec.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/PredicateSpec.java @@ -39,6 +39,9 @@ import org.springframework.web.server.ServerWebExchange; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.toAsyncPredicate; +/** + * Predicates that can be applies to a URI route. + */ public class PredicateSpec extends UriSpec { PredicateSpec(Route.AsyncBuilder routeBuilder, RouteLocatorBuilder.Builder builder) { @@ -63,74 +66,165 @@ public class PredicateSpec extends UriSpec { return new GatewayFilterSpec(this.routeBuilder, this.builder); } + /** + * A predicate to check if a request was made after a specific {@link ZonedDateTime} + * @param datetime requests would only be routed after this {@link ZonedDateTime} + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec after(ZonedDateTime datetime) { return asyncPredicate(getBean(AfterRoutePredicateFactory.class) .applyAsync(c-> c.setDatetime(datetime.toString()))); } + /** + * A predicate to check if a request was made before a specific {@link ZonedDateTime} + * @param datetime requests will only be routed before this {@link ZonedDateTime} + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec before(ZonedDateTime datetime) { return asyncPredicate(getBean(BeforeRoutePredicateFactory.class).applyAsync(c -> c.setDatetime(datetime.toString()))); } + /** + * A predicate to check if a request was made between two {@link ZonedDateTime}s + * @param datetime1 the request must have been made after this {@link ZonedDateTime} + * @param datetime2 the request must be made before this {@link ZonedDateTime} + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec between(ZonedDateTime datetime1, ZonedDateTime datetime2) { return asyncPredicate(getBean(BetweenRoutePredicateFactory.class) .applyAsync(c -> c.setDatetime1(datetime1.toString()).setDatetime2(datetime2.toString()))); } + /** + * A predicate that checks if a cookie matches a given regular expression + * @param name the name of the cookie + * @param regex the value of the cookies will be evaluated against this regular expression + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec cookie(String name, String regex) { return asyncPredicate(getBean(CookieRoutePredicateFactory.class) .applyAsync(c -> c.setName(name).setRegexp(regex))); } + /** + * A predicate that checks if a given header is present on the request + * @param header the header name to check + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec header(String header) { return asyncPredicate(getBean(HeaderRoutePredicateFactory.class) .applyAsync(c -> c.setHeader(header))); //TODO: default regexp } + /** + * A predicate that checks if a given headers has a value which matches a regular expression + * @param header the header name to check + * @param regex the regular expression to check against + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec header(String header, String regex) { return asyncPredicate(getBean(HeaderRoutePredicateFactory.class) .applyAsync(c -> c.setHeader(header).setRegexp(regex))); } + /** + * A predicate that checks if the {@code host} header matches a given pattern + * @param pattern the pattern to check against. The pattern is an Ant style pattern with {@code .} as a separator + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec host(String pattern) { return asyncPredicate(getBean(HostRoutePredicateFactory.class) .applyAsync(c-> c.setPattern(pattern))); } + /** + * A predicate that checks if the HTTP method matches + * @param method the name of the HTTP method + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec method(String method) { return asyncPredicate(getBean(MethodRoutePredicateFactory.class) .applyAsync(c -> c.setMethod(HttpMethod.resolve(method)))); } + /** + * A predicate that checks if the HTTP method matches + * @param method the HTTP method + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec method(HttpMethod method) { return asyncPredicate(getBean(MethodRoutePredicateFactory.class) .applyAsync(c -> c.setMethod(method))); } + /** + * A predicate that checks if the path of the request matches the given pattern + * @param pattern the pattern to check the path against. + * The pattern is a {@link org.springframework.util.PathMatcher} pattern + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec path(String pattern) { return asyncPredicate(getBean(PathRoutePredicateFactory.class) .applyAsync(c -> c.setPattern(pattern))); } + /** + * A predicate that checks the contents of the request body + * @param inClass the class to parse the body to + * @param predicate a predicate to check the contents of the body + * @param the type the body is parsed to + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec readBody(Class inClass, Predicate predicate) { return asyncPredicate(getBean(ReadBodyPredicateFactory.class) .applyAsync(c -> c.setPredicate(inClass, predicate))); } + /** + * A predicate that checks if a query parameter matches a regular expression + * @param param the query parameter name + * @param regex the regular expression to evaluate the query parameter value against + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec query(String param, String regex) { return asyncPredicate(getBean(QueryRoutePredicateFactory.class) .applyAsync(c -> c.setParam(param).setRegexp(regex))); } + /** + * A predicate that checks if a given query parameter is present in the request URL + * @param param the query parameter name + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec query(String param) { return asyncPredicate(getBean(QueryRoutePredicateFactory.class) .applyAsync(c -> c.setParam(param))); } + /** + * A predicate which checks the remote address of the request. + * By default the RemoteAddr Route Predicate Factory uses the remote address from the incoming request. + * This may not match the actual client IP address if Spring Cloud Gateway sits behind a proxy layer. + * Use {@link PredicateSpec#remoteAddr(RemoteAddressResolver, String...)} to customize the resolver. + * You can customize the way that the remote address is resolved by setting a custom RemoteAddressResolver. + + * @param addrs the remote address to verify. Should use CIDR-notation (IPv4 or IPv6) strings. + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec remoteAddr(String... addrs) { return remoteAddr(null, addrs); } + /** + * A predicate which checks the remote address of the request. Useful if Spring Cloud Gateway site behind a proxy + * layer. Spring Cloud Gateway comes with one non-default remote address resolver which is based off of the + * {@code X-Forwarded-For} header, {@link org.springframework.cloud.gateway.support.ipresolver.XForwardedRemoteAddressResolver}. + * See {@link org.springframework.cloud.gateway.support.ipresolver.XForwardedRemoteAddressResolver} for more information. + * @param resolver the {@link RemoteAddressResolver} to use to resolve the remote IP address against + * @param addrs the remote address to verify. Should use CIDR-notation (IPv4 or IPv6) strings. + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec remoteAddr(RemoteAddressResolver resolver, String... addrs) { return asyncPredicate(getBean(RemoteAddrRoutePredicateFactory.class).applyAsync(c -> { c.setSources(addrs); @@ -140,6 +234,12 @@ public class PredicateSpec extends UriSpec { })); } + /** + * A predicate which will select a route based on its assigned weight. The + * @param group the group the route belongs to + * @param weight the weight for the route + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec weight(String group, int weight) { return asyncPredicate(getBean(WeightRoutePredicateFactory.class) .applyAsync(c -> c.setGroup(group) @@ -147,6 +247,10 @@ public class PredicateSpec extends UriSpec { .setWeight(weight))); } + /** + * A predicate which is always true + * @return a {@link BooleanSpec} to be used to add logical operators + */ public BooleanSpec alwaysTrue() { return predicate(exchange -> true); } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/RouteLocatorBuilder.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/RouteLocatorBuilder.java index 2cf5c8b86..81d894c8d 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/RouteLocatorBuilder.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/RouteLocatorBuilder.java @@ -27,6 +27,9 @@ import org.springframework.context.ConfigurableApplicationContext; import reactor.core.publisher.Flux; +/** + * Used to build a {@link RouteLocator} + */ public class RouteLocatorBuilder { private ConfigurableApplicationContext context; @@ -35,10 +38,17 @@ public class RouteLocatorBuilder { this.context = context; } + /** + * Creates a new {@link Builder} + * @return a new {@link Builder} + */ public Builder routes() { return new Builder(context); } + /** + * A class that can be used to construct routes and return a {@link RouteLocator} + */ public static class Builder { private List routes = new ArrayList<>(); @@ -48,18 +58,33 @@ public class RouteLocatorBuilder { this.context = context; } + /** + * Creates a new {@link Route} + * @param id the unique id for the route + * @param fn a function which takes in a {@link PredicateSpec} and returns a {@link Route.AsyncBuilder} + * @return a {@link Builder} + */ public Builder route(String id, Function fn) { Route.AsyncBuilder routeBuilder = fn.apply(new RouteSpec(this).id(id)); add(routeBuilder); return this; } + /** + * Creates a new {@link Route} + * @param fn a function which takes in a {@link PredicateSpec} and returns a {@link Route.AsyncBuilder} + * @return a {@link Builder} + */ public Builder route(Function fn) { Route.AsyncBuilder routeBuilder = fn.apply(new RouteSpec(this).randomId()); add(routeBuilder); return this; } - + + /** + * Builds and returns a {@link RouteLocator} + * @return a {@link RouteLocator} + */ public RouteLocator build() { return () -> Flux.fromIterable(this.routes).map(routeBuilder -> routeBuilder.build()); } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/UriSpec.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/UriSpec.java index c253118a7..4a54db242 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/UriSpec.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/UriSpec.java @@ -20,6 +20,9 @@ import org.springframework.cloud.gateway.route.Route; import java.net.URI; +/** + * A specification to add a URI to a route. + */ public class UriSpec { final Route.AsyncBuilder routeBuilder; final RouteLocatorBuilder.Builder builder; @@ -29,10 +32,20 @@ public class UriSpec { this.builder = builder; } + /** + * Set the URI for the route. + * @param uri the URI for the route + * @return a {@link Route.AsyncBuilder} + */ public Route.AsyncBuilder uri(String uri) { return this.routeBuilder.uri(uri); } + /** + * Set the URI for the route. + * @param uri the URI for the route. + * @return a {@link Route.AsyncBuilder} + */ public Route.AsyncBuilder uri(URI uri) { return this.routeBuilder.uri(uri); }