Add JMX MBean for Tomcat DataSource
If the DataSource is a Tomcat one we force it to register an MBean if spring.jmx.enabled=true Fixes gh-1590
This commit is contained in:
@@ -16,9 +16,14 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.jdbc;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import javax.sql.XADataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.tomcat.jdbc.pool.DataSourceProxy;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -27,6 +32,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.Registrar;
|
||||
@@ -59,6 +65,8 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
@EnableConfigurationProperties(DataSourceProperties.class)
|
||||
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
|
||||
public class DataSourceAutoConfiguration {
|
||||
|
||||
private static Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);
|
||||
|
||||
/**
|
||||
* Determines if the {@code dataSource} being used by Spring was created from
|
||||
@@ -134,7 +142,25 @@ public class DataSourceAutoConfiguration {
|
||||
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
|
||||
return new NamedParameterJdbcTemplate(this.dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnExpression("${spring.datasource.jmxEnabled:true}")
|
||||
@ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy")
|
||||
@Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)
|
||||
protected static class TomcatDataSourceJmxConfiguration {
|
||||
@Bean
|
||||
public Object dataSourceMBean(DataSource dataSource) {
|
||||
if (dataSource instanceof DataSourceProxy) {
|
||||
try {
|
||||
return ((DataSourceProxy) dataSource).createPool().getJmxPool();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
logger.warn("Cannot expose DataSource to JMX (could not connect)");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
@@ -134,11 +135,20 @@ public class TomcatDataSourceConfigurationTests {
|
||||
@Import(DataSourceAutoConfiguration.class)
|
||||
protected static class TomcatDataSourceConfiguration {
|
||||
|
||||
@Autowired
|
||||
private DataSourceProperties properties;
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
|
||||
public DataSource dataSource() {
|
||||
return DataSourceBuilder.create()
|
||||
.type(org.apache.tomcat.jdbc.pool.DataSource.class).build();
|
||||
DataSourceBuilder factory = DataSourceBuilder
|
||||
.create(this.properties.getClassLoader())
|
||||
.driverClassName(this.properties.getDriverClassName())
|
||||
.url(this.properties.getUrl())
|
||||
.username(this.properties.getUsername())
|
||||
.password(this.properties.getPassword())
|
||||
.type(org.apache.tomcat.jdbc.pool.DataSource.class);
|
||||
return factory.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
package sample.data.jpa;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Integration test to run the application.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
|
||||
@WebAppConfiguration
|
||||
// Enable JMX so we can test the MBeans (you can't do this in a properties file)
|
||||
@TestPropertySource(properties="spring.jmx.enabled:true")
|
||||
@ActiveProfiles("scratch")
|
||||
// Separate profile for web tests to avoid clashing databases
|
||||
public class SampleDataJpaApplicationTests {
|
||||
@@ -44,4 +53,11 @@ public class SampleDataJpaApplicationTests {
|
||||
this.mvc.perform(get("/")).andExpect(status().isOk())
|
||||
.andExpect(content().string("Bath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJmx() throws Exception {
|
||||
assertEquals(1, ManagementFactory.getPlatformMBeanServer().queryMBeans(
|
||||
new ObjectName("jpa.sample:type=ConnectionPool,*"), null).size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
spring.datasource.url: jdbc:hsqldb:mem:scratchdb
|
||||
spring.jmx.default_domain: jpa.sample
|
||||
Reference in New Issue
Block a user