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 96b699aed3..f71d32eb1b 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 @@ -17,6 +17,7 @@ package org.springframework.boot.actuate.autoconfigure; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.Map; import javax.jms.ConnectionFactory; @@ -75,6 +76,7 @@ import org.springframework.data.couchbase.core.CouchbaseOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import org.springframework.mail.javamail.JavaMailSenderImpl; /** @@ -170,7 +172,7 @@ public class HealthIndicatorAutoConfiguration { } @Configuration - @ConditionalOnClass(JdbcTemplate.class) + @ConditionalOnClass({ JdbcTemplate.class, AbstractRoutingDataSource.class }) @ConditionalOnBean(DataSource.class) @ConditionalOnEnabledHealthIndicator("db") public static class DataSourcesHealthIndicatorConfiguration extends @@ -186,10 +188,21 @@ public class HealthIndicatorAutoConfiguration { public DataSourcesHealthIndicatorConfiguration( ObjectProvider> dataSourcesProvider, ObjectProvider> metadataProvidersProvider) { - this.dataSources = dataSourcesProvider.getIfAvailable(); + this.dataSources = filterDataSources(dataSourcesProvider.getIfAvailable()); this.metadataProviders = metadataProvidersProvider.getIfAvailable(); } + private static Map filterDataSources( + Map candidates) { + Map dataSources = new LinkedHashMap(); + for (Map.Entry entry : candidates.entrySet()) { + if (!(entry.getValue() instanceof AbstractRoutingDataSource)) { + dataSources.put(entry.getKey(), entry.getValue()); + } + } + return dataSources; + } + @Override public void afterPropertiesSet() throws Exception { this.poolMetadataProvider = new DataSourcePoolMetadataProviders( 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 49b888c13c..953827f4e4 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,8 +24,10 @@ import io.searchbox.client.JestClient; import org.junit.After; import org.junit.Test; +import org.springframework.beans.DirectFieldAccessor; 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.CouchbaseHealthIndicator; import org.springframework.boot.actuate.health.DataSourceHealthIndicator; import org.springframework.boot.actuate.health.DiskSpaceHealthIndicator; @@ -61,6 +63,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.couchbase.core.CouchbaseOperations; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -226,6 +229,39 @@ public class HealthIndicatorAutoConfigurationTests { .isEqualTo(DataSourceHealthIndicator.class); } + @Test + public void dataSourceHealthIndicatorWithSeveralDataSources() { + this.context.register(EmbeddedDataSourceConfiguration.class, + DataSourceConfig.class, ManagementServerProperties.class, + HealthIndicatorAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "management.health.diskspace.enabled:false"); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertThat(beans).hasSize(1); + HealthIndicator bean = beans.values().iterator().next(); + assertThat(bean).isExactlyInstanceOf(CompositeHealthIndicator.class); + Map indicators = (Map) + new DirectFieldAccessor(bean).getPropertyValue("indicators"); + assertThat(indicators).hasSize(2); + } + + @Test + public void dataSourceHealthIndicatorWithAbstractRoutingDataSource() { + this.context.register(EmbeddedDataSourceConfiguration.class, + RoutingDatasourceConfig.class, ManagementServerProperties.class, + HealthIndicatorAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "management.health.diskspace.enabled:false"); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertThat(beans).hasSize(1); + assertThat(beans.values().iterator().next().getClass()) + .isEqualTo(DataSourceHealthIndicator.class); + } + @Test public void dataSourceHealthIndicatorWithCustomValidationQuery() { this.context.register(PropertyPlaceholderAutoConfiguration.class, @@ -507,7 +543,7 @@ public class HealthIndicatorAutoConfigurationTests { @Bean @ConfigurationProperties(prefix = "spring.datasource.test") - public DataSource dataSource() { + public DataSource testDataSource() { return DataSourceBuilder.create() .driverClassName("org.hsqldb.jdbc.JDBCDriver") .url("jdbc:hsqldb:mem:test").username("sa").build(); @@ -515,6 +551,16 @@ public class HealthIndicatorAutoConfigurationTests { } + @Configuration + protected static class RoutingDatasourceConfig { + + @Bean + AbstractRoutingDataSource routingDataSource() { + return mock(AbstractRoutingDataSource.class); + } + + } + @Configuration protected static class CustomHealthIndicator {