Merge remote-tracking branch 'origin/2.2.x'

This commit is contained in:
Olga Maciaszek-Sharma
2020-05-18 16:26:40 +02:00
3 changed files with 227 additions and 0 deletions

View File

@@ -943,6 +943,8 @@ 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:: 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.
[[spring-cloud-loadbalancer-starter]]
=== Spring Cloud LoadBalancer Starter

View File

@@ -19,6 +19,7 @@ package org.springframework.cloud.loadbalancer.annotation;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled;
@@ -70,12 +71,36 @@ public class LoadBalancerClientConfiguration {
@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "default", matchIfMissing = true)
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
.withCaching().build(context);
}
@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "zone-preference")
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
.withZonePreference().withCaching().build(context);
}
@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "health-check")
public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withDiscoveryClient()
.withHealthChecks().withCaching().build(context);
}
@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean
@@ -103,12 +128,36 @@ public class LoadBalancerClientConfiguration {
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "default", matchIfMissing = true)
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
.withCaching().build(context);
}
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "zone-preference")
public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
.withZonePreference().withCaching().build(context);
}
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.configurations",
havingValue = "health-check")
public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSuppliers.builder().withBlockingDiscoveryClient()
.withHealthChecks().withCaching().build(context);
}
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean

View File

@@ -0,0 +1,176 @@
/*
* Copyright 2012-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.annotation;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration;
import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration;
import org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.HealthCheckServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceSupplier;
import org.springframework.cloud.loadbalancer.core.ZonePreferenceServiceInstanceListSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import static org.assertj.core.api.BDDAssertions.then;
/**
* Tests for {@link LoadBalancerClientConfiguration}.
*
* @author Olga Maciaszek-Sharma
*/
class LoadBalancerClientConfigurationTests {
ApplicationContextRunner reactiveDiscoveryClientRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
ReactiveCompositeDiscoveryClientAutoConfiguration.class,
LoadBalancerCacheAutoConfiguration.class,
LoadBalancerAutoConfiguration.class,
LoadBalancerClientConfiguration.class));
ApplicationContextRunner blockingDiscoveryClientRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(CompositeDiscoveryClientAutoConfiguration.class,
LoadBalancerCacheAutoConfiguration.class,
LoadBalancerAutoConfiguration.class,
LoadBalancerClientConfiguration.class));
@Test
void shouldInstantiateDefaultServiceInstanceListSupplierWhenConfigurationsPropertyNotSet() {
reactiveDiscoveryClientRunner.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate())
.isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateDefaultServiceInstanceListSupplier() {
reactiveDiscoveryClientRunner
.withPropertyValues("spring.cloud.loadbalancer.configurations=default")
.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate())
.isInstanceOf(
DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateZonePreferenceServiceInstanceListSupplier() {
reactiveDiscoveryClientRunner
.withPropertyValues(
"spring.cloud.loadbalancer.configurations=zone-preference")
.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier)
.getDelegate();
then(delegate).isInstanceOf(
ZonePreferenceServiceInstanceListSupplier.class);
ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate)
.getDelegate();
then(secondDelegate).isInstanceOf(
DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateHealthCheckServiceInstanceListSupplier() {
reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class)
.withPropertyValues(
"spring.cloud.loadbalancer.configurations=health-check")
.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier)
.getDelegate();
then(delegate)
.isInstanceOf(HealthCheckServiceInstanceListSupplier.class);
ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate)
.getDelegate();
then(secondDelegate).isInstanceOf(
DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateDefaultBlockingServiceInstanceListSupplierWhenConfigurationsPropertyNotSet() {
blockingDiscoveryClientRunner.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate())
.isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateDefaultBlockingServiceInstanceListSupplier() {
blockingDiscoveryClientRunner
.withPropertyValues("spring.cloud.loadbalancer.configurations=default")
.run(context -> {
ServiceInstanceListSupplier supplier = context
.getBean(ServiceInstanceListSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class);
then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate())
.isInstanceOf(
DiscoveryClientServiceInstanceListSupplier.class);
});
}
@Test
void shouldInstantiateServiceInstanceSupplierRegardlessOfConfigurationProperty() {
reactiveDiscoveryClientRunner
.withPropertyValues(
"spring.cloud.loadbalancer.configurations=zone-preference")
.run(context -> {
ServiceInstanceSupplier supplier = context
.getBean(ServiceInstanceSupplier.class);
then(supplier).isInstanceOf(CachingServiceInstanceSupplier.class);
});
}
@Configuration
protected static class TestConfig {
@Bean
@LoadBalanced
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
}