Added support for ReactiveHealthIndicator. (#3903)

This commit is contained in:
joyita07
2020-10-30 06:36:13 -07:00
committed by GitHub
parent 6ce8123be1
commit 78ca251e96
2 changed files with 101 additions and 17 deletions

View File

@@ -17,12 +17,14 @@
package org.springframework.cloud.netflix.eureka;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
@@ -32,6 +34,7 @@ import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicatorRegistryFactory;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthContributor;
@@ -40,8 +43,6 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import static com.netflix.appinfo.InstanceInfo.InstanceStatus;
/**
* A Eureka health checker, maps the application status into {@link InstanceStatus} that
* will be propagated to Eureka registry.
@@ -52,6 +53,7 @@ import static com.netflix.appinfo.InstanceInfo.InstanceStatus;
*
* @author Jakub Narloch
* @author Spencer Gibb
* @author Nowrin Anwar Joyita
* @see HealthCheckHandler
* @see StatusAggregator
* @see HealthAggregator
@@ -74,6 +76,8 @@ public class EurekaHealthCheckHandler
private Map<String, HealthIndicator> healthIndicators;
private Map<String, ReactiveHealthIndicator> reactiveHealthIndicators = new HashMap<>();
@Deprecated
private CompositeHealthIndicator healthIndicator;
@@ -110,8 +114,12 @@ public class EurekaHealthCheckHandler
.getBeansOfType(HealthIndicator.class);
this.healthIndicators = new HashMap<>();
final Map<String, ReactiveHealthIndicator> reactiveHealthIndicators = applicationContext
.getBeansOfType(ReactiveHealthIndicator.class);
if (statusAggregator != null) {
populateHealthIndicators(healthIndicators);
populateReactiveHealthIndicators(reactiveHealthIndicators);
}
else {
createHealthIndicator(healthIndicators);
@@ -165,6 +173,14 @@ public class EurekaHealthCheckHandler
}
}
void populateReactiveHealthIndicators(
Map<String, ReactiveHealthIndicator> reactiveHealthIndicators) {
for (Map.Entry<String, ReactiveHealthIndicator> entry : reactiveHealthIndicators
.entrySet()) {
this.reactiveHealthIndicators.put(entry.getKey(), entry.getValue());
}
}
@Override
public InstanceStatus getStatus(InstanceStatus instanceStatus) {
return getHealthStatus();
@@ -190,9 +206,21 @@ public class EurekaHealthCheckHandler
protected Status getStatus(StatusAggregator statusAggregator) {
Status status;
Set<Status> statusSet = healthIndicators.values().stream()
.map(HealthIndicator::health).map(Health::getStatus)
.collect(Collectors.toSet());
Set<Status> statusSet = new HashSet<>();
if (healthIndicators != null) {
statusSet.addAll(
healthIndicators.values().stream().map(HealthIndicator::health)
.map(Health::getStatus).collect(Collectors.toSet()));
}
if (reactiveHealthIndicators != null) {
statusSet.addAll(reactiveHealthIndicators.values().stream()
.map(ReactiveHealthIndicator::health).map(health -> {
return health.block().getStatus();
}).collect(Collectors.toSet()));
}
status = statusAggregator.getAggregateStatus(statusSet);
return status;
}

View File

@@ -21,11 +21,15 @@ import java.util.List;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicator;
import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthIndicator;
import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator;
@@ -39,27 +43,29 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests the {@link EurekaHealthCheckHandler} with different health indicator registered.
*
* @author Jakub Narloch
* @author Nowrin Anwar Joyita
*/
public class EurekaHealthCheckHandlerTests {
private EurekaHealthCheckHandler healthCheckHandler;
private EurekaHealthCheckHandler healthCheckHandlerWithStatusAggregator;
@Before
public void setUp() throws Exception {
healthCheckHandler = new EurekaHealthCheckHandler(new OrderedHealthAggregator());
healthCheckHandler = new EurekaHealthCheckHandler(
new OrderedHealthAggregator());
healthCheckHandlerWithStatusAggregator = new EurekaHealthCheckHandler(
new SimpleStatusAggregator());
}
@Test
public void testNoHealthCheckRegistered() throws Exception {
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
assertThat(status).isEqualTo(InstanceStatus.UNKNOWN);
}
@Test
public void testAllUp() throws Exception {
initialize(UpHealthConfiguration.class);
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
@@ -67,8 +73,7 @@ public class EurekaHealthCheckHandlerTests {
}
@Test
public void testDown() throws Exception {
public void testDownWithBlockingIndicators() throws Exception {
initialize(UpHealthConfiguration.class, DownHealthConfiguration.class);
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
@@ -76,8 +81,35 @@ public class EurekaHealthCheckHandlerTests {
}
@Test
public void testUnknown() throws Exception {
public void testDownWithReactiveIndicators() throws Exception {
initialize(ReactiveUpHealthConfiguration.class,
ReactiveDownHealthConfiguration.class);
InstanceStatus status = healthCheckHandlerWithStatusAggregator
.getStatus(InstanceStatus.UNKNOWN);
assertThat(status).isEqualTo(InstanceStatus.DOWN);
}
@Test
public void testDownWhenBlockingIndicatorUpAndReactiveDown() throws Exception {
initialize(UpHealthConfiguration.class, ReactiveDownHealthConfiguration.class);
InstanceStatus status = healthCheckHandlerWithStatusAggregator
.getStatus(InstanceStatus.UNKNOWN);
assertThat(status).isEqualTo(InstanceStatus.DOWN);
}
@Test
public void testDownWhenBlockingIndicatorDownAndReactiveUp() throws Exception {
initialize(DownHealthConfiguration.class, ReactiveUpHealthConfiguration.class);
InstanceStatus status = healthCheckHandlerWithStatusAggregator
.getStatus(InstanceStatus.UNKNOWN);
assertThat(status).isEqualTo(InstanceStatus.DOWN);
}
@Test
public void testUnknown() throws Exception {
initialize(FatalHealthConfiguration.class);
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UNKNOWN);
@@ -86,7 +118,6 @@ public class EurekaHealthCheckHandlerTests {
@Test
public void testEurekaIgnored() throws Exception {
initialize(EurekaDownHealthConfiguration.class);
InstanceStatus status = healthCheckHandler.getStatus(InstanceStatus.UP);
@@ -98,10 +129,12 @@ public class EurekaHealthCheckHandlerTests {
configurations);
healthCheckHandler.setApplicationContext(applicationContext);
healthCheckHandler.afterPropertiesSet();
healthCheckHandlerWithStatusAggregator
.setApplicationContext(applicationContext);
healthCheckHandlerWithStatusAggregator.afterPropertiesSet();
}
public static class UpHealthConfiguration {
@Bean
public HealthIndicator healthIndicator() {
return new AbstractHealthIndicator() {
@@ -115,7 +148,6 @@ public class EurekaHealthCheckHandlerTests {
}
public static class DownHealthConfiguration {
@Bean
public HealthIndicator healthIndicator() {
return new AbstractHealthIndicator() {
@@ -129,7 +161,6 @@ public class EurekaHealthCheckHandlerTests {
}
public static class FatalHealthConfiguration {
@Bean
public HealthIndicator healthIndicator() {
return new AbstractHealthIndicator() {
@@ -142,8 +173,33 @@ public class EurekaHealthCheckHandlerTests {
}
public static class EurekaDownHealthConfiguration {
public static class ReactiveUpHealthConfiguration {
@Bean
public ReactiveHealthIndicator reactiveHealthIndicator() {
return new AbstractReactiveHealthIndicator() {
@Override
protected Mono<Health> doHealthCheck(Health.Builder builder) {
return Mono.just(builder.up().build());
}
};
}
}
public static class ReactiveDownHealthConfiguration {
@Bean
public ReactiveHealthIndicator reactiveHealthIndicator() {
return new AbstractReactiveHealthIndicator() {
@Override
protected Mono<Health> doHealthCheck(Health.Builder builder) {
return Mono.just(builder.down().build());
}
};
}
}
public static class EurekaDownHealthConfiguration {
@Bean
public DiscoveryHealthIndicator discoveryHealthIndicator() {
return new DiscoveryClientHealthIndicator(null, null) {