diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc index 42688ad6..cef32584 100644 --- a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc +++ b/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc @@ -559,7 +559,7 @@ Since `4.0.0`, Spring Cloud LoadBalancer supports Spring AOT transformations and Since `5.0.0`, Spring Cloud LoadBalancer supports https://docs.spring.io/spring-framework/reference/7.0-SNAPSHOT/integration/rest-clients.html#rest-http-interface[Spring Interface Clients] AutoConfiguration through the `LoadBalancerRestClientHttpServiceGroupConfigurer` and `LoadBalancerWebClientHttpServiceGroupConfigurer`. For each Interface Client group, if the group `baseUrl` (defined under the -`spring.http.client.service.group.[groupName].base-url` property) is `null`, a `serviceId`-based URL for load-balancing is set up as the `baseUrl`, with `serviceId` resolved from the Interface Client `groupName`. The default scheme for the load-balanced `baseUrl` (`http`, by default) can be set through the `spring.cloud.loadbalancer.interface-clients.default-scheme` property. +`spring.http.client.service.group.[groupName].base-url` property) is `null`, a `serviceId`-based URL for load-balancing is set up as the `baseUrl`, with `serviceId` resolved from the Interface Client `groupName`. If the group `baseUrl` is `null` or it is already a `serviceId`-based URL, a `DeferringLoadBalancerInterceptor` instance is picked from the application context for blocking scenarios, and a `DeferringLoadBalancerExchangeFilterFunction` instance for reactive scenarios, and is added to the group's `RestClient.Builder` or `WebClient.Builder` if available, allowing for the requests to be load-balanced. diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java index 35ea42c4..a682c4b0 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java @@ -116,10 +116,8 @@ public class LoadBalancerAutoConfiguration { @ConditionalOnMissingBean(LoadBalancerRestClientHttpServiceGroupConfigurer.class) LoadBalancerRestClientHttpServiceGroupConfigurer loadBalancerRestClientHttpServiceGroupConfigurer( ObjectProvider loadBalancerInterceptorProvider, - HttpClientServiceProperties properties, - ReactiveLoadBalancer.Factory loadBalancerFactory) { - return new LoadBalancerRestClientHttpServiceGroupConfigurer(loadBalancerInterceptorProvider, properties, - loadBalancerFactory); + HttpClientServiceProperties properties) { + return new LoadBalancerRestClientHttpServiceGroupConfigurer(loadBalancerInterceptorProvider, properties); } } diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java index fc3b998a..4057de50 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java @@ -105,12 +105,6 @@ public class LoadBalancerProperties { */ private Stats stats = new Stats(); - /** - * Properties for load-balanced interface clients. LoadBalancer serviceId will be used - * as interface clients group name. - */ - private InterfaceClients interfaceClients = new InterfaceClients(); - public HealthCheck getHealthCheck() { return healthCheck; } @@ -183,14 +177,6 @@ public class LoadBalancerProperties { this.stats = stats; } - public InterfaceClients getInterfaceClients() { - return interfaceClients; - } - - public void setInterfaceClients(InterfaceClients interfaceClients) { - this.interfaceClients = interfaceClients; - } - public static class StickySession { /** @@ -585,22 +571,4 @@ public class LoadBalancerProperties { } - public static class InterfaceClients { - - /** - * Default scheme to use when building interface clients baseUrl. If a baseUrl is - * provided by the user, this will be ignored. - */ - private String defaultScheme = "http"; - - public String getDefaultScheme() { - return defaultScheme; - } - - public void setDefaultScheme(String defaultScheme) { - this.defaultScheme = defaultScheme; - } - - } - } diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurer.java index a083da5c..672c16bd 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurer.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurer.java @@ -22,8 +22,6 @@ import org.jspecify.annotations.NonNull; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; import org.springframework.util.function.SingletonSupplier; import org.springframework.web.client.RestClient; import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; @@ -51,20 +49,16 @@ public class LoadBalancerRestClientHttpServiceGroupConfigurer implements RestCli // Make sure Boot's configurers run before private static final int ORDER = 10; - private final ReactiveLoadBalancer.Factory loadBalancerClientFactory; - private final SingletonSupplier loadBalancerInterceptorSupplier; private final HttpClientServiceProperties clientServiceProperties; public LoadBalancerRestClientHttpServiceGroupConfigurer( ObjectProvider loadBalancerInterceptorProvider, - HttpClientServiceProperties clientServiceProperties, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { + HttpClientServiceProperties clientServiceProperties) { this.loadBalancerInterceptorSupplier = SingletonSupplier .ofNullable(loadBalancerInterceptorProvider::getIfAvailable); this.clientServiceProperties = clientServiceProperties; - this.loadBalancerClientFactory = loadBalancerClientFactory; } @Override @@ -95,9 +89,7 @@ public class LoadBalancerRestClientHttpServiceGroupConfigurer implements RestCli } private URI constructBaseUrl(String groupName) { - LoadBalancerProperties loadBalancerProperties = loadBalancerClientFactory.getProperties(groupName); - return constructInterfaceClientsBaseUrl(groupName, - loadBalancerProperties.getInterfaceClients().getDefaultScheme()); + return constructInterfaceClientsBaseUrl(groupName); } } diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java index 9f687b39..ace12bd1 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java @@ -121,8 +121,8 @@ public final class LoadBalancerUriTools { return originalOrDefault; } - public static URI constructInterfaceClientsBaseUrl(String groupName, String defaultScheme) { - return UriComponentsBuilder.newInstance().scheme(defaultScheme).host(groupName).encode().build().toUri(); + public static URI constructInterfaceClientsBaseUrl(String groupName) { + return UriComponentsBuilder.newInstance().scheme(DEFAULT_SCHEME).host(groupName).encode().build().toUri(); } public static boolean isServiceIdUrl(String baseUrlString, String serviceId) { diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java index 1fc4abc7..58913842 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java @@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.http.client.reactive.service.ReactiveHttpClientServiceProperties; -import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.context.ApplicationContext; @@ -74,10 +73,8 @@ public class LoadBalancerBeanPostProcessorAutoConfiguration { @ConditionalOnMissingBean(LoadBalancerWebClientHttpServiceGroupConfigurer.class) LoadBalancerWebClientHttpServiceGroupConfigurer loadBalancerWebClientHttpServiceGroupConfigurer( ObjectProvider> deferringExchangeFilterFunction, - ReactiveHttpClientServiceProperties properties, - ReactiveLoadBalancer.Factory loadBalancerFactory) { - return new LoadBalancerWebClientHttpServiceGroupConfigurer(deferringExchangeFilterFunction, properties, - loadBalancerFactory); + ReactiveHttpClientServiceProperties properties) { + return new LoadBalancerWebClientHttpServiceGroupConfigurer(deferringExchangeFilterFunction, properties); } } diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurer.java index 1c02d85e..cdd51ae2 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurer.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurer.java @@ -21,8 +21,6 @@ import java.net.URI; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.http.client.reactive.service.ReactiveHttpClientServiceProperties; import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools; import org.springframework.util.function.SingletonSupplier; import org.springframework.web.reactive.function.client.WebClient; @@ -51,20 +49,16 @@ public class LoadBalancerWebClientHttpServiceGroupConfigurer implements WebClien // Make sure Boot's configurers run before private static final int ORDER = 10; - private final ReactiveLoadBalancer.Factory loadBalancerClientFactory; - private final SingletonSupplier> loadBalancerFilterFunctionSupplier; private final ReactiveHttpClientServiceProperties clientServiceProperties; public LoadBalancerWebClientHttpServiceGroupConfigurer( ObjectProvider> exchangeFilterFunctionProvider, - ReactiveHttpClientServiceProperties clientServiceProperties, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { + ReactiveHttpClientServiceProperties clientServiceProperties) { this.loadBalancerFilterFunctionSupplier = SingletonSupplier .ofNullable(exchangeFilterFunctionProvider::getIfAvailable); this.clientServiceProperties = clientServiceProperties; - this.loadBalancerClientFactory = loadBalancerClientFactory; } @Override @@ -96,9 +90,7 @@ public class LoadBalancerWebClientHttpServiceGroupConfigurer implements WebClien } private URI constructBaseUrl(String groupName) { - LoadBalancerProperties loadBalancerProperties = loadBalancerClientFactory.getProperties(groupName); - return constructInterfaceClientsBaseUrl(groupName, - loadBalancerProperties.getInterfaceClients().getDefaultScheme()); + return constructInterfaceClientsBaseUrl(groupName); } } diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurerTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurerTests.java index ffe133da..8d6ba31a 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurerTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRestClientHttpServiceGroupConfigurerTests.java @@ -28,8 +28,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties; import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties.Group; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; import org.springframework.web.client.RestClient; import org.springframework.web.service.invoker.HttpServiceProxyFactory; import org.springframework.web.service.registry.HttpServiceGroup; @@ -37,20 +35,17 @@ import org.springframework.web.service.registry.HttpServiceGroupConfigurer; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Tests for {@link LoadBalancerRestClientHttpServiceGroupConfigurer} * * @author Olga Maciaszek-Sharma */ -@SuppressWarnings({ "unchecked", "removal" }) +@SuppressWarnings({ "removal" }) class LoadBalancerRestClientHttpServiceGroupConfigurerTests { private static final String GROUP_NAME = "testService"; - private ReactiveLoadBalancer.Factory loadBalancerClientFactory; - private HttpClientServiceProperties clientServiceProperties; private ObjectProvider interceptorProvider; @@ -59,16 +54,13 @@ class LoadBalancerRestClientHttpServiceGroupConfigurerTests { void setup() { DeferringLoadBalancerInterceptor interceptor = mock(DeferringLoadBalancerInterceptor.class); interceptorProvider = new SimpleObjectProvider<>(interceptor); - loadBalancerClientFactory = mock(ReactiveLoadBalancer.Factory.class); clientServiceProperties = new HttpClientServiceProperties(); - LoadBalancerProperties properties = new LoadBalancerProperties(); - when(loadBalancerClientFactory.getProperties(GROUP_NAME)).thenReturn(properties); } @Test void shouldAddInterceptorWhenBaseUrlIsNotSet() { LoadBalancerRestClientHttpServiceGroupConfigurer configurer = new LoadBalancerRestClientHttpServiceGroupConfigurer( - interceptorProvider, clientServiceProperties, loadBalancerClientFactory); + interceptorProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups); @@ -85,7 +77,7 @@ class LoadBalancerRestClientHttpServiceGroupConfigurerTests { group.setBaseUrl("https://" + GROUP_NAME + "/path"); clientServiceProperties.getGroup().put(GROUP_NAME, group); LoadBalancerRestClientHttpServiceGroupConfigurer configurer = new LoadBalancerRestClientHttpServiceGroupConfigurer( - interceptorProvider, clientServiceProperties, loadBalancerClientFactory); + interceptorProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups); @@ -102,7 +94,7 @@ class LoadBalancerRestClientHttpServiceGroupConfigurerTests { group.setBaseUrl("https://some-other-service/path"); clientServiceProperties.getGroup().put(GROUP_NAME, group); LoadBalancerRestClientHttpServiceGroupConfigurer configurer = new LoadBalancerRestClientHttpServiceGroupConfigurer( - interceptorProvider, clientServiceProperties, loadBalancerClientFactory); + interceptorProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups); diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurerTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurerTests.java index c91c12a3..5916a7bd 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurerTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientHttpServiceGroupConfigurerTests.java @@ -27,8 +27,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.http.client.reactive.service.ReactiveHttpClientServiceProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.SimpleObjectProvider; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.service.invoker.HttpServiceProxyFactory; @@ -37,7 +35,6 @@ import org.springframework.web.service.registry.HttpServiceGroupConfigurer; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Tests for {@link LoadBalancerWebClientHttpServiceGroupConfigurer} @@ -49,8 +46,6 @@ class LoadBalancerWebClientHttpServiceGroupConfigurerTests { private static final String GROUP_NAME = "testService"; - private ReactiveLoadBalancer.Factory loadBalancerClientFactory; - private ReactiveHttpClientServiceProperties clientServiceProperties; private ObjectProvider> exchangeFilterFunctionProvider; @@ -60,16 +55,13 @@ class LoadBalancerWebClientHttpServiceGroupConfigurerTests { DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction = mock( DeferringLoadBalancerExchangeFilterFunction.class); exchangeFilterFunctionProvider = new SimpleObjectProvider<>(exchangeFilterFunction); - loadBalancerClientFactory = mock(ReactiveLoadBalancer.Factory.class); clientServiceProperties = new ReactiveHttpClientServiceProperties(); - LoadBalancerProperties properties = new LoadBalancerProperties(); - when(loadBalancerClientFactory.getProperties(GROUP_NAME)).thenReturn(properties); } @Test void shouldAddInterceptorWhenBaseUrlIsNotSet() { LoadBalancerWebClientHttpServiceGroupConfigurer configurer = new LoadBalancerWebClientHttpServiceGroupConfigurer( - exchangeFilterFunctionProvider, clientServiceProperties, loadBalancerClientFactory); + exchangeFilterFunctionProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups); @@ -86,7 +78,7 @@ class LoadBalancerWebClientHttpServiceGroupConfigurerTests { group.setBaseUrl("https://" + GROUP_NAME + "/path"); clientServiceProperties.getGroup().put(GROUP_NAME, group); LoadBalancerWebClientHttpServiceGroupConfigurer configurer = new LoadBalancerWebClientHttpServiceGroupConfigurer( - exchangeFilterFunctionProvider, clientServiceProperties, loadBalancerClientFactory); + exchangeFilterFunctionProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups); @@ -103,7 +95,7 @@ class LoadBalancerWebClientHttpServiceGroupConfigurerTests { group.setBaseUrl("https://some-other-service/path"); clientServiceProperties.getGroup().put(GROUP_NAME, group); LoadBalancerWebClientHttpServiceGroupConfigurer configurer = new LoadBalancerWebClientHttpServiceGroupConfigurer( - exchangeFilterFunctionProvider, clientServiceProperties, loadBalancerClientFactory); + exchangeFilterFunctionProvider, clientServiceProperties); TestGroups groups = new TestGroups(); configurer.configureGroups(groups);