Skip to content

Commit 83bb54b

Browse files
committed
Renames ServiceInstanceListSuppliers to ServiceInstanceListSupplierBuilder (#761)
Puts static builder() method on ServiceInstanceListSupplier. Deprecates ServiceInstanceListSupplier.fixed(Environment) and replaces with fixed(serviceId).
1 parent 2b30b35 commit 83bb54b

File tree

7 files changed

+297
-272
lines changed

7 files changed

+297
-272
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ public class CustomLoadBalancerConfiguration {
932932
@Bean
933933
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
934934
ConfigurableApplicationContext context) {
935-
return ServiceInstanceListSuppliers.builder()
935+
return ServiceInstanceListSupplier.builder()
936936
.withDiscoveryClient()
937937
.withHealthChecks()
938938
.withCaching()
@@ -941,7 +941,7 @@ public class CustomLoadBalancerConfiguration {
941941
}
942942
----
943943

944-
TIP:: In order to make working on your own LoadBalancer configuration easier, we have added some utility methods in `ServiceInstanceListSuppliers` class.
944+
TIP:: In order to make working on your own LoadBalancer configuration easier, we have added a `builder()` method to the `ServiceInstanceListSupplier` class.
945945

946946
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.
947947

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
2929
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
3030
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
31-
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSuppliers;
3231
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
3332
import org.springframework.context.ConfigurableApplicationContext;
3433
import org.springframework.context.annotation.Bean;
@@ -69,7 +68,7 @@ public static class ReactiveSupportConfiguration {
6968
havingValue = "default", matchIfMissing = true)
7069
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
7170
ConfigurableApplicationContext context) {
72-
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
71+
return ServiceInstanceListSupplier.builder().withDiscoveryClient()
7372
.withCaching().build(context);
7473
}
7574

@@ -80,7 +79,7 @@ public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
8079
havingValue = "zone-preference")
8180
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
8281
ConfigurableApplicationContext context) {
83-
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
82+
return ServiceInstanceListSupplier.builder().withDiscoveryClient()
8483
.withZonePreference().withCaching().build(context);
8584
}
8685

@@ -91,7 +90,7 @@ public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceL
9190
havingValue = "health-check")
9291
public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier(
9392
ConfigurableApplicationContext context) {
94-
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
93+
return ServiceInstanceListSupplier.builder().withDiscoveryClient()
9594
.withHealthChecks().withCaching().build(context);
9695
}
9796

@@ -109,7 +108,7 @@ public static class BlockingSupportConfiguration {
109108
havingValue = "default", matchIfMissing = true)
110109
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
111110
ConfigurableApplicationContext context) {
112-
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
111+
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient()
113112
.withCaching().build(context);
114113
}
115114

@@ -120,7 +119,7 @@ public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
120119
havingValue = "zone-preference")
121120
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
122121
ConfigurableApplicationContext context) {
123-
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
122+
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient()
124123
.withZonePreference().withCaching().build(context);
125124
}
126125

@@ -131,7 +130,7 @@ public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceL
131130
havingValue = "health-check")
132131
public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier(
133132
ConfigurableApplicationContext context) {
134-
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
133+
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient()
135134
.withHealthChecks().withCaching().build(context);
136135
}
137136

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

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,32 @@ public interface ServiceInstanceListSupplier
3939

4040
String getServiceId();
4141

42+
static ServiceInstanceListSupplierBuilder builder() {
43+
return new ServiceInstanceListSupplierBuilder();
44+
}
45+
4246
static FixedServiceInstanceListSupplier.Builder fixed(Environment environment) {
4347
return new FixedServiceInstanceListSupplier.Builder(environment);
4448
}
4549

