From fdef92b3b77f57d0cf2d327bd9d73eac2ae220ee Mon Sep 17 00:00:00 2001 From: Toshiaki Maki Date: Fri, 6 Jul 2018 04:46:11 +0900 Subject: [PATCH] Autoconfigure CloudFoundryRouteServiceRoutePredicateFactory and add cloudFoundryRouteService in DSL (#294) --- .../config/GatewayAutoConfiguration.java | 6 ++ .../gateway/route/builder/PredicateSpec.java | 7 ++ ...RoutePredicateFactoryIntegrationTests.java | 76 +++++++++++++++++++ .../src/test/resources/application.yml | 8 ++ 4 files changed, 97 insertions(+) create mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests.java diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index b936e6203..0f14ac9d1 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -89,6 +89,7 @@ import org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping; import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory; +import org.springframework.cloud.gateway.handler.predicate.CloudFoundryRouteServiceRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory; @@ -432,6 +433,11 @@ public class GatewayAutoConfiguration { return new WeightRoutePredicateFactory(); } + @Bean + public CloudFoundryRouteServiceRoutePredicateFactory cloudFoundryRouteServiceRoutePredicateFactory() { + return new CloudFoundryRouteServiceRoutePredicateFactory(); + } + // GatewayFilter Factory beans @Bean 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 dc805737c..993d849a0 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 @@ -23,6 +23,7 @@ import org.springframework.cloud.gateway.handler.AsyncPredicate; import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.BeforeRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.BetweenRoutePredicateFactory; +import org.springframework.cloud.gateway.handler.predicate.CloudFoundryRouteServiceRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.HostRoutePredicateFactory; @@ -248,6 +249,12 @@ public class PredicateSpec extends UriSpec { .setWeight(weight))); } + public BooleanSpec cloudFoundryRouteService() { + return predicate( + getBean(CloudFoundryRouteServiceRoutePredicateFactory.class).apply(c -> { + })); + } + /** * A predicate which is always true * @return a {@link BooleanSpec} to be used to add logical operators diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests.java new file mode 100644 index 000000000..14701593d --- /dev/null +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests.java @@ -0,0 +1,76 @@ +package org.springframework.cloud.gateway.handler.predicate; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.cloud.gateway.test.BaseWebClientTests; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.fasterxml.jackson.databind.JsonNode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +/** + * @author Toshiaki Maki + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT) +@DirtiesContext +public class CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests + extends BaseWebClientTests { + @LocalServerPort + int port; + + @Test + public void predicateWorkWithProperties() { + testClient.get().uri("/").header("Host", "props.routeservice.example.com") + .header("X-CF-Forwarded-Url", + "http://localhost:" + port + "/actuator/health") + .header("X-CF-Proxy-Signature", "foo") + .header("X-CF-Proxy-Metadata", "bar").exchange() + .expectBody(JsonNode.class) + .consumeWith(r -> assertThat(r.getResponseBody().has("status")).isTrue()); + } + + @Test + public void predicateWillNotWorkUnlessHeadersAreEnough() { + testClient.get().uri("/").header("Host", "props.routeservice.example.com") + .header("X-CF-Forwarded-Url", + "http://localhost:" + port + "/actuator/health") + .header("X-CF-Proxy-Metadata", "bar").exchange().expectStatus().isOk() + .expectHeader().valueEquals(ROUTE_ID_HEADER, "default_path_to_httpbin"); + } + + @Test + public void predicateWorkWithDsl() { + testClient.get().uri("/").header("Host", "dsl.routeservice.example.com") + .header("X-CF-Forwarded-Url", + "http://localhost:" + port + "/actuator/health") + .header("X-CF-Proxy-Signature", "foo") + .header("X-CF-Proxy-Metadata", "bar").exchange() + .expectBody(JsonNode.class) + .consumeWith(r -> assertThat(r.getResponseBody().has("status")).isTrue()); + } + + @EnableAutoConfiguration + @SpringBootConfiguration + @Import(DefaultTestConfig.class) + public static class TestConfig { + @Bean + public RouteLocator routeLocator(RouteLocatorBuilder builder) { + return builder.routes().route(r -> r.cloudFoundryRouteService().and() + .header("Host", "dsl.routeservice.example.com") + .filters(f -> f.requestHeaderToRequestUri("X-CF-Forwarded-Url")) + .uri("http://example.com")).build(); + } + } +} \ No newline at end of file diff --git a/spring-cloud-gateway-core/src/test/resources/application.yml b/spring-cloud-gateway-core/src/test/resources/application.yml index dc2bb2ebc..2db2461ee 100644 --- a/spring-cloud-gateway-core/src/test/resources/application.yml +++ b/spring-cloud-gateway-core/src/test/resources/application.yml @@ -253,6 +253,14 @@ spring: filters: - RequestHeaderToRequestUri=X-CF-Forwarded-Url + # ===================================== + - id: cloudfoundry_routeservice_test + uri: ${test.uri} + predicates: + - CloudFoundryRouteService= + filters: + - RequestHeaderToRequestUri=X-CF-Forwarded-Url + # ===================================== - id: default_path_to_httpbin uri: ${test.uri}