Skip to content

Commit efdc196

Browse files
safeeransari-gcwilkinsona
authored andcommitted
Avoid NPE when routing DataSource has target with null key
See gh-27698
1 parent e409489 commit efdc196

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Collection;
2020
import java.util.Iterator;
2121
import java.util.Map;
22+
import java.util.Optional;
2223
import java.util.function.Function;
2324
import java.util.stream.Collectors;
2425

@@ -57,6 +58,7 @@
5758
* @author Stephane Nicoll
5859
* @author Arthur Kalimullin
5960
* @author Julio Gomez
61+
* @author Safeer Ansari
6062
* @since 2.0.0
6163
*/
6264
@Configuration(proxyBeanMethods = false)
@@ -124,10 +126,13 @@ static class RoutingDataSourceHealthContributor implements CompositeHealthContri
124126

125127
private final CompositeHealthContributor delegate;
126128

129+
private static final String UNNAMED_DATASOURCE_KEY = "unnamed";
130+
127131
RoutingDataSourceHealthContributor(AbstractRoutingDataSource routingDataSource,
128132
Function<DataSource, HealthContributor> contributorFunction) {
129133
Map<String, DataSource> routedDataSources = routingDataSource.getResolvedDataSources().entrySet().stream()
130-
.collect(Collectors.toMap((e) -> e.getKey().toString(), Map.Entry::getValue));
134+
.collect(Collectors.toMap((e) -> Optional.ofNullable(e.getKey()).map(Object::toString)
135+
.orElse(UNNAMED_DATASOURCE_KEY), Map.Entry::getValue));
131136
this.delegate = CompositeHealthContributor.fromMap(routedDataSources, contributorFunction);
132137
}
133138

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
*
5050
* @author Phillip Webb
5151
* @author Julio Gomez
52+
* @author Safeer Ansari
5253
*/
5354
class DataSourceHealthContributorAutoConfigurationTests {
5455

@@ -102,10 +103,11 @@ void runWithOnlyRoutingDataSourceShouldIncludeRoutingDataSourceWithComposedIndic
102103
assertThat(context).hasSingleBean(RoutingDataSourceHealthContributor.class);
103104
RoutingDataSourceHealthContributor routingHealthContributor = context
104105
.getBean(RoutingDataSourceHealthContributor.class);
106+
assertThat(routingHealthContributor.getContributor("unnamed")).isInstanceOf(DataSourceHealthIndicator.class);
105107
assertThat(routingHealthContributor.getContributor("one")).isInstanceOf(DataSourceHealthIndicator.class);
106108
assertThat(routingHealthContributor.getContributor("two")).isInstanceOf(DataSourceHealthIndicator.class);
107109
assertThat(routingHealthContributor.iterator()).toIterable().extracting("name")
108-
.containsExactlyInAnyOrder("one", "two");
110+
.containsExactlyInAnyOrder("unnamed", "one", "two");
109111
});
110112
}
111113

@@ -155,6 +157,7 @@ static class RoutingDataSourceConfig {
155157
@Bean
156158
AbstractRoutingDataSource routingDataSource() {
157159
Map<Object, DataSource> dataSources = new HashMap<>();
160+
dataSources.put(null, mock(DataSource.class));
158161
dataSources.put("one", mock(DataSource.class));
159162
dataSources.put("two", mock(DataSource.class));
160163
AbstractRoutingDataSource routingDataSource = mock(AbstractRoutingDataSource.class);

0 commit comments

Comments
 (0)