From 539f0a7d1ee93408f31a313fe989a80a999e58b4 Mon Sep 17 00:00:00 2001 From: Ignacio Lozano Date: Thu, 23 Feb 2023 12:38:51 +0100 Subject: [PATCH 1/3] Fix NPE when autoconfigured WebTestClient is used When `management.server.port` != `server.port` and test is using the autoconfigured WebTestClient, a NPE is raised by `RoutePredicateHandlerMapping` [related gh-2870] Fixes gh-2872 --- .../handler/RoutePredicateHandlerMapping.java | 1 + ...hAutoconfiguredClientIntegrationTests.java | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java index 54e8735c..0f813c44 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java @@ -77,6 +77,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping { protected Mono getHandlerInternal(ServerWebExchange exchange) { // don't handle requests on management port if set and different than server port if (this.managementPortType == DIFFERENT && this.managementPort != null + && exchange.getRequest().getLocalAddress() != null && exchange.getRequest().getLocalAddress().getPort() == this.managementPort) { return Mono.empty(); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java new file mode 100644 index 00000000..a6428241 --- /dev/null +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.handler; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +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.util.TestSocketUtils; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@AutoConfigureWebTestClient +public class RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests { + + @Autowired + WebTestClient webTestClient; + + @BeforeAll + static void beforeClass() { + int managementPort = TestSocketUtils.findAvailableTcpPort(); + System.setProperty("management.server.port", String.valueOf(managementPort)); + } + + @AfterAll + static void afterClass() { + System.clearProperty("management.server.port"); + } + + @Test + void shouldReturnOk() { + this.webTestClient.get().uri("/get").exchange().expectStatus().isOk(); + } + + @EnableAutoConfiguration + @SpringBootConfiguration + @Import(BaseWebClientTests.DefaultTestConfig.class) + @RestController + public static class TestConfig { + + @Value("${test.uri:http://httpbin.org:80}") + String uri; + + @GetMapping("/get") + String get() { + return "hello"; + } + + @Bean + RouteLocator testRoutes(RouteLocatorBuilder builder) { + return builder.routes().route(predicateSpec -> predicateSpec.path("/get").uri(uri)).build(); + } + + } + +} From a0e32e9d7ad1bfc7950738543b2e44214927b49b Mon Sep 17 00:00:00 2001 From: spencergibb Date: Thu, 23 Feb 2023 13:18:14 -0500 Subject: [PATCH 2/3] =?UTF-8?q?Updates=20to=20use=20SocketUtils=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...andlerMappingWithAutoconfiguredClientIntegrationTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java index a6428241..1727ee8e 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java @@ -31,8 +31,8 @@ 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.util.TestSocketUtils; import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.SocketUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -47,7 +47,7 @@ public class RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTest @BeforeAll static void beforeClass() { - int managementPort = TestSocketUtils.findAvailableTcpPort(); + int managementPort = SocketUtils.findAvailableTcpPort(); System.setProperty("management.server.port", String.valueOf(managementPort)); } From 671b4165c3772af1dea6abf775daaee7158cf521 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Thu, 23 Feb 2023 13:40:52 -0500 Subject: [PATCH 3/3] Polish gh-2872 Fixes for gateway routes on management port. Updates the test to fail if NPE check isn't done. --- ...erMappingWithAutoconfiguredClientIntegrationTests.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java index 1727ee8e..c0b6330a 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTests.java @@ -33,7 +33,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -70,14 +69,9 @@ public class RoutePredicateHandlerMappingWithAutoconfiguredClientIntegrationTest @Value("${test.uri:http://httpbin.org:80}") String uri; - @GetMapping("/get") - String get() { - return "hello"; - } - @Bean RouteLocator testRoutes(RouteLocatorBuilder builder) { - return builder.routes().route(predicateSpec -> predicateSpec.path("/get").uri(uri)).build(); + return builder.routes().route(r -> r.path("/get").filters(f -> f.prefixPath("/httpbin")).uri(uri)).build(); } }