diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java index be84c6efa790..aeb078580007 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -57,6 +58,7 @@ * @author Stephane Nicoll * @author Arthur Kalimullin * @author Julio Gomez + * @author Safeer Ansari * @since 2.0.0 */ @Configuration(proxyBeanMethods = false) @@ -124,10 +126,13 @@ static class RoutingDataSourceHealthContributor implements CompositeHealthContri private final CompositeHealthContributor delegate; + private static final String UNNAMED_DATASOURCE_KEY = "unnamed"; + RoutingDataSourceHealthContributor(AbstractRoutingDataSource routingDataSource, Function contributorFunction) { Map routedDataSources = routingDataSource.getResolvedDataSources().entrySet().stream() - .collect(Collectors.toMap((e) -> e.getKey().toString(), Map.Entry::getValue)); + .collect(Collectors.toMap((e) -> Optional.ofNullable(e.getKey()).map(Object::toString) + .orElse(UNNAMED_DATASOURCE_KEY), Map.Entry::getValue)); this.delegate = CompositeHealthContributor.fromMap(routedDataSources, contributorFunction); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java index 91d7eac8e534..2d86bf1f989f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java @@ -49,6 +49,7 @@ * * @author Phillip Webb * @author Julio Gomez + * @author Safeer Ansari */ class DataSourceHealthContributorAutoConfigurationTests { @@ -102,10 +103,11 @@ void runWithOnlyRoutingDataSourceShouldIncludeRoutingDataSourceWithComposedIndic assertThat(context).hasSingleBean(RoutingDataSourceHealthContributor.class); RoutingDataSourceHealthContributor routingHealthContributor = context .getBean(RoutingDataSourceHealthContributor.class); + assertThat(routingHealthContributor.getContributor("unnamed")).isInstanceOf(DataSourceHealthIndicator.class); assertThat(routingHealthContributor.getContributor("one")).isInstanceOf(DataSourceHealthIndicator.class); assertThat(routingHealthContributor.getContributor("two")).isInstanceOf(DataSourceHealthIndicator.class); assertThat(routingHealthContributor.iterator()).toIterable().extracting("name") - .containsExactlyInAnyOrder("one", "two"); + .containsExactlyInAnyOrder("unnamed", "one", "two"); }); } @@ -155,6 +157,7 @@ static class RoutingDataSourceConfig { @Bean AbstractRoutingDataSource routingDataSource() { Map dataSources = new HashMap<>(); + dataSources.put(null, mock(DataSource.class)); dataSources.put("one", mock(DataSource.class)); dataSources.put("two", mock(DataSource.class)); AbstractRoutingDataSource routingDataSource = mock(AbstractRoutingDataSource.class);