Restore AbstractRoutingDataSource health support
Update `DataSourceHealthContributorAutoConfiguration` so that any `AbstractRoutingDataSource` beans are still included in the overall health. Prior to this commit, a regression in Spring Boot 2.2 meant that if a single routing bean was found an `IllegalArgumentException` would be thrown. In Spring Boot 2.1 all `AbstractRoutingDataSource` would be filtered from the results, but if no results existed the following was returned: "details": { "db": { "status": "UNKNOWN" }, In Spring Boot 2.2 we now always include routing datasource beans, even if other non-routing database beans are found. The health details includes `"routing" : true` to help users disambiguate any results. Fixes gh-18661
This commit is contained in:
parent
ba30ee03df
commit
c5138c56ff
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.boot.actuate.autoconfigure.jdbc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -27,7 +26,10 @@ import org.springframework.beans.factory.InitializingBean;
|
|||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
|
@ -60,7 +62,7 @@ import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
|||
@ConditionalOnEnabledHealthIndicator("db")
|
||||
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
|
||||
public class DataSourceHealthContributorAutoConfiguration extends
|
||||
CompositeHealthContributorConfiguration<DataSourceHealthIndicator, DataSource> implements InitializingBean {
|
||||
CompositeHealthContributorConfiguration<AbstractHealthIndicator, DataSource> implements InitializingBean {
|
||||
|
||||
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
|
||||
|
||||
|
@ -79,24 +81,14 @@ public class DataSourceHealthContributorAutoConfiguration extends
|
|||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "dbHealthIndicator", "dbHealthContributor" })
|
||||
public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources) {
|
||||
return createContributor(filterDataSources(dataSources));
|
||||
}
|
||||
|
||||
private Map<String, DataSource> filterDataSources(Map<String, DataSource> candidates) {
|
||||
if (candidates == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, DataSource> dataSources = new LinkedHashMap<>();
|
||||
candidates.forEach((name, dataSource) -> {
|
||||
if (!(dataSource instanceof AbstractRoutingDataSource)) {
|
||||
dataSources.put(name, dataSource);
|
||||
}
|
||||
});
|
||||
return dataSources;
|
||||
return createContributor(dataSources);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSourceHealthIndicator createIndicator(DataSource source) {
|
||||
protected AbstractHealthIndicator createIndicator(DataSource source) {
|
||||
if (source instanceof AbstractRoutingDataSource) {
|
||||
return new RoutingDataSourceHealthIndicator();
|
||||
}
|
||||
return new DataSourceHealthIndicator(source, getValidationQuery(source));
|
||||
}
|
||||
|
||||
|
@ -105,4 +97,17 @@ public class DataSourceHealthContributorAutoConfiguration extends
|
|||
return (poolMetadata != null) ? poolMetadata.getValidationQuery() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HealthIndicator} used for {@link AbstractRoutingDataSource} beans where we
|
||||
* can't actually query for the status.
|
||||
*/
|
||||
static class RoutingDataSourceHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
builder.unknown().withDetail("routing", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import javax.sql.DataSource;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration.RoutingDataSourceHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.CompositeHealthContributor;
|
||||
import org.springframework.boot.actuate.health.NamedContributor;
|
||||
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
|
||||
|
@ -71,10 +72,20 @@ class DataSourceHealthContributorAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void runShouldFilterRoutingDataSource() {
|
||||
void runWithRoutingAndEmbeddedDataSourceShouldFilterRoutingDataSource() {
|
||||
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, RoutingDatasourceConfig.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(DataSourceHealthIndicator.class)
|
||||
.doesNotHaveBean(CompositeHealthContributor.class));
|
||||
.run((context) -> {
|
||||
CompositeHealthContributor composite = context.getBean(CompositeHealthContributor.class);
|
||||
assertThat(composite.getContributor("dataSource")).isInstanceOf(DataSourceHealthIndicator.class);
|
||||
assertThat(composite.getContributor("routingDataSource"))
|
||||
.isInstanceOf(RoutingDataSourceHealthIndicator.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWithOnlyRoutingDataSourceShouldFilterRoutingDataSource() {
|
||||
this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(RoutingDataSourceHealthIndicator.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue