Browse Source

Call `get(Request request)` on delegates.

pull/1250/head
Olga MaciaszekSharma 1 year ago
parent
commit
91313ff9b6
  1. 4
      docs/src/main/asciidoc/spring-cloud-commons.adoc
  2. 49
      spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java
  3. 22
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java
  4. 4
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java
  5. 24
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java
  6. 32
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java
  7. 26
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java
  8. 8
      spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java
  9. 6
      spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java

4
docs/src/main/asciidoc/spring-cloud-commons.adoc

@ -964,8 +964,8 @@ public class CustomLoadBalancerConfiguration { @@ -964,8 +964,8 @@ public class CustomLoadBalancerConfiguration {
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withZonePreference()
.withCaching()
.withZonePreference()
.build(context);
}
}
@ -1110,8 +1110,8 @@ public class CustomLoadBalancerConfiguration { @@ -1110,8 +1110,8 @@ public class CustomLoadBalancerConfiguration {
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHints()
.withCaching()
.withHints()
.build(context);
}
}

49
spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java

@ -73,6 +73,21 @@ public class LoadBalancerProperties { @@ -73,6 +73,21 @@ public class LoadBalancerProperties {
*/
private boolean useRawStatusCodeInResponseData;
/**
* If this flag is set to {@code true},
* {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented
* to call {@code delegate.get(request)} in classes assignable from
* {@code DelegatingServiceInstanceListSupplier} that don't already implement that
* method, with the exclusion of {@code CachingServiceInstanceListSupplier} and
* {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the
* instance supplier hierarchy directly after the supplier performing instance
* retrieval over the network, before any request-based filtering is done.
* @deprecated This flag will be removed in 4.1, where this behaviour will become the
* default
*/
@Deprecated
private boolean callGetWithRequestOnDelegates;
public HealthCheck getHealthCheck() {
return healthCheck;
}
@ -134,6 +149,40 @@ public class LoadBalancerProperties { @@ -134,6 +149,40 @@ public class LoadBalancerProperties {
this.useRawStatusCodeInResponseData = useRawStatusCodeInResponseData;
}
/**
* If this flag is set to {@code true},
* {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented
* to call {@code delegate.get(request)} in classes assignable from
* {@code DelegatingServiceInstanceListSupplier} that don't already implement that
* method, with the exclusion of {@code CachingServiceInstanceListSupplier} and
* {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the
* instance supplier hierarchy directly after the supplier performing instance
* retrieval over the network, before any request-based filtering is done.
* @deprecated This flag will be removed in 4.1, where this behaviour will become the
* default
*/
@Deprecated
public boolean isCallGetWithRequestOnDelegates() {
return callGetWithRequestOnDelegates;
}
/**
* If this flag is set to {@code true},
* {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented
* to call {@code delegate.get(request)} in classes assignable from
* {@code DelegatingServiceInstanceListSupplier} that don't already implement that
* method, with the exclusion of {@code CachingServiceInstanceListSupplier} and
* {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the
* instance supplier hierarchy directly after the supplier performing instance
* retrieval over the network, before any request-based filtering is done.
* @deprecated This flag will be removed in 4.1, where this behaviour will become the
* default
*/
@Deprecated
public void setCallGetWithRequestOnDelegates(boolean callGetWithRequestOnDelegates) {
this.callGetWithRequestOnDelegates = callGetWithRequestOnDelegates;
}
public static class StickySession {
/**

22
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java

@ -93,7 +93,7 @@ public class LoadBalancerClientConfiguration { @@ -93,7 +93,7 @@ public class LoadBalancerClientConfiguration {
@Conditional(ZonePreferenceConfigurationCondition.class)
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withZonePreference().withCaching()
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().withZonePreference()
.build(context);
}
@ -119,8 +119,8 @@ public class LoadBalancerClientConfiguration { @@ -119,8 +119,8 @@ public class LoadBalancerClientConfiguration {
@Conditional(RequestBasedStickySessionConfigurationCondition.class)
public ServiceInstanceListSupplier requestBasedStickySessionDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withRequestBasedStickySession()
.withCaching().build(context);
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching()
.withRequestBasedStickySession().build(context);
}
@Bean
@ -129,8 +129,8 @@ public class LoadBalancerClientConfiguration { @@ -129,8 +129,8 @@ public class LoadBalancerClientConfiguration {
@Conditional(SameInstancePreferenceConfigurationCondition.class)
public ServiceInstanceListSupplier sameInstancePreferenceServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withSameInstancePreference()
.withCaching().build(context);
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching()
.withSameInstancePreference().build(context);
}
}
@ -155,8 +155,8 @@ public class LoadBalancerClientConfiguration { @@ -155,8 +155,8 @@ public class LoadBalancerClientConfiguration {
@Conditional(ZonePreferenceConfigurationCondition.class)
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withZonePreference()
.withCaching().build(context);
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching()
.withZonePreference().build(context);
}
@Bean
@ -175,8 +175,8 @@ public class LoadBalancerClientConfiguration { @@ -175,8 +175,8 @@ public class LoadBalancerClientConfiguration {
@Conditional(RequestBasedStickySessionConfigurationCondition.class)
public ServiceInstanceListSupplier requestBasedStickySessionDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withRequestBasedStickySession()
.withCaching().build(context);
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching()
.withRequestBasedStickySession().build(context);
}
@Bean
@ -185,8 +185,8 @@ public class LoadBalancerClientConfiguration { @@ -185,8 +185,8 @@ public class LoadBalancerClientConfiguration {
@Conditional(SameInstancePreferenceConfigurationCondition.class)
public ServiceInstanceListSupplier sameInstancePreferenceServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withSameInstancePreference()
.withCaching().build(context);
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching()
.withSameInstancePreference().build(context);
}
}

4
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java

@ -38,12 +38,12 @@ public abstract class DelegatingServiceInstanceListSupplier @@ -38,12 +38,12 @@ public abstract class DelegatingServiceInstanceListSupplier
}
public ServiceInstanceListSupplier getDelegate() {
return this.delegate;
return delegate;
}
@Override
public String getServiceId() {
return this.delegate.getServiceId();
return delegate.getServiceId();
}
@Override

24
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java

@ -24,6 +24,8 @@ import org.apache.commons.logging.LogFactory; @@ -24,6 +24,8 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Flux;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
/**
* An implementation of {@link ServiceInstanceListSupplier} that selects the previously
@ -39,10 +41,24 @@ public class SameInstancePreferenceServiceInstanceListSupplier extends Delegatin @@ -39,10 +41,24 @@ public class SameInstancePreferenceServiceInstanceListSupplier extends Delegatin
private ServiceInstance previouslyReturnedInstance;
private boolean callGetWithRequestOnDelegates;
public SameInstancePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) {
super(delegate);
}
/**
* @deprecated for removal in 4.1, where calling {@code get(Request request)} on
* delegate will be the default behaviour.
*/
@Deprecated
public SameInstancePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory) {
super(delegate);
callGetWithRequestOnDelegates = loadBalancerClientFactory.getProperties(getServiceId())
.isCallGetWithRequestOnDelegates();
}
@Override
public String getServiceId() {
return delegate.getServiceId();
@ -53,6 +69,14 @@ public class SameInstancePreferenceServiceInstanceListSupplier extends Delegatin @@ -53,6 +69,14 @@ public class SameInstancePreferenceServiceInstanceListSupplier extends Delegatin
return delegate.get().map(this::filteredBySameInstancePreference);
}
@Override
public Flux<List<ServiceInstance>> get(Request request) {
if (callGetWithRequestOnDelegates) {
return delegate.get(request).map(this::filteredBySameInstancePreference);
}
return get();
}
private List<ServiceInstance> filteredBySameInstancePreference(List<ServiceInstance> serviceInstances) {
if (previouslyReturnedInstance != null && serviceInstances.contains(previouslyReturnedInstance)) {
if (LOG.isDebugEnabled()) {

32
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java

@ -57,8 +57,6 @@ public final class ServiceInstanceListSupplierBuilder { @@ -57,8 +57,6 @@ public final class ServiceInstanceListSupplierBuilder {
private Creator baseCreator;
private DelegateCreator cachingCreator;
private final List<DelegateCreator> creators = new ArrayList<>();
ServiceInstanceListSupplierBuilder() {
@ -148,8 +146,10 @@ public final class ServiceInstanceListSupplierBuilder { @@ -148,8 +146,10 @@ public final class ServiceInstanceListSupplierBuilder {
* @return the {@link ServiceInstanceListSupplierBuilder} object
*/
public ServiceInstanceListSupplierBuilder withSameInstancePreference() {
DelegateCreator creator = (context,
delegate) -> new SameInstancePreferenceServiceInstanceListSupplier(delegate);
DelegateCreator creator = (context, delegate) -> {
LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class);
return new SameInstancePreferenceServiceInstanceListSupplier(delegate, loadBalancerClientFactory);
};
this.creators.add(creator);
return this;
}
@ -191,8 +191,9 @@ public final class ServiceInstanceListSupplierBuilder { @@ -191,8 +191,9 @@ public final class ServiceInstanceListSupplierBuilder {
*/
public ServiceInstanceListSupplierBuilder withZonePreference() {
DelegateCreator creator = (context, delegate) -> {
LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class);
LoadBalancerZoneConfig zoneConfig = context.getBean(LoadBalancerZoneConfig.class);
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig);
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig, loadBalancerClientFactory);
};
this.creators.add(creator);
return this;
@ -206,8 +207,9 @@ public final class ServiceInstanceListSupplierBuilder { @@ -206,8 +207,9 @@ public final class ServiceInstanceListSupplierBuilder {
*/
public ServiceInstanceListSupplierBuilder withZonePreference(String zoneName) {
DelegateCreator creator = (context, delegate) -> {
LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class);
LoadBalancerZoneConfig zoneConfig = new LoadBalancerZoneConfig(zoneName);
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig);
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig, loadBalancerClientFactory);
};
this.creators.add(creator);
return this;
@ -228,19 +230,15 @@ public final class ServiceInstanceListSupplierBuilder { @@ -228,19 +230,15 @@ public final class ServiceInstanceListSupplierBuilder {
}
/**
* If {@link LoadBalancerCacheManager} is available in the context, wraps created
* {@link ServiceInstanceListSupplier} hierarchy with a
* {@link CachingServiceInstanceListSupplier} instance to provide a caching mechanism
* for service instances. Uses {@link ObjectProvider} to lazily resolve
* If {@link LoadBalancerCacheManager} is available in the context, adds a
* {@link CachingServiceInstanceListSupplier} instance to the
* {@link ServiceInstanceListSupplier} hierarchy to provide a caching mechanism for
* service instances. Uses {@link ObjectProvider} to lazily resolve
* {@link LoadBalancerCacheManager}.
* @return the {@link ServiceInstanceListSupplierBuilder} object
*/
public ServiceInstanceListSupplierBuilder withCaching() {
if (cachingCreator != null && LOG.isWarnEnabled()) {
LOG.warn(
"Overriding a previously set cachingCreator with a CachingServiceInstanceListSupplier-based cachingCreator.");
}
this.cachingCreator = (context, delegate) -> {
DelegateCreator creator = (context, delegate) -> {
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class);
if (cacheManagerProvider.getIfAvailable() != null) {
@ -251,6 +249,7 @@ public final class ServiceInstanceListSupplierBuilder { @@ -251,6 +249,7 @@ public final class ServiceInstanceListSupplierBuilder {
}
return delegate;
};
creators.add(creator);
return this;
}
@ -297,9 +296,6 @@ public final class ServiceInstanceListSupplierBuilder { @@ -297,9 +296,6 @@ public final class ServiceInstanceListSupplierBuilder {
supplier = creator.apply(context, supplier);
}
if (this.cachingCreator != null) {
supplier = this.cachingCreator.apply(context, supplier);
}
return supplier;
}

26
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java

@ -23,6 +23,8 @@ import java.util.Map; @@ -23,6 +23,8 @@ import java.util.Map;
import reactor.core.publisher.Flux;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig;
/**
@ -43,17 +45,41 @@ public class ZonePreferenceServiceInstanceListSupplier extends DelegatingService @@ -43,17 +45,41 @@ public class ZonePreferenceServiceInstanceListSupplier extends DelegatingService
private String zone;
private boolean callGetWithRequestOnDelegates;
public ZonePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
LoadBalancerZoneConfig zoneConfig) {
super(delegate);
this.zoneConfig = zoneConfig;
}
/**
* @deprecated for removal in 4.1, where calling {@code get(Request request)} on
* delegate will be the default behaviour.
*/
@Deprecated
public ZonePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate,
LoadBalancerZoneConfig zoneConfig,
ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory) {
super(delegate);
this.zoneConfig = zoneConfig;
callGetWithRequestOnDelegates = loadBalancerClientFactory.getProperties(getServiceId())
.isCallGetWithRequestOnDelegates();
}
@Override
public Flux<List<ServiceInstance>> get() {
return getDelegate().get().map(this::filteredByZone);
}
@Override
public Flux<List<ServiceInstance>> get(Request request) {
if (callGetWithRequestOnDelegates) {
return getDelegate().get(request).map(this::filteredByZone);
}
return get();
}
private List<ServiceInstance> filteredByZone(List<ServiceInstance> serviceInstances) {
if (zone == null) {
zone = zoneConfig.getZone();

8
spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java

@ -91,10 +91,10 @@ class LoadBalancerClientConfigurationTests { @@ -91,10 +91,10 @@ class LoadBalancerClientConfigurationTests {
reactiveDiscoveryClientRunner.withPropertyValues("spring.cloud.loadbalancer.configurations=zone-preference")
.run(context -> {
ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(ZonePreferenceServiceInstanceListSupplier.class);
ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier)
.getDelegate();
then(delegate).isInstanceOf(ZonePreferenceServiceInstanceListSupplier.class);
then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class);
ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate)
.getDelegate();
then(secondDelegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class);
@ -119,10 +119,10 @@ class LoadBalancerClientConfigurationTests { @@ -119,10 +119,10 @@ class LoadBalancerClientConfigurationTests {
.withPropertyValues("spring.cloud.loadbalancer.configurations=request-based-sticky-session")
.run(context -> {
ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(RequestBasedStickySessionServiceInstanceListSupplier.class);
ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier)
.getDelegate();
then(delegate).isInstanceOf(RequestBasedStickySessionServiceInstanceListSupplier.class);
then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class);
ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate)
.getDelegate();
then(secondDelegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class);

6
spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java

@ -37,11 +37,9 @@ public class ServiceInstanceListSupplierBuilderTests { @@ -37,11 +37,9 @@ public class ServiceInstanceListSupplierBuilderTests {
public void testBuilder() {
new ApplicationContextRunner().withUserConfiguration(CacheTestConfig.class).run(context -> {
ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier.builder().withDiscoveryClient()
.withHealthChecks().withCaching().build(context);
assertThat(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
.withHealthChecks().build(context);
assertThat(supplier).isInstanceOf(HealthCheckServiceInstanceListSupplier.class);
DelegatingServiceInstanceListSupplier delegating = (DelegatingServiceInstanceListSupplier) supplier;
assertThat(delegating.getDelegate()).isInstanceOf(HealthCheckServiceInstanceListSupplier.class);
delegating = (DelegatingServiceInstanceListSupplier) delegating.getDelegate();
assertThat(delegating.getDelegate()).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class);
});
}

Loading…
Cancel
Save