/** * A filter that will retry failed requests. * @param repeat a {@link Repeat} * @param retry a {@link Retry} * @return a {@link GatewayFilterSpec} that can be used to apply additional filters */ public GatewayFilterSpec retry(Repeat<ServerWebExchange> repeat, Retry<ServerWebExchange> retry) { return filter(getBean(RetryGatewayFilterFactory.class).apply(repeat, retry)); }
protected GatewayFilterSpec createGatewayFilterSpec() { return new GatewayFilterSpec(this.routeBuilder, this.builder); }
/** * Adds hystrix execution exception headers to fallback request. * Depends on @{code org.springframework.cloud::spring-cloud-starter-netflix-hystrix} being on the classpath, * {@see http://cloud.spring.io/spring-cloud-netflix/} * * @param configConsumer a {@link Consumer} which can be used to set up the names of the headers in the config. * If header names arguments are not provided, default values are used. * @return a {@link GatewayFilterSpec} that can be used to apply additional filters */ public GatewayFilterSpec fallbackHeaders(Consumer<FallbackHeadersGatewayFilterFactory.Config> configConsumer) { FallbackHeadersGatewayFilterFactory factory = getFallbackHeadersGatewayFilterFactory(); return filter(factory.apply(configConsumer)); }
.route(r -> r.host("**.abc.org").and().path("/anything/png") .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("X-TestHeader", "foobar")) .uri(uri) .and().readBody(String.class, s -> s.trim().equalsIgnoreCase("hi")) .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("X-TestHeader", "read_body_pred") ).uri(uri) .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("X-TestHeader", "rewrite_request") .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> { return Mono.just(new Hello(s.toUpperCase())); .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("X-TestHeader", "rewrite_request_upper") .modifyRequestBody(String.class, String.class, (exchange, s) -> { return Mono.just(s.toUpperCase()+s.toUpperCase()); .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("X-TestHeader", "rewrite_response_upper") .modifyResponseBody(String.class, String.class, (exchange, s) -> { return Mono.just(s.toUpperCase());
}).filters(f -> f.addResponseHeader("X-TestHeader", "read_body_pred")) .uri("http://httpbin.org") ).route("modify_request_body", r -> r.path("/modify/test2") .filters(f -> f.addRequestHeader("X-TestHeader", "rewrite_request_upper") .modifyRequestBody(String.class, String.class, (exchange, s) -> Mono.just(s.toUpperCase())).modifyResponseBody(String.class, String.class, (exchange, s) -> Mono.just("12345")) ).uri("http://localhost:8005/body") .filters(f -> f.requestHeaderToRequestUri("X-Next-Url")) .uri("http://baidu.com")) .route(r -> r.path("/test6/**").and().query("url") .filters(f -> f.changeRequestUri(e -> Optional.of(URI.create( e.getRequest().getQueryParams().getFirst("url"))))) .uri("http://example.com")) .route(r -> r.path("/customer/**") .filters(f -> f.stripPrefix(2) .filter(new RateLimitByIpGatewayFilter(10, 1, Duration.ofSeconds(1)))) .uri("http://baidu.com") .order(0)
return builder.routes() .route("fortune_api", p -> p.path("/v2/fortune").and().host("api.monolith.com") .filters(f -> f.setPath("/fortune") .requestRateLimiter().rateLimiter(RedisRateLimiter.class, c -> c.setBurstCapacity(1).setReplenishRate(1)) .configure(c -> c.setKeyResolver(exchange -> Mono.just(exchange.getRequest().getHeaders().getFirst("X-Fortune-Key"))))) .uri("lb://fortune")) .route("fortune_rewrite", p -> p.path("/service/randomfortune") .filters(f -> f.setPath("/fortune") .hystrix(c -> c.setFallbackUri("forward:/defaultfortune"))) .uri("lb://fortune")) .route("hello_rewrite", p -> p.path("/service/hello/**") .filters(f -> f.filter((exchange, chain) -> { String name = exchange.getRequest().getQueryParams().getFirst("name"); String path = "/hello/"+name; .uri("lb://hello")) .route("index", p -> p.path("/") .filters(f -> f.setPath("/index.html")) .uri("lb://ui")) .route("ui", p -> p.path("/").or().path("/css/**").or().path("/js/**")
@Bean public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { // @formatter:off return builder.routes() .route( r -> r.path("/fluent/customer/**") .filters(f -> f.stripPrefix(2) .filter(new ElapsedFilter()) .addResponseHeader("X-Response-Default-Foo", "Default-Bar")) .uri("lb://CONSUMER") .order(0) .id("fluent_customer_service") ) .route(r -> r.path("/throttle/customer/**") .filters(f -> f.stripPrefix(2) .filter(new RateLimitByIpGatewayFilter(10, 1, Duration.ofSeconds(1))) .filter(rateLimitByCpuGatewayFilter)) .uri("lb://CONSUMER") .order(0) .id("throttle_customer_service") ) .build(); // @formatter:on }
/** * Applies the filter to the route. * @param gatewayFilter the filter to apply * @return a {@link GatewayFilterSpec} that can be used to apply additional filters */ public GatewayFilterSpec filter(GatewayFilter gatewayFilter) { if (gatewayFilter instanceof Ordered) { this.routeBuilder.filter(gatewayFilter); return this; } return this.filter(gatewayFilter, 0); }
private void testFilter(Class<? extends GatewayFilter> type, GatewayFilter gatewayFilter, int order) { ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class); Route.AsyncBuilder routeBuilder = Route.async() .id("123") .uri("abc:123") .predicate(exchange -> true); RouteLocatorBuilder.Builder routes = new RouteLocatorBuilder(context).routes(); GatewayFilterSpec spec = new GatewayFilterSpec(routeBuilder, routes); spec.filter(gatewayFilter); Route route = routeBuilder.build(); assertThat(route.getFilters()).hasSize(1); assertFilter(route.getFilters().get(0), type, order); }
@Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("non_standard_header_route", r -> r.path("/get-image/**") .filters(f -> f .addRequestHeader(HttpHeaders.HOST, "www.addrequestparameter.org") .stripPrefix(1) ) .uri("http://localhost:" + port + "/get")) .route("internal_route", r -> r.path("/get/**") .filters(f -> f.prefixPath("/httpbin")) .uri(uri)) .build(); }
@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { String httpUri = "http://httpbin.org:80"; return builder.routes() .route(p -> p .path("/get") .filters(f -> f.addRequestHeader("Hello", "World")) .uri(httpUri)) .route(p -> p .host("*.hystrix.com") .filters(f -> f .hystrix(config -> config .setName("mycmd") .setFallbackUri("forward:/fallback"))) .uri(httpUri)) .build(); } // end::route-locator[]
@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { //@formatter:off return builder.routes() .route("path_route", r -> r.path("/get") .uri("http://httpbin.org")) .route("host_route", r -> r.host("*.myhost.org") .uri("http://httpbin.org")) .route("rewrite_route", r -> r.host("*.rewrite.org") .filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}")) .uri("http://httpbin.org")) .route("hystrix_route", r -> r.host("*.hystrix.org") .filters(f -> f.hystrix(c -> c.setName("slowcmd"))) .uri("http://httpbin.org")) .route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org") .filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback"))) .uri("http://httpbin.org")) .route("limit_route", r -> r .host("*.limited.org").and().path("/anything/**") .filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter()))) .uri("http://httpbin.org")) .route("websocket_route", r -> r.path("/echo") .uri("ws://localhost:9000")) .build(); //@formatter:on }
@Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes().route("test_set_request_header", r -> r.order(-1) .host("**.setrequestheader.org") .filters(f -> f.prefixPath("/httpbin") .addRequestHeader("X-Req-Foo", "First") .setRequestHeader("X-Req-Foo", "Second")) .uri(uri)) .build(); } }
@Test public void testASetOfRoutes() { RouteLocator routeLocator = this.routeLocatorBuilder.routes() .route("test1", r -> r.host("*.somehost.org").and().path("/somepath") .filters(f -> f.addRequestHeader("header1", "header-value-1")) .uri("http://someuri")) .route("test2", r -> r.host("*.somehost2.org") .filters(f -> f.addResponseHeader("header-response-1", "header-response-1")) .uri("https://httpbin.org:9090")) .build(); StepVerifier.create(routeLocator.getRoutes()) .expectNextMatches( r -> r.getId().equals("test1") && r.getFilters().size() == 1 && r.getUri().equals(URI.create("http://someuri:80"))) .expectNextMatches( r -> r.getId().equals("test2") && r.getFilters().size() == 1 && r.getUri() .equals(URI.create("https://httpbin.org:9090"))) .expectComplete().verify(); }
@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.path("/myapi/**") .filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(myRateLimiter())) .prefixPath("/downstream")) .uri("http://localhost:"+port)) .build(); }
@Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("add_response_param_java_test", r -> r.path("/get").and().host("**.addresponseparamjava.org") .filters(f -> f.prefixPath("/httpbin") .addResponseHeader("example", "myresponsevalue")) .uri(uri)) .build(); } }
@Bean public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("hystrix_java", r -> r.host("**.hystrixjava.org") .filters(f -> f.prefixPath("/httpbin") .hystrix(config -> config.setFallbackUri("forward:/fallbackcontroller2"))) .uri(uri)) .route("hystrix_connection_failure", r -> r.host("**.hystrixconnectfail.org") .filters(f -> f.prefixPath("/httpbin") .hystrix(config -> { })) .uri("lb:badservice")) /* * This is a route encapsulated in a hystrix command that is ready to wait * for a response far longer than the underpinning WebClient would. */ .route("hystrix_response_stall", r -> r.host("**.hystrixresponsestall.org") .filters(f -> f.prefixPath("/httpbin") .hystrix(config -> config.setName("stalling-command"))) .uri(uri)) .build(); }
@Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("add_request_header_java_test", r -> r.path("/headers").and().host("**.addrequestheaderjava.org") .filters(f -> f.prefixPath("/httpbin").addRequestHeader("X-Request-Acme", "ValueB")) .uri(uri)) .build(); } }
@Bean public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.host("**.changeuri.org").and().header("X-Next-Url") .filters(f -> f.requestHeaderToRequestUri("X-Next-Url")) .uri("http://example.com")) .route(r -> r.host("**.changeuri.org").and().query("url") .filters(f -> f.changeRequestUri(e -> Optional.of(URI.create( e.getRequest().getQueryParams().getFirst("url"))))) .uri("http://example.com")) .build(); } }
@Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("custom_redis_rate_limiter", r -> r.path("/custom") .filters(f -> f.requestRateLimiter() .rateLimiter(RedisRateLimiter.class, rl -> rl.setBurstCapacity(40).setReplenishRate(20)) .and()) .uri("http://localhost")) .route("alt_custom_redis_rate_limiter", r -> r.path("/custom") .filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(myRateLimiter()))) .uri("http://localhost")) .build(); }