diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java index 363c7d08239..c843105d726 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.jms.ConnectionFactory; import javax.sql.DataSource; +import com.datastax.driver.core.Cluster; import org.apache.solr.client.solrj.SolrServer; import org.elasticsearch.client.Client; @@ -29,6 +30,7 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.ApplicationHealthIndicator; +import org.springframework.boot.actuate.health.CassandraHealthIndicator; import org.springframework.boot.actuate.health.CompositeHealthIndicator; import org.springframework.boot.actuate.health.DataSourceHealthIndicator; import org.springframework.boot.actuate.health.DiskSpaceHealthIndicator; @@ -48,9 +50,11 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -66,6 +70,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.ResolvableType; +import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.jdbc.core.JdbcTemplate; @@ -78,15 +83,17 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; * @author Andy Wilkinson * @author Stephane Nicoll * @author Phillip Webb + * @author Tommy Ludwig * @since 1.1.0 */ @Configuration @AutoConfigureBefore({ EndpointAutoConfiguration.class }) -@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MongoAutoConfiguration.class, - MongoDataAutoConfiguration.class, RedisAutoConfiguration.class, - RabbitAutoConfiguration.class, SolrAutoConfiguration.class, - MailSenderAutoConfiguration.class, JmsAutoConfiguration.class, - ElasticsearchAutoConfiguration.class }) +@AutoConfigureAfter({ CassandraAutoConfiguration.class, + CassandraDataAutoConfiguration.class, DataSourceAutoConfiguration.class, + MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + RedisAutoConfiguration.class, RabbitAutoConfiguration.class, + SolrAutoConfiguration.class, MailSenderAutoConfiguration.class, + JmsAutoConfiguration.class, ElasticsearchAutoConfiguration.class }) @EnableConfigurationProperties({ HealthIndicatorAutoConfigurationProperties.class }) public class HealthIndicatorAutoConfiguration { @@ -151,6 +158,24 @@ public class HealthIndicatorAutoConfiguration { } + @Configuration + @ConditionalOnClass({ CassandraOperations.class, Cluster.class }) + @ConditionalOnBean(CassandraOperations.class) + @ConditionalOnEnabledHealthIndicator("cassandra") + public static class CassandraHealthIndicatorConfiguration extends + CompositeHealthIndicatorConfiguration { + + @Autowired + private Map cassandraOperations; + + @Bean + @ConditionalOnMissingBean(name = "cassandraHealthIndicator") + public HealthIndicator cassandraHealthIndicator() { + return createHealthIndicator(this.cassandraOperations); + } + + } + @Configuration @ConditionalOnClass(JdbcTemplate.class) @ConditionalOnBean(DataSource.class) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CassandraHealthIndicator.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CassandraHealthIndicator.java index bd7ed32e96b..6c35cedb225 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CassandraHealthIndicator.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CassandraHealthIndicator.java @@ -20,7 +20,7 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; -import org.springframework.data.cassandra.core.CassandraAdminOperations; +import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.util.Assert; /** @@ -32,16 +32,15 @@ import org.springframework.util.Assert; */ public class CassandraHealthIndicator extends AbstractHealthIndicator { - private CassandraAdminOperations cassandraAdminOperations; + private CassandraOperations cassandraOperations; /** * Create a new {@link CassandraHealthIndicator} instance. - * @param cassandraAdminOperations the Cassandra admin operations + * @param cassandraOperations the Cassandra operations */ - public CassandraHealthIndicator(CassandraAdminOperations cassandraAdminOperations) { - Assert.notNull(cassandraAdminOperations, - "CassandraAdminOperations must not be null"); - this.cassandraAdminOperations = cassandraAdminOperations; + public CassandraHealthIndicator(CassandraOperations cassandraOperations) { + Assert.notNull(cassandraOperations, "CassandraOperations must not be null"); + this.cassandraOperations = cassandraOperations; } @Override @@ -49,7 +48,7 @@ public class CassandraHealthIndicator extends AbstractHealthIndicator { try { Select select = QueryBuilder.select("release_version").from("system", "local"); - ResultSet results = this.cassandraAdminOperations.query(select); + ResultSet results = this.cassandraOperations.query(select); if (results.isExhausted()) { builder.up(); return; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java index 572028f25d4..e96589840fd 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java @@ -24,6 +24,7 @@ import org.junit.After; import org.junit.Test; import org.springframework.boot.actuate.health.ApplicationHealthIndicator; +import org.springframework.boot.actuate.health.CassandraHealthIndicator; import org.springframework.boot.actuate.health.DataSourceHealthIndicator; import org.springframework.boot.actuate.health.DiskSpaceHealthIndicator; import org.springframework.boot.actuate.health.ElasticsearchHealthIndicator; @@ -54,9 +55,11 @@ import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.cassandra.core.CassandraOperations; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.mock; /** * Tests for {@link HealthIndicatorAutoConfiguration}. @@ -420,6 +423,20 @@ public class HealthIndicatorAutoConfigurationTests { beans.values().iterator().next().getClass()); } + @Test + public void cassandraHealthIndicator() throws Exception { + EnvironmentTestUtils.addEnvironment(this.context, + "management.health.diskspace.enabled:false"); + this.context.register(CassandraConfiguration.class, + ManagementServerProperties.class, HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(1, beans.size()); + assertEquals(CassandraHealthIndicator.class, + beans.values().iterator().next().getClass()); + } + @Configuration @EnableConfigurationProperties protected static class DataSourceConfig { @@ -449,4 +466,15 @@ public class HealthIndicatorAutoConfigurationTests { } + @Configuration + protected static class CassandraConfiguration { + + @Bean + public CassandraOperations cassandraOperations() { + CassandraOperations operations = mock(CassandraOperations.class); + return operations; + } + + } + } diff --git a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 12d887b3c83..6ae8a82a070 100644 --- a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -275,6 +275,9 @@ The following `HealthIndicators` are auto-configured by Spring Boot when appropr |=== |Name |Description +|{sc-spring-boot-actuator}/health/CassandraHealthIndicator.{sc-ext}[`CassandraHealthIndicator`] +|Checks that a Cassandra database is up. + |{sc-spring-boot-actuator}/health/DiskSpaceHealthIndicator.{sc-ext}[`DiskSpaceHealthIndicator`] |Checks for low disk space.