Skip to content

Commit 68cd27c

Browse files
committed
Do not require DataSourcePoolMetrics to auto-configure Hikari meters
Closes spring-projectsgh-13330
1 parent 27267a7 commit 68cd27c

File tree

2 files changed

+101
-43
lines changed

2 files changed

+101
-43
lines changed

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

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,44 +50,50 @@
5050
@Configuration
5151
@AutoConfigureAfter({ MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class,
5252
SimpleMetricsExportAutoConfiguration.class })
53-
@ConditionalOnBean({ DataSource.class, DataSourcePoolMetadataProvider.class,
54-
MeterRegistry.class })
53+
@ConditionalOnBean({ DataSource.class, MeterRegistry.class })
5554
public class DataSourcePoolMetricsAutoConfiguration {
5655

57-
private static final String DATASOURCE_SUFFIX = "dataSource";
56+
@Configuration
57+
@ConditionalOnBean(DataSourcePoolMetadataProvider.class)
58+
static class DataSourcePoolMetadataMetricsConfiguration {
5859

59-
private final MeterRegistry registry;
60+
private static final String DATASOURCE_SUFFIX = "dataSource";
6061

61-
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
62+
private final MeterRegistry registry;
6263

63-
public DataSourcePoolMetricsAutoConfiguration(MeterRegistry registry,
64-
Collection<DataSourcePoolMetadataProvider> metadataProviders) {
65-
this.registry = registry;
66-
this.metadataProviders = metadataProviders;
67-
}
64+
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
6865

69-
@Autowired
70-
public void bindDataSourcesToRegistry(Map<String, DataSource> dataSources) {
71-
dataSources.forEach(this::bindDataSourceToRegistry);
72-
}
66+
DataSourcePoolMetadataMetricsConfiguration(MeterRegistry registry,
67+
Collection<DataSourcePoolMetadataProvider> metadataProviders) {
68+
this.registry = registry;
69+
this.metadataProviders = metadataProviders;
70+
}
7371

74-
private void bindDataSourceToRegistry(String beanName, DataSource dataSource) {
75-
String dataSourceName = getDataSourceName(beanName);
76-
new DataSourcePoolMetrics(dataSource, this.metadataProviders, dataSourceName,
77-
Collections.emptyList()).bindTo(this.registry);
78-
}
72+
@Autowired
73+
public void bindDataSourcesToRegistry(Map<String, DataSource> dataSources) {
74+
dataSources.forEach(this::bindDataSourceToRegistry);
75+
}
76+
77+
private void bindDataSourceToRegistry(String beanName, DataSource dataSource) {
78+
String dataSourceName = getDataSourceName(beanName);
79+
new DataSourcePoolMetrics(dataSource, this.metadataProviders, dataSourceName,
80+
Collections.emptyList()).bindTo(this.registry);
81+
}
7982

80-
/**
81-
* Get the name of a DataSource based on its {@code beanName}.
82-
* @param beanName the name of the data source bean
83-
* @return a name for the given data source
84-
*/
85-
private String getDataSourceName(String beanName) {
86-
if (beanName.length() > DATASOURCE_SUFFIX.length()
87-
&& StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) {
88-
return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length());
83+
/**
84+
* Get the name of a DataSource based on its {@code beanName}.
85+
* @param beanName the name of the data source bean
86+
* @return a name for the given data source
87+
*/
88+
private String getDataSourceName(String beanName) {
89+
if (beanName.length() > DATASOURCE_SUFFIX.length()
90+
&& StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) {
91+
return beanName.substring(0,
92+
beanName.length() - DATASOURCE_SUFFIX.length());
93+
}
94+
return beanName;
8995
}
90-
return beanName;
96+
9197
}
9298

9399
@Configuration

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

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.autoconfigure.AutoConfigurations;
3434
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
3535
import org.springframework.boot.jdbc.DataSourceBuilder;
36+
import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider;
3637
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3738
import org.springframework.context.annotation.Bean;
3839
import org.springframework.context.annotation.Configuration;
@@ -53,22 +54,29 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
5354
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
5455
.withPropertyValues("spring.datasource.generate-unique-name=true")
5556
.with(MetricsRun.simple())
56-
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
57-
DataSourcePoolMetricsAutoConfiguration.class))
57+
.withConfiguration(
58+
AutoConfigurations.of(DataSourcePoolMetricsAutoConfiguration.class))
5859
.withUserConfiguration(BaseConfiguration.class);
5960