50+
static FixedServiceInstanceListSupplier.SimpleBuilder fixed(String serviceId) {
51+
return new FixedServiceInstanceListSupplier.SimpleBuilder(serviceId);
52+
}
53+
4654
class FixedServiceInstanceListSupplier implements ServiceInstanceListSupplier {
4755

4856
private final String serviceId;
4957

5058
private List<ServiceInstance> instances;
5159

60+
@Deprecated
5261
public static Builder with(Environment env) {
5362
return new Builder(env);
5463
}
5564

56-
private FixedServiceInstanceListSupplier(Environment env,
65+
private FixedServiceInstanceListSupplier(String serviceId,
5766
List<ServiceInstance> instances) {
58-
this.serviceId = env.getProperty(PROPERTY_NAME);
67+
this.serviceId = serviceId;
5968
this.instances = instances;
6069
}
6170

@@ -69,6 +78,43 @@ public Flux<List<ServiceInstance>> get() {
6978
return Flux.just(instances);
7079
}
7180

81+
@Deprecated
82+
public static final class SimpleBuilder {
83+
84+
private final ArrayList<ServiceInstance> instances = new ArrayList<>();
85+
86+
private final String serviceId;
87+
88+
private SimpleBuilder(String serviceId) {
89+
this.serviceId = serviceId;
90+
}
91+
92+
public SimpleBuilder instance(ServiceInstance instance) {
93+
instances.add(instance);
94+
return this;
95+
}
96+
97+
public SimpleBuilder instance(int port) {
98+
return instance("localhost", port);
99+
}
100+
101+
public SimpleBuilder instance(String host, int port) {
102+
DefaultServiceInstance instance = new DefaultServiceInstance(
103+
instanceId(serviceId, host, port), serviceId, host, port, false);
104+
return instance(instance);
105+
}
106+
107+
private String instanceId(String serviceId, String host, int port) {
108+
return serviceId + ":" + host + ":" + port;
109+
}
110+
111+
public FixedServiceInstanceListSupplier build() {
112+
return new FixedServiceInstanceListSupplier(serviceId, instances);
113+
}
114+
115+
}
116+
117+
@Deprecated
72118
public static final class Builder {
73119

74120
private final Environment env;
@@ -99,7 +145,8 @@ private String instanceId(String serviceId, String host, int port) {
99145
}
100146

101147
public FixedServiceInstanceListSupplier build() {
102-
return new FixedServiceInstanceListSupplier(env, instances);
148+
return new FixedServiceInstanceListSupplier(
149+
env.getProperty(PROPERTY_NAME), instances);
103150
}
104151

105152
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* Copyright 2013-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.loadbalancer.core;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.function.BiFunction;
22+
import java.util.function.Function;
23+
24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
26+
27+
import org.springframework.beans.factory.ObjectProvider;
28+
import org.springframework.cloud.client.discovery.DiscoveryClient;
29+
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
30+
import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties;
31+
import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager;
32+
import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig;
33+
import org.springframework.context.ConfigurableApplicationContext;
34+
import org.springframework.util.Assert;
35+
import org.springframework.web.reactive.function.client.WebClient;
36+
37+
/**
38+
* A Builder for creating a {@link ServiceInstanceListSupplier} hierarchy to be used in
39+
* {@link ReactorLoadBalancer} configuration.
40+
*
41+
* @author Spencer Gibb
42+
* @author Olga Maciaszek-Sharma
43+
*/
44+
public final class ServiceInstanceListSupplierBuilder {
45+
46+
private static final Log LOG = LogFactory
47+
.getLog(ServiceInstanceListSupplierBuilder.class);
48+
49+
private Creator baseCreator;
50+
51+
private DelegateCreator cachingCreator;
52+
53+
private final List<DelegateCreator> creators = new ArrayList<>();
54+
55+
ServiceInstanceListSupplierBuilder() {
56+
}
57+
58+
/**
59+
* Sets a blocking {@link DiscoveryClient}-based
60+
* {@link DiscoveryClientServiceInstanceListSupplier} as a base
61+
* {@link ServiceInstanceListSupplier} in the hierarchy.
62+
* @return the {@link ServiceInstanceListSupplierBuilder} object
63+
*/
64+
public ServiceInstanceListSupplierBuilder withBlockingDiscoveryClient() {
65+
if (baseCreator != null && LOG.isWarnEnabled()) {
66+
LOG.warn(
67+
"Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator.");
68+
}
69+
this.baseCreator = context -> {
70+
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
71+
72+
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient,
73+
context.getEnvironment());
74+
};
75+
return this;
76+
}
77+
78+
/**
79+
* Sets a {@link ReactiveDiscoveryClient}-based
80+
* {@link DiscoveryClientServiceInstanceListSupplier} as a base
81+
* {@link ServiceInstanceListSupplier} in the hierarchy.
82+
* @return the {@link ServiceInstanceListSupplierBuilder} object
83+
*/
84+
public ServiceInstanceListSupplierBuilder withDiscoveryClient() {
85+
if (baseCreator != null && LOG.isWarnEnabled()) {
86+
LOG.warn(
87+
"Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator.");
88+
}
89+
this.baseCreator = context -> {
90+
ReactiveDiscoveryClient discoveryClient = context
91+
.getBean(ReactiveDiscoveryClient.class);
92+
93+
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient,
94+
context.getEnvironment());
95+
};
96+
return this;
97+
}
98+
99+
/**
100+
* Sets a user-provided {@link ServiceInstanceListSupplier} as a base
101+
* {@link ServiceInstanceListSupplier} in the hierarchy.
102+
* @param supplier a user-provided {@link ServiceInstanceListSupplier} instance
103+
* @return the {@link ServiceInstanceListSupplierBuilder} object
104+
*/
105+
public ServiceInstanceListSupplierBuilder withBase(
106+
ServiceInstanceListSupplier supplier) {
107+
this.baseCreator = context -> supplier;
108+
return this;
109+
}
110+
111+
/**
112+
* Adds a {@link HealthCheckServiceInstanceListSupplier} to the
113+
* {@link ServiceInstanceListSupplier} hierarchy.
114+
* @return the {@link ServiceInstanceListSupplierBuilder} object
115+
*/
116+
public ServiceInstanceListSupplierBuilder withHealthChecks() {
117+
DelegateCreator creator = (context, delegate) -> {
118+
LoadBalancerProperties properties = context
119+
.getBean(LoadBalancerProperties.class);
120+
WebClient.Builder webClient = context.getBean(WebClient.Builder.class);
121+
return new HealthCheckServiceInstanceListSupplier(delegate,
122+
properties.getHealthCheck(), webClient.build());
123+
};
124+
this.creators.add(creator);
125+
return this;
126+
}
127+
128+
/**
129+
* Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided
130+
* {@link WebClient} instance to the {@link ServiceInstanceListSupplier} hierarchy.
131+
* @param webClient a user-provided {@link WebClient} instance
132+
* @return the {@link ServiceInstanceListSupplierBuilder} object
133+
*/
134+
public ServiceInstanceListSupplierBuilder withHealthChecks(WebClient webClient) {
135+
DelegateCreator creator = (context, delegate) -> {
136+
LoadBalancerProperties properties = context
137+
.getBean(LoadBalancerProperties.class);
138+
return new HealthCheckServiceInstanceListSupplier(delegate,
139+
properties.getHealthCheck(), webClient);
140+
};
141+
this.creators.add(creator);
142+
return this;
143+
}
144+
145+
/**
146+
* Adds a {@link ZonePreferenceServiceInstanceListSupplier} to the
147+
* {@link ServiceInstanceListSupplier} hierarchy.
148+
* @return the {@link ServiceInstanceListSupplierBuilder} object
149+
*/
150+
public ServiceInstanceListSupplierBuilder withZonePreference() {
151+
DelegateCreator creator = (context, delegate) -> {
152+
LoadBalancerZoneConfig zoneConfig = context
153+
.getBean(LoadBalancerZoneConfig.class);
154+
return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig);
155+
};
156+
this.creators.add(creator);
157+
return this;
158+
}
159+
160+
/**
161+
* If {@link LoadBalancerCacheManager} is available in the context, wraps created
162+
* {@link ServiceInstanceListSupplier} hierarchy with a
163+
* {@link CachingServiceInstanceListSupplier} instance to provide a caching mechanism
164+
* for service instances. Uses {@link ObjectProvider} to lazily resolve
165+
* {@link LoadBalancerCacheManager}.
166+
* @return the {@link ServiceInstanceListSupplierBuilder} object
167+
*/
168+
public ServiceInstanceListSupplierBuilder withCaching() {
169+
if (cachingCreator != null && LOG.isWarnEnabled()) {
170+
LOG.warn(
171+
"Overriding a previously set cachingCreator with a CachingServiceInstanceListSupplier-based cachingCreator.");
172+
}
173+
this.cachingCreator = (context, delegate) -> {
174+
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
175+
.getBeanProvider(LoadBalancerCacheManager.class);
176+
if (cacheManagerProvider.getIfAvailable() != null) {
177+
return new CachingServiceInstanceListSupplier(delegate,
178+
cacheManagerProvider.getIfAvailable());
179+
}
180+
if (LOG.isWarnEnabled()) {
181+
LOG.warn(
182+
"LoadBalancerCacheManager not available, returning delegate without caching.");
183+
}
184+
return delegate;
185+
};
186+
return this;
187+
}
188+
189+
/**
190+
* Builds the {@link ServiceInstanceListSupplier} hierarchy.
191+
* @param context application context
192+
* @return a {@link ServiceInstanceListSupplier} instance on top of the delegate
193+
* hierarchy
194+
*/
195+
public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) {
196+
Assert.notNull(baseCreator, "A baseCreator must not be null");
197+
198+
ServiceInstanceListSupplier supplier = baseCreator.apply(context);
199+
200+
for (DelegateCreator creator : creators) {
201+
supplier = creator.apply(context, supplier);
202+
}
203+
204+
if (this.cachingCreator != null) {
205+
supplier = this.cachingCreator.apply(context, supplier);
206+
}
207+
return supplier;
208+
}
209+
210+
/**
211+
* Allows creating a {@link ServiceInstanceListSupplier} instance based on provided
212+
* {@link ConfigurableApplicationContext}.
213+
*/
214+
public interface Creator extends
215+
Function<ConfigurableApplicationContext, ServiceInstanceListSupplier> {
216+
217+
}
218+
219+
/**
220+
* Allows creating a {@link ServiceInstanceListSupplier} instance based on provided
221+
* {@link ConfigurableApplicationContext} and another
222+
* {@link ServiceInstanceListSupplier} instance that will be used as a delegate.
223+
*/
224+
public interface DelegateCreator extends
225+
BiFunction<ConfigurableApplicationContext, ServiceInstanceListSupplier, ServiceInstanceListSupplier> {
226+
227+
}
228+
229+
}

0 commit comments

Comments
 (0)