From a1d9decd154233dd6ac5212140c09692316c6386 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Thu, 21 May 2020 12:41:00 -0400 Subject: [PATCH] Renames ServiceInstanceListSuppliers to ServiceInstanceListSupplierBuilder Puts static builder() method on ServiceInstanceListSupplier. Deprecates ServiceInstanceListSupplier.fixed(Environment) and replaces with fixed(serviceId). --- .../main/asciidoc/spring-cloud-commons.adoc | 4 +- .../LoadBalancerClientConfiguration.java | 13 +- .../core/ServiceInstanceListSupplier.java | 53 +++- .../ServiceInstanceListSupplierBuilder.java | 229 ++++++++++++++++ .../core/ServiceInstanceListSuppliers.java | 246 ------------------ ...CheckServiceInstanceListSupplierTests.java | 16 +- ...viceInstanceListSupplierBuilderTests.java} | 8 +- 7 files changed, 297 insertions(+), 272 deletions(-) create mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliers.java rename spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/{ServiceInstanceListSuppliersTests.java => ServiceInstanceListSupplierBuilderTests.java} (96%) diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index b65aac02b..0f6b3ad30 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -959,7 +959,7 @@ public class CustomLoadBalancerConfiguration { @Bean public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder() + return ServiceInstanceListSupplier.builder() .withDiscoveryClient() .withHealthChecks() .withCaching() @@ -968,7 +968,7 @@ public class CustomLoadBalancerConfiguration { } ---- -TIP:: In order to make working on your own LoadBalancer configuration easier, we have added some utility methods in `ServiceInstanceListSuppliers` class. +TIP:: In order to make working on your own LoadBalancer configuration easier, we have added a `builder()` method to the `ServiceInstanceListSupplier` class. TIP:: You can also use our alternative predefined configurations in place of the default ones by setting the value of `spring.cloud.loadbalancer.configurations` property to `zone-preference` to use `ZonePreferenceServiceInstanceListSupplier` with caching or to `health-check` to use `HealthCheckServiceInstanceListSupplier` with caching. diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java index ed3b1d5dd..22c2e2a58 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java @@ -32,7 +32,6 @@ import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSuppliers; import org.springframework.cloud.loadbalancer.core.ServiceInstanceSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.ApplicationContext; @@ -75,7 +74,7 @@ public static class ReactiveSupportConfiguration { havingValue = "default", matchIfMissing = true) public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withDiscoveryClient() + return ServiceInstanceListSupplier.builder().withDiscoveryClient() .withCaching().build(context); } @@ -86,7 +85,7 @@ public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( havingValue = "zone-preference") public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withDiscoveryClient() + return ServiceInstanceListSupplier.builder().withDiscoveryClient() .withZonePreference().withCaching().build(context); } @@ -97,7 +96,7 @@ public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceL havingValue = "health-check") public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withDiscoveryClient() + return ServiceInstanceListSupplier.builder().withDiscoveryClient() .withHealthChecks().withCaching().build(context); } @@ -132,7 +131,7 @@ public static class BlockingSupportConfiguration { havingValue = "default", matchIfMissing = true) public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient() + return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() .withCaching().build(context); } @@ -143,7 +142,7 @@ public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( havingValue = "zone-preference") public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient() + return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() .withZonePreference().withCaching().build(context); } @@ -154,7 +153,7 @@ public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceL havingValue = "health-check") public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { - return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient() + return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient() .withHealthChecks().withCaching().build(context); } diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java index a54457c37..1b98fcbb3 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java @@ -39,23 +39,32 @@ public interface ServiceInstanceListSupplier String getServiceId(); + static ServiceInstanceListSupplierBuilder builder() { + return new ServiceInstanceListSupplierBuilder(); + } + static FixedServiceInstanceListSupplier.Builder fixed(Environment environment) { return new FixedServiceInstanceListSupplier.Builder(environment); } + static FixedServiceInstanceListSupplier.SimpleBuilder fixed(String serviceId) { + return new FixedServiceInstanceListSupplier.SimpleBuilder(serviceId); + } + class FixedServiceInstanceListSupplier implements ServiceInstanceListSupplier { private final String serviceId; private List instances; + @Deprecated public static Builder with(Environment env) { return new Builder(env); } - private FixedServiceInstanceListSupplier(Environment env, + private FixedServiceInstanceListSupplier(String serviceId, List instances) { - this.serviceId = env.getProperty(PROPERTY_NAME); + this.serviceId = serviceId; this.instances = instances; } @@ -69,6 +78,43 @@ public Flux> get() { return Flux.just(instances); } + @Deprecated + public static final class SimpleBuilder { + + private final ArrayList instances = new ArrayList<>(); + + private final String serviceId; + + private SimpleBuilder(String serviceId) { + this.serviceId = serviceId; + } + + public SimpleBuilder instance(ServiceInstance instance) { + instances.add(instance); + return this; + } + + public SimpleBuilder instance(int port) { + return instance("localhost", port); + } + + public SimpleBuilder instance(String host, int port) { + DefaultServiceInstance instance = new DefaultServiceInstance( + instanceId(serviceId, host, port), serviceId, host, port, false); + return instance(instance); + } + + private String instanceId(String serviceId, String host, int port) { + return serviceId + ":" + host + ":" + port; + } + + public FixedServiceInstanceListSupplier build() { + return new FixedServiceInstanceListSupplier(serviceId, instances); + } + + } + + @Deprecated public static final class Builder { private final Environment env; @@ -99,7 +145,8 @@ private String instanceId(String serviceId, String host, int port) { } public FixedServiceInstanceListSupplier build() { - return new FixedServiceInstanceListSupplier(env, instances); + return new FixedServiceInstanceListSupplier( + env.getProperty(PROPERTY_NAME), instances); } } diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java new file mode 100644 index 000000000..8723d3803 --- /dev/null +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java @@ -0,0 +1,229 @@ +/* + * 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.loadbalancer.core; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; +import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties; +import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; +import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.util.Assert; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * A Builder for creating a {@link ServiceInstanceListSupplier} hierarchy to be used in + * {@link ReactorLoadBalancer} configuration. + * + * @author Spencer Gibb + * @author Olga Maciaszek-Sharma + */ +public final class ServiceInstanceListSupplierBuilder { + + private static final Log LOG = LogFactory + .getLog(ServiceInstanceListSupplierBuilder.class); + + private Creator baseCreator; + + private DelegateCreator cachingCreator; + + private final List creators = new ArrayList<>(); + + ServiceInstanceListSupplierBuilder() { + } + + /** + * Sets a blocking {@link DiscoveryClient}-based + * {@link DiscoveryClientServiceInstanceListSupplier} as a base + * {@link ServiceInstanceListSupplier} in the hierarchy. + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withBlockingDiscoveryClient() { + if (baseCreator != null && LOG.isWarnEnabled()) { + LOG.warn( + "Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator."); + } + this.baseCreator = context -> { + DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class); + + return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, + context.getEnvironment()); + }; + return this; + } + + /** + * Sets a {@link ReactiveDiscoveryClient}-based + * {@link DiscoveryClientServiceInstanceListSupplier} as a base + * {@link ServiceInstanceListSupplier} in the hierarchy. + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withDiscoveryClient() { + if (baseCreator != null && LOG.isWarnEnabled()) { + LOG.warn( + "Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator."); + } + this.baseCreator = context -> { + ReactiveDiscoveryClient discoveryClient = context + .getBean(ReactiveDiscoveryClient.class); + + return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, + context.getEnvironment()); + }; + return this; + } + + /** + * Sets a user-provided {@link ServiceInstanceListSupplier} as a base + * {@link ServiceInstanceListSupplier} in the hierarchy. + * @param supplier a user-provided {@link ServiceInstanceListSupplier} instance + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withBase( + ServiceInstanceListSupplier supplier) { + this.baseCreator = context -> supplier; + return this; + } + + /** + * Adds a {@link HealthCheckServiceInstanceListSupplier} to the + * {@link ServiceInstanceListSupplier} hierarchy. + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withHealthChecks() { + DelegateCreator creator = (context, delegate) -> { + LoadBalancerProperties properties = context + .getBean(LoadBalancerProperties.class); + WebClient.Builder webClient = context.getBean(WebClient.Builder.class); + return new HealthCheckServiceInstanceListSupplier(delegate, + properties.getHealthCheck(), webClient.build()); + }; + this.creators.add(creator); + return this; + } + + /** + * Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided + * {@link WebClient} instance to the {@link ServiceInstanceListSupplier} hierarchy. + * @param webClient a user-provided {@link WebClient} instance + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withHealthChecks(WebClient webClient) { + DelegateCreator creator = (context, delegate) -> { + LoadBalancerProperties properties = context + .getBean(LoadBalancerProperties.class); + return new HealthCheckServiceInstanceListSupplier(delegate, + properties.getHealthCheck(), webClient); + }; + this.creators.add(creator); + return this; + } + + /** + * Adds a {@link ZonePreferenceServiceInstanceListSupplier} to the + * {@link ServiceInstanceListSupplier} hierarchy. + * @return the {@link ServiceInstanceListSupplierBuilder} object + */ + public ServiceInstanceListSupplierBuilder withZonePreference() { + DelegateCreator creator = (context, delegate) -> { + LoadBalancerZoneConfig zoneConfig = context + .getBean(LoadBalancerZoneConfig.class); + return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig); + }; + this.creators.add(creator); + return this; + } + + /** + * 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 + * {@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) -> { + ObjectProvider cacheManagerProvider = context + .getBeanProvider(LoadBalancerCacheManager.class); + if (cacheManagerProvider.getIfAvailable() != null) { + return new CachingServiceInstanceListSupplier(delegate, + cacheManagerProvider.getIfAvailable()); + } + if (LOG.isWarnEnabled()) { + LOG.warn( + "LoadBalancerCacheManager not available, returning delegate without caching."); + } + return delegate; + }; + return this; + } + + /** + * Builds the {@link ServiceInstanceListSupplier} hierarchy. + * @param context application context + * @return a {@link ServiceInstanceListSupplier} instance on top of the delegate + * hierarchy + */ + public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) { + Assert.notNull(baseCreator, "A baseCreator must not be null"); + + ServiceInstanceListSupplier supplier = baseCreator.apply(context); + + for (DelegateCreator creator : creators) { + supplier = creator.apply(context, supplier); + } + + if (this.cachingCreator != null) { + supplier = this.cachingCreator.apply(context, supplier); + } + return supplier; + } + + /** + * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided + * {@link ConfigurableApplicationContext}. + */ + public interface Creator extends + Function { + + } + + /** + * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided + * {@link ConfigurableApplicationContext} and another + * {@link ServiceInstanceListSupplier} instance that will be used as a delegate. + */ + public interface DelegateCreator extends + BiFunction { + + } + +} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliers.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliers.java deleted file mode 100644 index 690a53eed..000000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliers.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.Assert; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * A utility class providing a {@link Builder} for creating a - * {@link ServiceInstanceListSupplier} hierarchy to be used in {@link ReactorLoadBalancer} - * configuration. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public abstract class ServiceInstanceListSuppliers { - - private ServiceInstanceListSuppliers() { - - } - - public static Builder builder() { - return new Builder(); - } - - /** - * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided - * {@link ConfigurableApplicationContext}. - */ - public interface Creator extends - Function { - - } - - /** - * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided - * {@link ConfigurableApplicationContext} and another - * {@link ServiceInstanceListSupplier} instance that will be used as a delegate. - */ - public interface DelegateCreator extends - BiFunction { - - } - - /** - * A builder for creating a {@link ServiceInstanceListSupplier} hierarchy to be used - * in {@link ReactorLoadBalancer} configuration. - */ - public static class Builder { - - private static final Log LOG = LogFactory.getLog(Builder.class); - - private Creator baseCreator; - - private DelegateCreator cachingCreator; - - private final List creators = new ArrayList<>(); - - public Builder() { - } - - /** - * Sets a blocking {@link DiscoveryClient}-based - * {@link DiscoveryClientServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @return the {@link Builder} object - */ - public Builder withBlockingDiscoveryClient() { - if (baseCreator != null && LOG.isWarnEnabled()) { - LOG.warn( - "Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator."); - } - this.baseCreator = context -> { - DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class); - - return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, - context.getEnvironment()); - }; - return this; - } - - /** - * Sets a {@link ReactiveDiscoveryClient}-based - * {@link DiscoveryClientServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @return the {@link Builder} object - */ - public Builder withDiscoveryClient() { - if (baseCreator != null && LOG.isWarnEnabled()) { - LOG.warn( - "Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator."); - } - this.baseCreator = context -> { - ReactiveDiscoveryClient discoveryClient = context - .getBean(ReactiveDiscoveryClient.class); - - return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, - context.getEnvironment()); - }; - return this; - } - - /** - * Sets a user-provided {@link ServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @param supplier a user-provided {@link ServiceInstanceListSupplier} instance - * @return the {@link Builder} object - */ - public Builder withBase(ServiceInstanceListSupplier supplier) { - this.baseCreator = context -> supplier; - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link Builder} object - */ - public Builder withHealthChecks() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerProperties properties = context - .getBean(LoadBalancerProperties.class); - WebClient.Builder webClient = context.getBean(WebClient.Builder.class); - return new HealthCheckServiceInstanceListSupplier(delegate, - properties.getHealthCheck(), webClient.build()); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided - * {@link WebClient} instance to the {@link ServiceInstanceListSupplier} - * hierarchy. - * @param webClient a user-provided {@link WebClient} instance - * @return the {@link Builder} object - */ - public Builder withHealthChecks(WebClient webClient) { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerProperties properties = context - .getBean(LoadBalancerProperties.class); - return new HealthCheckServiceInstanceListSupplier(delegate, - properties.getHealthCheck(), webClient); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link ZonePreferenceServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link Builder} object - */ - public Builder withZonePreference() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerZoneConfig zoneConfig = context - .getBean(LoadBalancerZoneConfig.class); - return new ZonePreferenceServiceInstanceListSupplier(delegate, - zoneConfig); - }; - this.creators.add(creator); - return this; - } - - /** - * 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 - * {@link LoadBalancerCacheManager}. - * @return the {@link Builder} object - */ - public Builder withCaching() { - if (cachingCreator != null && LOG.isWarnEnabled()) { - LOG.warn( - "Overriding a previously set cachingCreator with a CachingServiceInstanceListSupplier-based cachingCreator."); - } - this.cachingCreator = (context, delegate) -> { - ObjectProvider cacheManagerProvider = context - .getBeanProvider(LoadBalancerCacheManager.class); - if (cacheManagerProvider.getIfAvailable() != null) { - return new CachingServiceInstanceListSupplier(delegate, - cacheManagerProvider.getIfAvailable()); - } - if (LOG.isWarnEnabled()) { - LOG.warn( - "LoadBalancerCacheManager not available, returning delegate without caching."); - } - return delegate; - }; - return this; - } - - /** - * Builds the {@link ServiceInstanceListSupplier} hierarchy. - * @param context application context - * @return a {@link ServiceInstanceListSupplier} instance on top of the delegate - * hierarchy - */ - public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) { - Assert.notNull(baseCreator, "A baseCreator must not be null"); - - ServiceInstanceListSupplier supplier = baseCreator.apply(context); - - for (DelegateCreator creator : creators) { - supplier = creator.apply(context, supplier); - } - - if (this.cachingCreator != null) { - supplier = this.cachingCreator.apply(context, supplier); - } - return supplier; - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java index 474a0396b..b04a68280 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java @@ -41,7 +41,6 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties; import org.springframework.context.annotation.Configuration; -import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -92,9 +91,8 @@ void tearDown() throws Exception { void shouldCheckInstanceWithProvidedHealthCheckPath() { healthCheck.getPath().put("ignored-service", "/health"); listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSupplier.FixedServiceInstanceListSupplier - .with(new MockEnvironment()).build(), - healthCheck, webClient); + ServiceInstanceListSupplier.fixed("ignored-service").build(), healthCheck, + webClient); ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", "ignored-service", "127.0.0.1", port, false); @@ -107,9 +105,8 @@ void shouldCheckInstanceWithProvidedHealthCheckPath() { @Test void shouldCheckInstanceWithDefaultHealthCheckPath() { listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSupplier.FixedServiceInstanceListSupplier - .with(new MockEnvironment()).build(), - healthCheck, webClient); + ServiceInstanceListSupplier.fixed("ignored-service").build(), healthCheck, + webClient); ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", "ignored-service", "127.0.0.1", port, false); @@ -123,9 +120,8 @@ void shouldCheckInstanceWithDefaultHealthCheckPath() { void shouldReturnFalseIfEndpointNotFound() { healthCheck.getPath().put("ignored-service", "/test"); listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSupplier.FixedServiceInstanceListSupplier - .with(new MockEnvironment()).build(), - healthCheck, webClient); + ServiceInstanceListSupplier.fixed("ignored-service").build(), healthCheck, + webClient); ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", "ignored-service", "127.0.0.1", port, false); diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java similarity index 96% rename from spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTests.java rename to spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java index 39208e52d..532cc8a08 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java @@ -30,13 +30,13 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; -public class ServiceInstanceListSuppliersTests { +public class ServiceInstanceListSupplierBuilderTests { @Test public void testBuilder() { new ApplicationContextRunner().withUserConfiguration(CacheTestConfig.class) .run(context -> { - ServiceInstanceListSupplier supplier = ServiceInstanceListSuppliers + ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier .builder().withDiscoveryClient().withHealthChecks() .withCaching().build(context); assertThat(supplier) @@ -56,7 +56,7 @@ public void testIllegalArgumentExceptionThrownWhenBaseBuilderNull() { new ApplicationContextRunner().withUserConfiguration(CacheTestConfig.class) .run(context -> { try { - ServiceInstanceListSuppliers.builder().withHealthChecks() + ServiceInstanceListSupplier.builder().withHealthChecks() .build(context); fail("Should have thrown exception."); } @@ -72,7 +72,7 @@ public void testIllegalArgumentExceptionThrownWhenBaseBuilderNull() { public void testDelegateReturnedIfLoadBalancerCacheManagerNotAvailable() { new ApplicationContextRunner().withUserConfiguration(BaseTestConfig.class) .run(context -> { - ServiceInstanceListSupplier supplier = ServiceInstanceListSuppliers + ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier .builder().withDiscoveryClient().withHealthChecks() .withCaching().build(context); assertThat(supplier)