6061
@Test
6162
public void autoConfiguredDataSourceIsInstrumented() {
62-
this.contextRunner.run((context) -> {
63-
context.getBean(DataSource.class).getConnection().getMetaData();
64-
MeterRegistry registry = context.getBean(MeterRegistry.class);
65-
registry.get("jdbc.connections.max").tags("name", "dataSource").meter();
66-
});
63+
this.contextRunner
64+
.withConfiguration(
65+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
66+
.run((context) -> {
67+
context.getBean(DataSource.class).getConnection().getMetaData();
68+
MeterRegistry registry = context.getBean(MeterRegistry.class);
69+
registry.get("jdbc.connections.max").tags("name", "dataSource")
70+
.meter();
71+
});
6772
}
6873

6974
@Test
7075
public void dataSourceInstrumentationCanBeDisabled() {
71-
this.contextRunner.withPropertyValues("management.metrics.enable.jdbc=false")
76+
this.contextRunner
77+
.withConfiguration(
78+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
79+
.withPropertyValues("management.metrics.enable.jdbc=false")
7280
.run((context) -> {
7381
context.getBean(DataSource.class).getConnection().getMetaData();
7482
MeterRegistry registry = context.getBean(MeterRegistry.class);
@@ -79,7 +87,10 @@ public void dataSourceInstrumentationCanBeDisabled() {
7987

8088
@Test
8189
public void allDataSourcesCanBeInstrumented() {
82-
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class)
90+
this.contextRunner
91+
.withConfiguration(
92+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
93+
.withUserConfiguration(TwoDataSourcesConfiguration.class)
8394
.run((context) -> {
8495
context.getBean("firstDataSource", DataSource.class).getConnection()
8596
.getMetaData();
@@ -94,18 +105,23 @@ public void allDataSourcesCanBeInstrumented() {
94105

95106
@Test
96107
public void autoConfiguredHikariDataSourceIsInstrumented() {
97-
this.contextRunner.run((context) -> {
98-
context.getBean(DataSource.class).getConnection();
99-
MeterRegistry registry = context.getBean(MeterRegistry.class);
100-
registry.get("hikaricp.connections").meter();
101-
});
108+
this.contextRunner
109+
.withConfiguration(
110+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
111+
.run((context) -> {
112+
context.getBean(DataSource.class).getConnection();
113+
MeterRegistry registry = context.getBean(MeterRegistry.class);
114+
registry.get("hikaricp.connections").meter();
115+
});
102116
}
103117

104118
@Test
105119
public void autoConfiguredHikariDataSourceIsInstrumentedWhenUsingDataSourceInitialization() {
106120
this.contextRunner
107121
.withPropertyValues(
108122
"spring.datasource.schema:db/create-custom-schema.sql")
123+
.withConfiguration(
124+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
109125
.run((context) -> {
110126
context.getBean(DataSource.class).getConnection();
111127
MeterRegistry registry = context.getBean(MeterRegistry.class);
@@ -116,6 +132,8 @@ public void autoConfiguredHikariDataSourceIsInstrumentedWhenUsingDataSourceIniti
116132
@Test
117133
public void hikariCanBeInstrumentedAfterThePoolHasBeenSealed() {
118134
this.contextRunner.withUserConfiguration(HikariSealingConfiguration.class)
135+
.withConfiguration(
136+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
119137
.run((context) -> {
120138
assertThat(context).hasNotFailed();
121139
context.getBean(DataSource.class).getConnection();
@@ -127,6 +145,8 @@ public void hikariCanBeInstrumentedAfterThePoolHasBeenSealed() {
127145
@Test
128146
public void hikariDataSourceInstrumentationCanBeDisabled() {
129147
this.contextRunner.withPropertyValues("management.metrics.enable.hikaricp=false")
148+
.withConfiguration(
149+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
130150
.run((context) -> {
131151
context.getBean(DataSource.class).getConnection();
132152
MeterRegistry registry = context.getBean(MeterRegistry.class);
@@ -137,6 +157,8 @@ public void hikariDataSourceInstrumentationCanBeDisabled() {
137157
@Test
138158
public void allHikariDataSourcesCanBeInstrumented() {
139159
this.contextRunner.withUserConfiguration(TwoHikariDataSourcesConfiguration.class)
160+
.withConfiguration(
161+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
140162
.run((context) -> {
141163
context.getBean("firstDataSource", DataSource.class).getConnection();
142164
context.getBean("secondOne", DataSource.class).getConnection();
@@ -151,6 +173,8 @@ public void allHikariDataSourcesCanBeInstrumented() {
151173
@Test
152174
public void someHikariDataSourcesCanBeInstrumented() {
153175
this.contextRunner.withUserConfiguration(MixedDataSourcesConfiguration.class)
176+
.withConfiguration(
177+
AutoConfigurations.of(DataSourceAutoConfiguration.class))
154178
.run((context) -> {
155179
context.getBean("firstDataSource", DataSource.class).getConnection();
156180
context.getBean("secondOne", DataSource.class).getConnection();
@@ -161,6 +185,20 @@ public void someHikariDataSourcesCanBeInstrumented() {
161185
});
162186
}
163187

188+
@Test
189+
public void hikariDataSourceIsInstrumentedWithoutMetadataProvider() {
190+
this.contextRunner.withUserConfiguration(OneHikariDataSourceConfiguration.class)
191+
.run((context) -> {
192+
assertThat(context)
193+
.doesNotHaveBean(DataSourcePoolMetadataProvider.class);
194+
context.getBean("hikariDataSource", DataSource.class).getConnection();
195+
MeterRegistry registry = context.getBean(MeterRegistry.class);
196+
assertThat(registry.get("hikaricp.connections").meter().getId()
197+
.getTags())
198+
.containsExactly(Tag.of("pool", "hikariDataSource"));
199+
});
200+
}
201+
164202
@Configuration
165203
static class BaseConfiguration {
166204

@@ -214,6 +252,20 @@ private HikariDataSource createHikariDataSource(String poolName) {
214252

215253
}
216254

255+
@Configuration
256+
static class OneHikariDataSourceConfiguration {
257+
258+
@Bean
259+
public DataSource hikariDataSource() {
260+
String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID();
261+
HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url)
262+
.type(HikariDataSource.class).build();
263+
hikariDataSource.setPoolName("hikariDataSource");
264+
return hikariDataSource;
265+
}
266+
267+
}
268+
217269
@Configuration
218270
static class MixedDataSourcesConfiguration {
219271

0 commit comments

Comments
 (0)