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 05335a7d..68f78637 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 @@ -30,7 +30,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.interfaceclients.http.HttpInterfaceGroupsProperties; +import org.springframework.boot.autoconfigure.http.client.service.HttpClientServiceProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; @@ -112,12 +112,14 @@ public class LoadBalancerAutoConfiguration { } @Bean - @ConditionalOnBean(HttpInterfaceGroupsProperties.class) + @ConditionalOnBean({ HttpClientServiceProperties.class, ReactiveLoadBalancer.Factory.class }) @ConditionalOnMissingBean(LoadBalancerRestClientHttpServiceGroupConfigurer.class) LoadBalancerRestClientHttpServiceGroupConfigurer loadBalancerRestClientHttpServiceGroupConfigurer( ObjectProvider loadBalancerInterceptorProvider, - HttpInterfaceGroupsProperties properties) { - return new LoadBalancerRestClientHttpServiceGroupConfigurer(loadBalancerInterceptorProvider, properties); + HttpClientServiceProperties properties, + ReactiveLoadBalancer.Factory loadBalancerFactory) { + return new LoadBalancerRestClientHttpServiceGroupConfigurer(loadBalancerInterceptorProvider, properties, + loadBalancerFactory); } } 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 49a0d80a..fc3b998a 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 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. @@ -105,6 +105,12 @@ 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; } @@ -145,8 +151,7 @@ public class LoadBalancerProperties { this.hintHeaderName = hintHeaderName; } - // TODO: fix spelling in a major release - public void setxForwarded(XForwarded xForwarded) { + public void setXForwarded(XForwarded xForwarded) { this.xForwarded = xForwarded; } @@ -178,6 +183,14 @@ public class LoadBalancerProperties { this.stats = stats; } + public InterfaceClients getInterfaceClients() { + return interfaceClients; + } + + public void setInterfaceClients(InterfaceClients interfaceClients) { + this.interfaceClients = interfaceClients; + } + public static class StickySession { /** @@ -572,4 +585,22 @@ 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 1a1528f6..81120375 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 @@ -24,8 +24,9 @@ import org.apache.juli.logging.LogFactory; import org.jspecify.annotations.NonNull; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.interfaceclients.http.HttpInterfaceGroupProperties; -import org.springframework.boot.autoconfigure.interfaceclients.http.HttpInterfaceGroupsProperties; +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.http.client.ClientHttpRequestInterceptor; import org.springframework.util.function.SingletonSupplier; import org.springframework.web.client.RestClient; @@ -37,20 +38,22 @@ import org.springframework.web.util.UriComponentsBuilder; */ public class LoadBalancerRestClientHttpServiceGroupConfigurer implements RestClientHttpServiceGroupConfigurer { - private static final String DEFAULT_SCHEME = "http"; - private static final Log LOG = LogFactory.getLog(LoadBalancerRestClientHttpServiceGroupConfigurer.class); + private final ReactiveLoadBalancer.Factory loadBalancerClientFactory; + private final SingletonSupplier loadBalancerInterceptorSupplier; - private final HttpInterfaceGroupsProperties properties; + private final HttpClientServiceProperties clientServiceProperties; public LoadBalancerRestClientHttpServiceGroupConfigurer( ObjectProvider loadBalancerInterceptorProvider, - HttpInterfaceGroupsProperties properties) { + HttpClientServiceProperties clientServiceProperties, + ReactiveLoadBalancer.Factory loadBalancerClientFactory) { this.loadBalancerInterceptorSupplier = SingletonSupplier .ofNullable(loadBalancerInterceptorProvider.getIfAvailable()); - this.properties = properties; + this.clientServiceProperties = clientServiceProperties; + this.loadBalancerClientFactory = loadBalancerClientFactory; } @Override @@ -61,11 +64,8 @@ public class LoadBalancerRestClientHttpServiceGroupConfigurer implements RestCli } groups.configureClient((group, builder) -> { String groupName = group.name(); - HttpInterfaceGroupProperties groupProperties = properties.getProperties(groupName); - if (groupProperties == null) { - return; - } - if (groupProperties.getBaseUrl() == null) { + HttpClientServiceProperties.Group groupProperties = clientServiceProperties.getGroup().get(groupName); + if (groupProperties == null || groupProperties.getBaseUrl() == null) { URI baseUrl = constructBaseUrl(groupName); builder.baseUrl(baseUrl); builder.requestInterceptor(loadBalancerInterceptor); @@ -94,8 +94,14 @@ public class LoadBalancerRestClientHttpServiceGroupConfigurer implements RestCli return groupName.equals(baseUrl.getHost()); } - private static URI constructBaseUrl(String groupName) { - return UriComponentsBuilder.newInstance().scheme(DEFAULT_SCHEME).host(groupName).encode().build().toUri(); + private URI constructBaseUrl(String groupName) { + LoadBalancerProperties loadBalancerProperties = loadBalancerClientFactory.getProperties(groupName); + return UriComponentsBuilder.newInstance() + .scheme(loadBalancerProperties.getInterfaceClients().getDefaultScheme()) + .host(groupName) + .encode() + .build() + .toUri(); } }