diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicator.java index 7708fa8780..c708246320 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicator.java @@ -24,6 +24,7 @@ import reactor.core.scheduler.Schedulers; import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.data.redis.connection.ReactiveRedisClusterConnection; import org.springframework.data.redis.connection.ReactiveRedisConnection; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; @@ -33,6 +34,7 @@ import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; * @author Stephane Nicoll * @author Mark Paluch * @author Artsiom Yudovin + * @author Scott Frederick * @since 2.0.0 */ public class RedisReactiveHealthIndicator extends AbstractReactiveHealthIndicator { @@ -50,7 +52,8 @@ public class RedisReactiveHealthIndicator extends AbstractReactiveHealthIndicato } private Mono doHealthCheck(Health.Builder builder, ReactiveRedisConnection connection) { - return connection.serverCommands().info().map((info) -> up(builder, info)) + return connection.serverCommands().info() + .map((info) -> up(builder, info, (connection instanceof ReactiveRedisClusterConnection))) .onErrorResume((ex) -> Mono.just(down(builder, ex))) .flatMap((health) -> connection.closeLater().thenReturn(health)); } @@ -60,9 +63,21 @@ public class RedisReactiveHealthIndicator extends AbstractReactiveHealthIndicato .subscribeOn(Schedulers.boundedElastic()); } - private Health up(Health.Builder builder, Properties info) { - return builder.up() - .withDetail(RedisHealthIndicator.VERSION, info.getProperty(RedisHealthIndicator.REDIS_VERSION)).build(); + private Health up(Health.Builder builder, Properties info, boolean isClusterConnection) { + if (isClusterConnection) { + return builder.up().withDetail(RedisHealthIndicator.VERSION, getClusterVersionProperty(info)).build(); + } + else { + return builder.up() + .withDetail(RedisHealthIndicator.VERSION, info.getProperty(RedisHealthIndicator.REDIS_VERSION)) + .build(); + } + } + + private Object getClusterVersionProperty(Properties info) { + return info.keySet().stream().map(String.class::cast) + .filter((key) -> key.endsWith(RedisHealthIndicator.REDIS_VERSION)).findFirst().map(info::get) + .orElse(""); } private Health down(Health.Builder builder, Throwable cause) { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java index 6fcce879c3..078962266d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/redis/RedisReactiveHealthIndicatorTests.java @@ -26,6 +26,8 @@ import reactor.test.StepVerifier; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Status; import org.springframework.data.redis.RedisConnectionFailureException; +import org.springframework.data.redis.connection.ReactiveClusterServerCommands; +import org.springframework.data.redis.connection.ReactiveRedisClusterConnection; import org.springframework.data.redis.connection.ReactiveRedisConnection; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; import org.springframework.data.redis.connection.ReactiveServerCommands; @@ -42,6 +44,7 @@ import static org.mockito.Mockito.verify; * @author Mark Paluch * @author Nikolay Rybak * @author Artsiom Yudovin + * @author Scott Frederick */ class RedisReactiveHealthIndicatorTests { @@ -63,6 +66,24 @@ class RedisReactiveHealthIndicatorTests { verify(redisConnection).closeLater(); } + @Test + void redisClusterIsUp() { + Properties info = new Properties(); + info.put("127.0.0.1:7002.redis_version", "2.8.9"); + ReactiveRedisConnection redisConnection = mock(ReactiveRedisClusterConnection.class); + given(redisConnection.closeLater()).willReturn(Mono.empty()); + ReactiveClusterServerCommands commands = mock(ReactiveClusterServerCommands.class); + given(commands.info()).willReturn(Mono.just(info)); + RedisReactiveHealthIndicator healthIndicator = createHealthIndicator(redisConnection, commands); + Mono health = healthIndicator.health(); + StepVerifier.create(health).consumeNextWith((h) -> { + assertThat(h.getStatus()).isEqualTo(Status.UP); + assertThat(h.getDetails()).containsOnlyKeys("version"); + assertThat(h.getDetails().get("version")).isEqualTo("2.8.9"); + }).verifyComplete(); + verify(redisConnection).closeLater(); + } + @Test void redisCommandIsDown() { ReactiveServerCommands commands = mock(ReactiveServerCommands.class);