diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java index 9c15ecfe7..3c0f3f54f 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java @@ -122,7 +122,11 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor RestTemplate restTemplate; if (restTemplateBuilderSupplier != null && restTemplateBuilderSupplier.get() != null) { - restTemplate = restTemplateBuilderSupplier.get().requestFactory(() -> requestFactory).build(); + // Avoid using RestTemplateBuilder.requestFactory(() -> requestFactory) + // when we have a concrete type, the reflective builder can throw errors if + // there is custom configuration (ie Redirects.DONT_FOLLOW) gh-4423 + restTemplate = restTemplateBuilderSupplier.get().build(); + restTemplate.setRequestFactory(requestFactory); } else { restTemplate = new RestTemplate(requestFactory); diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTests.java index 37aa572c3..dbad69d55 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTests.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactoryTests.java @@ -16,12 +16,22 @@ package org.springframework.cloud.netflix.eureka.http; +import java.util.Optional; + import com.netflix.discovery.shared.resolver.DefaultEndpoint; import com.netflix.discovery.shared.transport.EurekaHttpClient; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.client.InterceptingClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -58,6 +68,24 @@ class RestTemplateTransportClientFactoryTests { assertThat(eurekaHttpClient).isInstanceOf(RestTemplateEurekaHttpClient.class); } + @Test + void testRequestFactorySetWithRestTemplateBuilderSupplier() { + // Gateway Server WebMVC sets Redirects.DONT_FOLLOW, gh-4423 + RestTemplateBuilder builder = new RestTemplateBuilder() + .requestFactorySettings(new ClientHttpRequestFactorySettings(Redirects.DONT_FOLLOW, null, null, null)); + transportClientFactory = new RestTemplateTransportClientFactory(Optional.empty(), Optional.empty(), + new DefaultEurekaClientHttpRequestFactorySupplier(), () -> builder); + EurekaHttpClient eurekaHttpClient = transportClientFactory + .newClient(new DefaultEndpoint("http://localhost:8761")); + RestTemplateEurekaHttpClient restTemplateEurekaHttpClient = (RestTemplateEurekaHttpClient) eurekaHttpClient; + RestTemplate restTemplate = restTemplateEurekaHttpClient.getRestTemplate(); + ClientHttpRequestFactory requestFactory = restTemplate.getRequestFactory(); + if (requestFactory instanceof InterceptingClientHttpRequestFactory interceptingClientHttpRequestFactory) { + requestFactory = interceptingClientHttpRequestFactory.getDelegate(); + } + assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class); + } + @AfterEach void shutdown() { transportClientFactory.shutdown();