Bumping versions

This commit is contained in:
buildmaster
2020-09-17 17:52:36 +00:00
parent dad59dea10
commit 2e2ff80e07
25 changed files with 255 additions and 447 deletions

View File

@@ -43,8 +43,7 @@ public class CloudFoundryAppServiceDiscoveryClient extends CloudFoundryDiscovery
private static final String INTERNAL_DOMAIN = "apps.internal";
CloudFoundryAppServiceDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
CloudFoundryService svc,
CloudFoundryAppServiceDiscoveryClient(CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
}
@@ -56,23 +55,19 @@ public class CloudFoundryAppServiceDiscoveryClient extends CloudFoundryDiscovery
@Override
public List<ServiceInstance> getInstances(String serviceId) {
return getCloudFoundryService()
.getApplicationInstances(serviceId).filter(tuple -> tuple.getT1()
.getUrls().stream().anyMatch(this::isInternalDomain))
.map(tuple -> {
return getCloudFoundryService().getApplicationInstances(serviceId)
.filter(tuple -> tuple.getT1().getUrls().stream().anyMatch(this::isInternalDomain)).map(tuple -> {
ApplicationDetail applicationDetail = tuple.getT1();
InstanceDetail instanceDetail = tuple.getT2();
String applicationId = applicationDetail.getId();
String applicationIndex = instanceDetail.getIndex();
String name = applicationDetail.getName();
String url = applicationDetail.getUrls().stream()
.filter(this::isInternalDomain).findFirst()
String url = applicationDetail.getUrls().stream().filter(this::isInternalDomain).findFirst()
.map(x -> instanceDetail.getIndex() + "." + x).get();
HashMap<String, String> metadata = new HashMap<>();
metadata.put("applicationId", applicationId);
metadata.put("instanceId", applicationIndex);
return (ServiceInstance) new DefaultServiceInstance(name, url, 8080,
false, metadata);
return (ServiceInstance) new DefaultServiceInstance(name, url, 8080, false, metadata);
}).collectList().block();
}

View File

@@ -48,11 +48,10 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient {
private final CloudFoundryDiscoveryProperties properties;
private final String description = "Cloud Foundry " + DiscoveryClient.class.getName()
+ " implementation";
private final String description = "Cloud Foundry " + DiscoveryClient.class.getName() + " implementation";
CloudFoundryDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
CloudFoundryDiscoveryClient(CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
CloudFoundryDiscoveryProperties properties) {
this.cloudFoundryService = svc;
this.cloudFoundryOperations = cloudFoundryOperations;
this.properties = properties;
@@ -73,24 +72,22 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient {
String applicationIndex = instanceDetail.getIndex();
String instanceId = applicationId + "." + applicationIndex;
String name = applicationDetail.getName();
String url = applicationDetail.getUrls().size() > 0
? applicationDetail.getUrls().get(0) : null;
String url = applicationDetail.getUrls().size() > 0 ? applicationDetail.getUrls().get(0) : null;
boolean secure = (url + "").toLowerCase().startsWith("https");
HashMap<String, String> metadata = new HashMap<>();
metadata.put("applicationId", applicationId);
metadata.put("instanceId", applicationIndex);
return (ServiceInstance) new DefaultServiceInstance(instanceId, name, url,
secure ? 443 : 80, secure, metadata);
return (ServiceInstance) new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80, secure,
metadata);
}).collectList().blockOptional().orElse(new ArrayList<>());
}
@Override
public List<String> getServices() {
return this.cloudFoundryOperations.applications().list()
.map(ApplicationSummary::getName).collectList().blockOptional()
.orElse(new ArrayList<>());
return this.cloudFoundryOperations.applications().list().map(ApplicationSummary::getName).collectList()
.blockOptional().orElse(new ArrayList<>());
}
@Override

View File

@@ -45,39 +45,32 @@ public class CloudFoundryDiscoveryClientConfiguration {
@Bean
@ConditionalOnBean(CloudFoundryDiscoveryClient.class)
public CloudFoundryHeartbeatSender cloudFoundryHeartbeatSender(
CloudFoundryDiscoveryClient client) {
public CloudFoundryHeartbeatSender cloudFoundryHeartbeatSender(CloudFoundryDiscoveryClient client) {
return new CloudFoundryHeartbeatSender(client);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "false",
matchIfMissing = true)
public static class CloudFoundryDiscoveryClientConfig {
@Bean
@ConditionalOnMissingBean(DiscoveryClient.class)
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(
CloudFoundryOperations cf, CloudFoundryService svc,
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
return new CloudFoundryDiscoveryClient(cf, svc,
cloudFoundryDiscoveryProperties);
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(CloudFoundryOperations cf,
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
return new CloudFoundryDiscoveryClient(cf, svc, cloudFoundryDiscoveryProperties);
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
havingValue = "true")
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "true")
public static class DnsBasedCloudFoundryDiscoveryClientConfig {
@Bean
@ConditionalOnProperty(
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
havingValue = "true")
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "true")
@ConditionalOnMissingBean(DiscoveryClient.class)
public SimpleDnsBasedDiscoveryClient discoveryClient(
ObjectProvider<ServiceIdToHostnameConverter> provider,
public SimpleDnsBasedDiscoveryClient discoveryClient(ObjectProvider<ServiceIdToHostnameConverter> provider,
CloudFoundryDiscoveryProperties properties) {
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
return converter == null ? new SimpleDnsBasedDiscoveryClient(properties)
@@ -85,13 +78,11 @@ public class CloudFoundryDiscoveryClientConfiguration {
}
@Bean
@ConditionalOnProperty(
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "false",
matchIfMissing = true)
@ConditionalOnMissingBean(DiscoveryClient.class)
public CloudFoundryAppServiceDiscoveryClient cloudFoundryDiscoveryClient(
CloudFoundryOperations cf, CloudFoundryService svc,
CloudFoundryDiscoveryProperties properties) {
public CloudFoundryAppServiceDiscoveryClient cloudFoundryDiscoveryClient(CloudFoundryOperations cf,
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
return new CloudFoundryAppServiceDiscoveryClient(cf, svc, properties);
}

View File

@@ -42,8 +42,7 @@ public class CloudFoundryHeartbeatSender implements ApplicationEventPublisherAwa
this.client = client;
}
@Scheduled(
fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
@Scheduled(fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
public void poll() {
if (this.publisher != null) {
List<String> services = this.client.getServices();

View File

@@ -36,8 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.enabled",
matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.enabled", matchIfMissing = true)
public @interface ConditionalOnCloudFoundryDiscoveryEnabled {
}

View File

@@ -40,8 +40,7 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
*/
public class SimpleDnsBasedDiscoveryClient implements DiscoveryClient {
private static final Logger log = LoggerFactory
.getLogger(SimpleDnsBasedDiscoveryClient.class);
private static final Logger log = LoggerFactory.getLogger(SimpleDnsBasedDiscoveryClient.class);
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
@@ -67,8 +66,8 @@ public class SimpleDnsBasedDiscoveryClient implements DiscoveryClient {
InetAddress[] addresses = InetAddress.getAllByName(hostname);
if (addresses != null) {
for (InetAddress address : addresses) {
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(
serviceId, address.getHostAddress(), 8080, false);
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(serviceId,
address.getHostAddress(), 8080, false);
serviceInstances.add(serviceInstance);
}
}

View File

@@ -34,16 +34,14 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
* "https://www.cloudfoundry.org/blog/polyglot-service-discovery-container-networking-cloud-foundry/">Polyglot
* Service Discovery for Container Networking in Cloud Foundry</a>
*/
public class CloudFoundryAppServiceReactiveDiscoveryClient
extends CloudFoundryNativeReactiveDiscoveryClient {
public class CloudFoundryAppServiceReactiveDiscoveryClient extends CloudFoundryNativeReactiveDiscoveryClient {
private static final String INTERNAL_DOMAIN = "apps.internal";
private final CloudFoundryService cloudFoundryService;
CloudFoundryAppServiceReactiveDiscoveryClient(
CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
CloudFoundryAppServiceReactiveDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
this.cloudFoundryService = svc;
}
@@ -56,8 +54,7 @@ public class CloudFoundryAppServiceReactiveDiscoveryClient
@Override
public Flux<ServiceInstance> getInstances(String serviceId) {
return cloudFoundryService.getApplicationInstances(serviceId)
.filter(tuple -> tuple.getT1().getUrls().stream()
.anyMatch(this::isInternalDomain))
.filter(tuple -> tuple.getT1().getUrls().stream().anyMatch(this::isInternalDomain))
.map(this::mapApplicationInstanceToServiceInstance);
}

View File

@@ -37,8 +37,7 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
*
* @author Tim Ysewyn
*/
public class CloudFoundryNativeReactiveDiscoveryClient
implements ReactiveDiscoveryClient {
public class CloudFoundryNativeReactiveDiscoveryClient implements ReactiveDiscoveryClient {
private final CloudFoundryService cloudFoundryService;
@@ -46,8 +45,8 @@ public class CloudFoundryNativeReactiveDiscoveryClient
private final CloudFoundryDiscoveryProperties properties;
CloudFoundryNativeReactiveDiscoveryClient(CloudFoundryOperations operations,
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
CloudFoundryNativeReactiveDiscoveryClient(CloudFoundryOperations operations, CloudFoundryService svc,
CloudFoundryDiscoveryProperties properties) {
this.cloudFoundryService = svc;
this.cloudFoundryOperations = operations;
this.properties = properties;
@@ -66,8 +65,7 @@ public class CloudFoundryNativeReactiveDiscoveryClient
@Override
public Flux<String> getServices() {
return this.cloudFoundryOperations.applications().list()
.map(ApplicationSummary::getName);
return this.cloudFoundryOperations.applications().list().map(ApplicationSummary::getName);
}
@Override
@@ -75,8 +73,7 @@ public class CloudFoundryNativeReactiveDiscoveryClient
return this.properties.getOrder();
}
protected ServiceInstance mapApplicationInstanceToServiceInstance(
Tuple2<ApplicationDetail, InstanceDetail> tuple) {
protected ServiceInstance mapApplicationInstanceToServiceInstance(Tuple2<ApplicationDetail, InstanceDetail> tuple) {
ApplicationDetail applicationDetail = tuple.getT1();
InstanceDetail instanceDetail = tuple.getT2();
@@ -84,16 +81,14 @@ public class CloudFoundryNativeReactiveDiscoveryClient
String applicationIndex = instanceDetail.getIndex();
String instanceId = applicationId + "." + applicationIndex;
String name = applicationDetail.getName();
String url = applicationDetail.getUrls().size() > 0
? applicationDetail.getUrls().get(0) : null;
String url = applicationDetail.getUrls().size() > 0 ? applicationDetail.getUrls().get(0) : null;
boolean secure = (url + "").toLowerCase().startsWith("https");
HashMap<String, String> metadata = new HashMap<>();
metadata.put("applicationId", applicationId);
metadata.put("instanceId", applicationIndex);
return new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80,
secure, metadata);
return new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80, secure, metadata);
}
}

View File

@@ -55,26 +55,22 @@ import org.springframework.context.annotation.Configuration;
public class CloudFoundryReactiveDiscoveryClientConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "false",
matchIfMissing = true)
public static class CloudFoundryNativeReactiveDiscoveryClientConfig {
@Bean
@ConditionalOnMissingBean
public CloudFoundryNativeReactiveDiscoveryClient nativeCloudFoundryDiscoveryClient(
CloudFoundryOperations cf, CloudFoundryService svc,
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
return new CloudFoundryNativeReactiveDiscoveryClient(cf, svc,
cloudFoundryDiscoveryProperties);
public CloudFoundryNativeReactiveDiscoveryClient nativeCloudFoundryDiscoveryClient(CloudFoundryOperations cf,
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
return new CloudFoundryNativeReactiveDiscoveryClient(cf, svc, cloudFoundryDiscoveryProperties);
}
@Bean
@ConditionalOnClass(
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnDiscoveryHealthIndicatorEnabled
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
CloudFoundryNativeReactiveDiscoveryClient client,
DiscoveryClientHealthIndicatorProperties properties) {
CloudFoundryNativeReactiveDiscoveryClient client, DiscoveryClientHealthIndicatorProperties properties) {
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
}
@@ -87,34 +83,27 @@ public class CloudFoundryReactiveDiscoveryClientConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
havingValue = "true")
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "true")
public static class DnsConfig {
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
havingValue = "true")
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "true")
public static class SimpleDnsConfig {
@Bean
@ConditionalOnMissingBean
public SimpleDnsBasedReactiveDiscoveryClient dnsBasedReactiveDiscoveryClient(
ObjectProvider<ServiceIdToHostnameConverter> provider,
CloudFoundryDiscoveryProperties properties) {
ObjectProvider<ServiceIdToHostnameConverter> provider, CloudFoundryDiscoveryProperties properties) {
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
return converter == null
? new SimpleDnsBasedReactiveDiscoveryClient(properties)
return converter == null ? new SimpleDnsBasedReactiveDiscoveryClient(properties)
: new SimpleDnsBasedReactiveDiscoveryClient(converter);
}
@Bean
@ConditionalOnClass(
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnDiscoveryHealthIndicatorEnabled
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
SimpleDnsBasedReactiveDiscoveryClient client,
DiscoveryClientHealthIndicatorProperties properties) {
SimpleDnsBasedReactiveDiscoveryClient client, DiscoveryClientHealthIndicatorProperties properties) {
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
}
@@ -127,23 +116,19 @@ public class CloudFoundryReactiveDiscoveryClientConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
havingValue = "false", matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "false",
matchIfMissing = true)
public static class AppServiceConfig {
@Bean
@ConditionalOnMissingBean
public CloudFoundryAppServiceReactiveDiscoveryClient appServiceReactiveDiscoveryClient(
CloudFoundryOperations cf, CloudFoundryService svc,
CloudFoundryDiscoveryProperties properties) {
return new CloudFoundryAppServiceReactiveDiscoveryClient(cf, svc,
properties);
CloudFoundryOperations cf, CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
return new CloudFoundryAppServiceReactiveDiscoveryClient(cf, svc, properties);
}
@Bean
@ConditionalOnClass(
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
@ConditionalOnDiscoveryHealthIndicatorEnabled
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
CloudFoundryAppServiceReactiveDiscoveryClient client,

View File

@@ -30,8 +30,7 @@ import org.springframework.stereotype.Component;
* @author Tim Ysewyn
*/
@Component
public class CloudFoundryReactiveHeartbeatSender
implements ApplicationEventPublisherAware {
public class CloudFoundryReactiveHeartbeatSender implements ApplicationEventPublisherAware {
private final ReactiveDiscoveryClient client;
@@ -41,12 +40,10 @@ public class CloudFoundryReactiveHeartbeatSender
this.client = client;
}
@Scheduled(
fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
@Scheduled(fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
public void poll() {
if (this.publisher != null) {
this.publisher.publishEvent(
new HeartbeatEvent(this.client, this.client.getServices()));
this.publisher.publishEvent(new HeartbeatEvent(this.client, this.client.getServices()));
}
}

View File

@@ -42,18 +42,15 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
*/
public class SimpleDnsBasedReactiveDiscoveryClient implements ReactiveDiscoveryClient {
private static final Logger log = LoggerFactory
.getLogger(SimpleDnsBasedReactiveDiscoveryClient.class);
private static final Logger log = LoggerFactory.getLogger(SimpleDnsBasedReactiveDiscoveryClient.class);
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
public SimpleDnsBasedReactiveDiscoveryClient(
ServiceIdToHostnameConverter serviceIdToHostnameConverter) {
public SimpleDnsBasedReactiveDiscoveryClient(ServiceIdToHostnameConverter serviceIdToHostnameConverter) {
this.serviceIdToHostnameConverter = serviceIdToHostnameConverter;
}
public SimpleDnsBasedReactiveDiscoveryClient(
CloudFoundryDiscoveryProperties properties) {
public SimpleDnsBasedReactiveDiscoveryClient(CloudFoundryDiscoveryProperties properties) {
this(serviceId -> serviceId + "." + properties.getInternalDomain());
}
@@ -64,10 +61,8 @@ public class SimpleDnsBasedReactiveDiscoveryClient implements ReactiveDiscoveryC
@Override
public Flux<ServiceInstance> getInstances(String serviceId) {
return Mono.justOrEmpty(serviceIdToHostnameConverter.toHostname(serviceId))
.flatMapMany(getInetAddresses())
.map(address -> new DefaultServiceInstance(serviceId,
address.getHostAddress(), 8080, false));
return Mono.justOrEmpty(serviceIdToHostnameConverter.toHostname(serviceId)).flatMapMany(getInetAddresses())
.map(address -> new DefaultServiceInstance(serviceId, address.getHostAddress(), 8080, false));
}
private Function<String, Publisher<? extends InetAddress>> getInetAddresses() {

View File

@@ -50,26 +50,23 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
public void setUp() {
this.cloudFoundryOperations = mock(CloudFoundryOperations.class);
this.cloudFoundryService = mock(CloudFoundryService.class);
this.discoveryClient = new CloudFoundryAppServiceDiscoveryClient(
this.cloudFoundryOperations, this.cloudFoundryService,
new CloudFoundryDiscoveryProperties());
this.discoveryClient = new CloudFoundryAppServiceDiscoveryClient(this.cloudFoundryOperations,
this.cloudFoundryService, new CloudFoundryDiscoveryProperties());
}
@Test
public void getInstancesOneInstance() {
String serviceId = "billing";
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1")
.name("billing").instances(1).memoryLimit(1024).stack("cflinux2")
.diskQuota(1024).requestedState("Running").runningInstances(1)
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1").name("billing").instances(1)
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(1)
.urls("billing.apps.example.com", "billing.apps.internal").build();
given(this.cloudFoundryService.getApplicationInstances(serviceId))
.willReturn(Flux.just(Tuples.of(applicationDetail,
InstanceDetail.builder().index("0").build())));
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build())));
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
assertThat(instances).hasSize(1);
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId,
"0.billing.apps.internal", 8080, false, new HashMap<String, String>() {
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId, "0.billing.apps.internal", 8080,
false, new HashMap<String, String>() {
{
put("applicationId", "billing1");
put("instanceId", "0");
@@ -80,37 +77,32 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
@Test
public void getInstancesThreeInstance() {
String serviceId = "billing";
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing-id")
.name("billing").instances(3).memoryLimit(1024).stack("cflinux2")
.diskQuota(1024).requestedState("Running").runningInstances(3)
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing-id").name("billing").instances(3)
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(3)
.urls("billing.apps.example.com", "billing.apps.internal").build();
given(this.cloudFoundryService.getApplicationInstances(serviceId))
.willReturn(Flux.just(
Tuples.of(applicationDetail,
InstanceDetail.builder().index("0").build()),
Tuples.of(applicationDetail,
InstanceDetail.builder().index("1").build()),
Tuples.of(applicationDetail,
InstanceDetail.builder().index("2").build())));
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build()),
Tuples.of(applicationDetail, InstanceDetail.builder().index("1").build()),
Tuples.of(applicationDetail, InstanceDetail.builder().index("2").build())));
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
assertThat(instances).hasSize(3);
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId,
"0.billing.apps.internal", 8080, false, new HashMap<String, String>() {
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId, "0.billing.apps.internal", 8080,
false, new HashMap<String, String>() {
{
put("applicationId", "billing-id");
put("instanceId", "0");
}
}));
assertThat(instances.get(1)).isEqualTo(new DefaultServiceInstance(serviceId,
"1.billing.apps.internal", 8080, false, new HashMap<String, String>() {
assertThat(instances.get(1)).isEqualTo(new DefaultServiceInstance(serviceId, "1.billing.apps.internal", 8080,
false, new HashMap<String, String>() {
{
put("applicationId", "billing-id");
put("instanceId", "1");
}
}));
assertThat(instances.get(2)).isEqualTo(new DefaultServiceInstance(serviceId,
"2.billing.apps.internal", 8080, false, new HashMap<String, String>() {
assertThat(instances.get(2)).isEqualTo(new DefaultServiceInstance(serviceId, "2.billing.apps.internal", 8080,
false, new HashMap<String, String>() {
{
put("applicationId", "billing-id");
put("instanceId", "2");
@@ -121,13 +113,11 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
@Test
public void getInstancesEmpty() {
String serviceId = "billing";
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1")
.name("billing").instances(1).memoryLimit(1024).stack("cflinux2")
.diskQuota(1024).requestedState("Running").runningInstances(1)
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1").name("billing").instances(1)
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(1)
.url("billing.apps.example.com").build();
given(this.cloudFoundryService.getApplicationInstances(serviceId))
.willReturn(Flux.just(Tuples.of(applicationDetail,
InstanceDetail.builder().index("0").build())));
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build())));
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
assertThat(instances).isEmpty();

View File

@@ -37,41 +37,31 @@ import static org.assertj.core.api.Assertions.assertThat;
public class CloudFoundryDiscoveryClientConfigurationTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations
.of(CloudFoundryDiscoveryClientConfiguration.class));
.withConfiguration(AutoConfigurations.of(CloudFoundryDiscoveryClientConfiguration.class));
@Test
public void testDefault() {
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
.run((context) -> {
DiscoveryClient discoveryClient = context
.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass())
.isEqualTo(CloudFoundryDiscoveryClient.class);
});
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class).run((context) -> {
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryDiscoveryClient.class);
});
}
@Test
public void testUseDnsTrue() {
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true")
.run((context) -> {
DiscoveryClient discoveryClient = context
.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass())
.isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true").run((context) -> {
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
});
}
@Test
public void testUseDnsFalse() {
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=false")
.run((context) -> {
DiscoveryClient discoveryClient = context
.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass())
.isEqualTo(CloudFoundryDiscoveryClient.class);
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=false").run((context) -> {
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryDiscoveryClient.class);
});
}
@@ -81,23 +71,17 @@ public class CloudFoundryDiscoveryClientConfigurationTest {
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
.run((context) -> {
DiscoveryClient discoveryClient = context
.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass())
.isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
});
}
@Test
public void testUseContainerIpTrue() {
this.contextRunner
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
"spring.cloud.cloudfoundry.discovery.use-container-ip=true")
.run((context) -> {
DiscoveryClient discoveryClient = context
.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass())
.isEqualTo(SimpleDnsBasedDiscoveryClient.class);
this.contextRunner.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
"spring.cloud.cloudfoundry.discovery.use-container-ip=true").run((context) -> {
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
assertThat(discoveryClient.getClass()).isEqualTo(SimpleDnsBasedDiscoveryClient.class);
});
}

View File

@@ -58,42 +58,35 @@ public class CloudFoundryDiscoveryClientTest {
public void setUp() {
this.ops = mock(CloudFoundryOperations.class);
this.svc = mock(CloudFoundryService.class);
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(this.ops,
this.svc, new CloudFoundryDiscoveryProperties());
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(this.ops, this.svc,
new CloudFoundryDiscoveryProperties());
}
@Test
public void testServiceResolution() {
Applications apps = mock(Applications.class);
ApplicationSummary s = ApplicationSummary.builder()
.id(UUID.randomUUID().toString()).instances(2).memoryLimit(1024)
.requestedState("requestedState").diskQuota(1024)
.name(this.hiServiceServiceId).runningInstances(2).build();
ApplicationSummary s = ApplicationSummary.builder().id(UUID.randomUUID().toString()).instances(2)
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name(this.hiServiceServiceId)
.runningInstances(2).build();
Mockito.when(apps.list()).thenReturn(Flux.just(s));
Mockito.when(this.ops.applications()).thenReturn(apps);
List<String> serviceNames = this.cloudFoundryDiscoveryClient.getServices();
assertThat(serviceNames.contains(this.hiServiceServiceId))
.as("there should be one registered service.").isTrue();
serviceNames.forEach(serviceName -> this.log
.debug("\t discovered serviceName: " + serviceName));
assertThat(serviceNames.contains(this.hiServiceServiceId)).as("there should be one registered service.")
.isTrue();
serviceNames.forEach(serviceName -> this.log.debug("\t discovered serviceName: " + serviceName));
}
@Test
public void testInstances() {
ApplicationDetail applicationDetail = ApplicationDetail.builder().instances(2)
.name("my-app").stack("stack").memoryLimit(1024).id("id")
.requestedState("requestedState").runningInstances(2)
ApplicationDetail applicationDetail = ApplicationDetail.builder().instances(2).name("my-app").stack("stack")
.memoryLimit(1024).id("id").requestedState("requestedState").runningInstances(2)
.url("http://my-app-cfapps-io").diskQuota(20).build();
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
Tuple2<ApplicationDetail, InstanceDetail> tuple2 = Tuples.of(applicationDetail,
instanceDetail);
Mockito.when(this.svc.getApplicationInstances(this.hiServiceServiceId))
.thenReturn(Flux.just(tuple2));
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient
.getInstances(this.hiServiceServiceId);
Tuple2<ApplicationDetail, InstanceDetail> tuple2 = Tuples.of(applicationDetail, instanceDetail);
Mockito.when(this.svc.getApplicationInstances(this.hiServiceServiceId)).thenReturn(Flux.just(tuple2));
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient.getInstances(this.hiServiceServiceId);
assertThat(instances.size()).as("Wrong instances: " + instances).isEqualTo(1);
assertThat(instances.get(0).getInstanceId()).as("Wrong instance ID")
.isEqualTo("id.0");
assertThat(instances.get(0).getInstanceId()).as("Wrong instance ID").isEqualTo("id.0");
}
}

View File

@@ -49,22 +49,17 @@ class CloudFoundryAppServiceReactiveDiscoveryClientTests {
@Test
public void shouldReturnFluxOfServiceInstances() {
ApplicationDetail appDetail1 = ApplicationDetail.builder()
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
.name("service").runningInstances(1).url("instance.apps.internal")
.build();
ApplicationDetail appDetail1 = ApplicationDetail.builder().id(UUID.randomUUID().toString()).stack("stack")
.instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service")
.runningInstances(1).url("instance.apps.internal").build();
Tuple2<ApplicationDetail, InstanceDetail> instance1 = Tuples.of(appDetail1,
InstanceDetail.builder().index("0").build());
ApplicationDetail appDetail2 = ApplicationDetail.builder()
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
.name("service").runningInstances(1).url("instance.apps.not.internal")
.build();
ApplicationDetail appDetail2 = ApplicationDetail.builder().id(UUID.randomUUID().toString()).stack("stack")
.instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service")
.runningInstances(1).url("instance.apps.not.internal").build();
Tuple2<ApplicationDetail, InstanceDetail> instance2 = Tuples.of(appDetail2,
InstanceDetail.builder().index("0").build());
when(this.svc.getApplicationInstances("service"))
.thenReturn(Flux.just(instance1, instance2));
when(this.svc.getApplicationInstances("service")).thenReturn(Flux.just(instance1, instance2));
Flux<ServiceInstance> instances = this.client.getInstances("service");
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
}

View File

@@ -62,8 +62,7 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
@Test
public void verifyDefaults() {
when(properties.getOrder()).thenReturn(0);
assertThat(client.description())
.isEqualTo("CF Reactive Service Discovery Client");
assertThat(client.description()).isEqualTo("CF Reactive Service Discovery Client");
assertThat(client.getOrder()).isEqualTo(0);
}
@@ -71,10 +70,9 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
public void shouldReturnFluxOfServices() {
Applications apps = mock(Applications.class);
when(operations.applications()).thenReturn(apps);
ApplicationSummary summary = ApplicationSummary.builder()
.id(UUID.randomUUID().toString()).instances(1).memoryLimit(1024)
.requestedState("requestedState").diskQuota(1024).name("service")
.runningInstances(1).build();
ApplicationSummary summary = ApplicationSummary.builder().id(UUID.randomUUID().toString()).instances(1)
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service").runningInstances(1)
.build();
when(apps.list()).thenReturn(Flux.just(summary));
Flux<String> services = this.client.getServices();
StepVerifier.create(services).expectNext("service").expectComplete().verify();
@@ -89,13 +87,11 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
@Test
public void shouldReturnFluxOfServiceInstances() {
ApplicationDetail applicationDetail = ApplicationDetail.builder()
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
ApplicationDetail applicationDetail = ApplicationDetail.builder().id(UUID.randomUUID().toString())
.stack("stack").instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
.name("service").runningInstances(1).build();
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
Tuple2<ApplicationDetail, InstanceDetail> instance = Tuples.of(applicationDetail,
instanceDetail);
Tuple2<ApplicationDetail, InstanceDetail> instance = Tuples.of(applicationDetail, instanceDetail);
when(this.svc.getApplicationInstances("service")).thenReturn(Flux.just(instance));
Flux<ServiceInstance> instances = this.client.getInstances("service");
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();

View File

@@ -39,138 +39,100 @@ import static org.mockito.Mockito.mock;
*/
class CloudFoundryReactiveDiscoveryClientConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(MockedCloudFoundryConfiguration.class,
CloudFoundryReactiveDiscoveryClientConfiguration.class));
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
.of(MockedCloudFoundryConfiguration.class, CloudFoundryReactiveDiscoveryClientConfiguration.class));
@Test
public void shouldNotHaveDiscoveryClientsWhenDiscoveryDisabled() {
contextRunner.withPropertyValues("spring.cloud.discovery.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(
ReactiveDiscoveryClientHealthIndicator.class);
});
contextRunner.withPropertyValues("spring.cloud.discovery.enabled=false").run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldNotHaveDiscoveryClientsWhenReactiveDiscoveryDisabled() {
contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(
ReactiveDiscoveryClientHealthIndicator.class);
});
contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false").run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldNotHaveDiscoveryClientsWhenCloudFoundryDiscoveryDisabled() {
contextRunner
.withPropertyValues("spring.cloud.cloudfoundry.discovery.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(
ReactiveDiscoveryClientHealthIndicator.class);
});
contextRunner.withPropertyValues("spring.cloud.cloudfoundry.discovery.enabled=false").run(context -> {
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldUseNativeDiscovery() {
contextRunner
.withConfiguration(AutoConfigurations
.of(ReactiveCommonsClientAutoConfiguration.class))
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
.run(context -> {
assertThat(context)
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
assertThat(context)
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldUseDnsDiscovery() {
contextRunner
.withConfiguration(AutoConfigurations
.of(ReactiveCommonsClientAutoConfiguration.class))
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
"spring.cloud.cloudfoundry.discovery.use-container-ip=true")
.run(context -> {
assertThat(context)
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
assertThat(context).hasBean("dnsBasedReactiveDiscoveryClient");
assertThat(context)
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldUseAppServiceDiscovery() {
contextRunner
.withConfiguration(AutoConfigurations
.of(ReactiveCommonsClientAutoConfiguration.class))
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
.run(context -> {
assertThat(context)
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
assertThat(context).hasBean("appServiceReactiveDiscoveryClient");
assertThat(context)
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void shouldUseCustomServiceDiscovery() {
contextRunner
.withConfiguration(AutoConfigurations
.of(ReactiveCommonsClientAutoConfiguration.class))
.withUserConfiguration(
CustomCloudFoundryReactiveDiscoveryClientConfiguration.class)
.run(context -> {
assertThat(context)
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).getBeans(ReactiveDiscoveryClient.class)
.hasSize(2);
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
.withUserConfiguration(CustomCloudFoundryReactiveDiscoveryClientConfiguration.class).run(context -> {
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).getBeans(ReactiveDiscoveryClient.class).hasSize(2);
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
assertThat(context)
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void worksWithoutWebflux() {
contextRunner
.withClassLoader(
new FilteredClassLoader("org.springframework.web.reactive"))
.run(context -> {
assertThat(context)
.doesNotHaveBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(
ReactiveDiscoveryClientHealthIndicator.class);
});
contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.reactive")).run(context -> {
assertThat(context).doesNotHaveBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@Test
public void worksWithoutActuator() {
contextRunner
.withClassLoader(
new FilteredClassLoader("org.springframework.boot.actuate"))
.run(context -> {
assertThat(context)
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(
ReactiveDiscoveryClientHealthIndicator.class);
});
contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.boot.actuate")).run(context -> {
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
});
}
@TestConfiguration