Handle AbstractReactiveHealthIndicator.doHealthCheck exception

Exceptions inside AbstractReactiveHealthIndicator.doHealthCheck()
method, outside of Mono pipeline, could fail whole endpoint
response instead of returning `DOWN` status from indicator.

See gh-10822
This commit is contained in:
Nikolay Rybak 2017-10-30 16:24:14 +02:00 committed by Stephane Nicoll
parent c50a0d855f
commit 99c2fa699e
2 changed files with 25 additions and 3 deletions

View File

@ -29,8 +29,17 @@ public abstract class AbstractReactiveHealthIndicator implements ReactiveHealthI
@Override
public final Mono<Health> health() {
return doHealthCheck(new Health.Builder())
.onErrorResume((ex) -> Mono.just(new Health.Builder().down(ex).build()));
try {
return doHealthCheck(new Health.Builder())
.onErrorResume(this::handleFailure);
}
catch (Throwable ex) {
return handleFailure(ex);
}
}
private Mono<Health> handleFailure(Throwable ex) {
return Mono.just(new Health.Builder().down(ex).build());
}
/**

View File

@ -18,6 +18,7 @@ package org.springframework.boot.actuate.redis;
import java.util.Properties;
import io.lettuce.core.RedisConnectionException;
import org.junit.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@ -61,7 +62,7 @@ public class RedisReactiveHealthIndicatorTests {
}
@Test
public void redisIsDown() throws Exception {
public void redisCommandIsDown() throws Exception {
ReactiveServerCommands commands = mock(ReactiveServerCommands.class);
given(commands.info()).willReturn(
Mono.error(new RedisConnectionFailureException("Connection failed")));
@ -75,6 +76,18 @@ public class RedisReactiveHealthIndicatorTests {
verify(redisConnection).close();
}
@Test
public void redisConnectionIsDown() throws Exception {
ReactiveRedisConnectionFactory redisConnectionFactory = mock(ReactiveRedisConnectionFactory.class);
given(redisConnectionFactory.getReactiveConnection()).willThrow(
new RedisConnectionException("Unable to connect to localhost:6379"));
RedisReactiveHealthIndicator healthIndicator = new RedisReactiveHealthIndicator(redisConnectionFactory);
Mono<Health> health = healthIndicator.health();
StepVerifier.create(health)
.consumeNextWith((h) -> assertThat(h.getStatus()).isEqualTo(Status.DOWN))
.verifyComplete();
}
private RedisReactiveHealthIndicator createHealthIndicator(
ReactiveRedisConnection redisConnection,
ReactiveServerCommands serverCommands) {