diff --git a/docs/src/main/asciidoc/spring-cloud-gateway.adoc b/docs/src/main/asciidoc/spring-cloud-gateway.adoc index 8715209f..b7a3d1e8 100644 --- a/docs/src/main/asciidoc/spring-cloud-gateway.adoc +++ b/docs/src/main/asciidoc/spring-cloud-gateway.adoc @@ -43,6 +43,53 @@ All "`pre`" filter logic is executed. Then the proxy request is made. After the NOTE: URIs defined in routes without a port get default port values of 80 and 443 for the HTTP and HTTPS URIs, respectively. +== Configuring Route Predicate Factories and Gateway Filter Factories + +There are two ways to configure predicates and filters: shortcuts and fully expanded arguments. Most examples below use the shortcut way. + +The name and argument names will be listed as `code` in the first sentance or two of the each section. The arguments are typically listed in the order that would be needed for the shortcut configuration. + +=== Shortcut Configuration + +Shortcut configuration is recognized by the filter name, followed by an equals sign (`=`), followed by argument values separated by commas (`,`). + +.application.yml +[source,yaml] +---- +spring: + cloud: + gateway: + routes: + - id: after_route + uri: https://example.org + predicates: + - Cookie=mycookie,mycookievalue +---- + +The previous sample defines the `Cookie` Route Predicate Factory with two arguments, the cookie name, `mycookie` and the value to match `mycookievalue`. + +=== Fully Expanded Arguments + +Fully expanded arguments appear more like standard yaml configuration with name/value pairs. Typically, there will be a `name` key and an `args` key. The `args` key is a map of key value pairs to configure the predicate or filter. + +.application.yml +[source,yaml] +---- +spring: + cloud: + gateway: + routes: + - id: after_route + uri: https://example.org + predicates: + - name: Cookie + args: + name: mycookie + regexp: mycookievalue +---- + +This is the full configuration of the shortcut configuration of the `Cookie` predicate shown above. + [[gateway-request-predicates-factories]] == Route Predicate Factories @@ -53,7 +100,7 @@ You can combine multiple route predicate factories with logical `and` statements === The After Route Predicate Factory -The after route predicate factory takes one parameter, a datetime. +The `After` route predicate factory takes one parameter, a `datetime` (which is a java `ZonedDateTime`). This predicate matches requests that happen after the specified datetime. The following example configures an after route predicate: @@ -76,7 +123,7 @@ This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denv === The Before Route Predicate Factory -The before route predicate factory takes one parameter, a `datetime`. +The `Before` route predicate factory takes one parameter, a `datetime` (which is a java `ZonedDateTime`). This predicate matches requests that happen before the specified `datetime`. The following example configures a before route predicate: @@ -99,7 +146,8 @@ This route matches any request made before Jan 20, 2017 17:42 Mountain Time (Den === The Between Route Predicate Factory -The between route predicate factory takes two parameters, `datetime1` and `datetime2`. +The `Between` route predicate factory takes two parameters, `datetime1` and `datetime2` +which are java `ZonedDateTime` objects. This predicate matches requests that happen after `datetime1` and before `datetime2`. The `datetime2` parameter must be after `datetime1`. The following example configures a between route predicate: @@ -124,7 +172,7 @@ This could be useful for maintenance windows. === The Cookie Route Predicate Factory -The cookie route predicate factory takes two parameters, the cookie name and a regular expression. +The `Cookie` route predicate factory takes two parameters, the cookie `name` and a `regexp` (which is a Java regular expression). This predicate matches cookies that have the given name and whose values match the regular expression. The following example configures a cookie route predicate factory: @@ -147,7 +195,7 @@ This route matches requests that have a cookie named `chocolate` whose value mat === The Header Route Predicate Factory -The header route predicate factory takes two parameters, the header name and a regular expression. +The `Header` route predicate factory takes two parameters, the header `name` and a `regexp` (which is a Java regular expression). This predicate matches with a header that has the given name whose value matches the regular expression. The following example configures a header route predicate: @@ -170,7 +218,7 @@ This route matches if the request has a header named `X-Request-Id` whose value === The Host Route Predicate Factory -The host route predicate factory takes one parameter: a list of host name patterns. +The `Host` route predicate factory takes one parameter: a list of host name `patterns`. The pattern is an Ant-style pattern with `.` as the separator. This predicates matches the `Host` header that matches the pattern. The following example configures a host route predicate: @@ -200,7 +248,7 @@ Those values are then available for use by < { + + public MyRoutePredicateFactory() { + super(Config.class); + } + + @Override + public Predicate apply(Config config) { + // grab configuration from Config object + return exchange -> { + //grab the request + ServerHttpRequest request = exchange.getRequest(); + //take information from the request to see if it + //matches configuration. + return matches(config, request); + }; + } + + public static class Config { + //Put the configuration properties for your filter here + } + +} +---- === Writing Custom GatewayFilter Factories To write a `GatewayFilter`, you must implement `GatewayFilterFactory`. @@ -2387,16 +2485,16 @@ public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory { - //If you want to build a "pre" filter you need to manipulate the - //request before calling chain.filter - ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); - //use builder to manipulate the request - return chain.filter(exchange.mutate().request(request).build()); + //If you want to build a "pre" filter you need to manipulate the + //request before calling chain.filter + ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); + //use builder to manipulate the request + return chain.filter(exchange.mutate().request(request).build()); }; } public static class Config { - //Put the configuration properties for your filter here + //Put the configuration properties for your filter here } } @@ -2423,7 +2521,7 @@ public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory { Error error = new Error(it.toString()); - * error.printStackTrace(); throw error; }); - */ + // builder.blockingMethodCallback(it -> { + // Error error = new Error(it.toString()); + // error.printStackTrace(); + // throw error; + // }); + + // Uses Unsafe#park + builder.allowBlockingCallsInside("reactor.core.scheduler.SchedulerTask", + "dispose"); // Uses // ch.qos.logback.classic.spi.PackagingDataCalculator#getImplementationVersion @@ -69,6 +74,12 @@ public class CustomBlockHoundIntegration implements BlockHoundIntegration { "execute"); builder.allowBlockingCallsInside( "io.netty.util.concurrent.SingleThreadEventExecutor$6", "run"); + // builder.allowBlockingCallsInside("io.netty.util.concurrent.GlobalEventExecutor", + // "takeTask"); + // builder.allowBlockingCallsInside("io.netty.util.concurrent.GlobalEventExecutor", + // "addTask"); + builder.allowBlockingCallsInside( + "io.netty.util.concurrent.FastThreadLocalRunnable", "run"); // SECURITY RELATED