|
|
@ -20,12 +20,14 @@ import java.sql.Connection;
|
|
|
|
import java.sql.ResultSet;
|
|
|
|
import java.sql.ResultSet;
|
|
|
|
import java.sql.ResultSetMetaData;
|
|
|
|
import java.sql.ResultSetMetaData;
|
|
|
|
import java.sql.SQLException;
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
|
import org.springframework.dao.DataAccessException;
|
|
|
|
import org.springframework.dao.DataAccessException;
|
|
|
|
import org.springframework.dao.support.DataAccessUtils;
|
|
|
|
import org.springframework.dao.support.DataAccessUtils;
|
|
|
|
import org.springframework.jdbc.IncorrectResultSetColumnCountException;
|
|
|
|
import org.springframework.jdbc.IncorrectResultSetColumnCountException;
|
|
|
@ -33,6 +35,7 @@ import org.springframework.jdbc.core.ConnectionCallback;
|
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
|
import org.springframework.jdbc.core.RowMapper;
|
|
|
|
import org.springframework.jdbc.core.RowMapper;
|
|
|
|
import org.springframework.jdbc.support.JdbcUtils;
|
|
|
|
import org.springframework.jdbc.support.JdbcUtils;
|
|
|
|
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -45,24 +48,26 @@ import org.springframework.util.StringUtils;
|
|
|
|
* @author Stephane Nicoll
|
|
|
|
* @author Stephane Nicoll
|
|
|
|
* @since 1.1.0
|
|
|
|
* @since 1.1.0
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
public class DataSourceHealthIndicator extends AbstractHealthIndicator implements
|
|
|
|
|
|
|
|
InitializingBean {
|
|
|
|
private DataSource dataSource;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final Map<String, String> queries = new HashMap<String, String>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final Map<String, String> PRODUCT_SPECIFIC_QUERIES;
|
|
|
|
static {
|
|
|
|
static {
|
|
|
|
|
|
|
|
Map<String, String> queries = new HashMap<String, String>();
|
|
|
|
queries.put("HSQL Database Engine", "SELECT COUNT(*) FROM "
|
|
|
|
queries.put("HSQL Database Engine", "SELECT COUNT(*) FROM "
|
|
|
|
+ "INFORMATION_SCHEMA.SYSTEM_USERS");
|
|
|
|
+ "INFORMATION_SCHEMA.SYSTEM_USERS");
|
|
|
|
queries.put("Oracle", "SELECT 'Hello' from DUAL");
|
|
|
|
queries.put("Oracle", "SELECT 'Hello' from DUAL");
|
|
|
|
queries.put("Apache Derby", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
|
|
|
|
queries.put("Apache Derby", "SELECT 1 FROM SYSIBM.SYSDUMMY1");
|
|
|
|
|
|
|
|
PRODUCT_SPECIFIC_QUERIES = Collections.unmodifiableMap(queries);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static final String DEFAULT_QUERY = "SELECT 1";
|
|
|
|
private static final String DEFAULT_QUERY = "SELECT 1";
|
|
|
|
|
|
|
|
|
|
|
|
private String query = null;
|
|
|
|
private DataSource dataSource;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String query;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} instance.
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} instance.
|
|
|
@ -71,7 +76,17 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} using the specified datasource.
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} using the specified
|
|
|
|
|
|
|
|
* {@link DataSource}.
|
|
|
|
|
|
|
|
* @param dataSource the data source
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public DataSourceHealthIndicator(DataSource dataSource) {
|
|
|
|
|
|
|
|
this(dataSource, null);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} using the specified
|
|
|
|
|
|
|
|
* {@link DataSource} and validation query.
|
|
|
|
* @param dataSource the data source
|
|
|
|
* @param dataSource the data source
|
|
|
|
* @param query the validation query to use (can be {@code null})
|
|
|
|
* @param query the validation query to use (can be {@code null})
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -81,12 +96,10 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
|
|
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@Override
|
|
|
|
* Create a new {@link DataSourceHealthIndicator} using the specified datasource.
|
|
|
|
public void afterPropertiesSet() throws Exception {
|
|
|
|
* @param dataSource the data source
|
|
|
|
Assert.state(this.dataSource != null,
|
|
|
|
*/
|
|
|
|
"DataSource for DataSourceHealthIndicator must be specified");
|
|
|
|
public DataSourceHealthIndicator(DataSource dataSource) {
|
|
|
|
|
|
|
|
this(dataSource, null);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -102,11 +115,11 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
private void doDataSourceHealthCheck(Health.Builder builder) throws Exception {
|
|
|
|
private void doDataSourceHealthCheck(Health.Builder builder) throws Exception {
|
|
|
|
String product = getProduct();
|
|
|
|
String product = getProduct();
|
|
|
|
builder.up().withDetail("database", product);
|
|
|
|
builder.up().withDetail("database", product);
|
|
|
|
String query = detectQuery(product);
|
|
|
|
String validationQuery = getValidationQuery(product);
|
|
|
|
if (StringUtils.hasText(query)) {
|
|
|
|
if (StringUtils.hasText(validationQuery)) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// Avoid calling getObject as it breaks MySQL on Java 7
|
|
|
|
// Avoid calling getObject as it breaks MySQL on Java 7
|
|
|
|
List<Object> results = this.jdbcTemplate.query(query,
|
|
|
|
List<Object> results = this.jdbcTemplate.query(validationQuery,
|
|
|
|
new SingleColumnRowMapper());
|
|
|
|
new SingleColumnRowMapper());
|
|
|
|
Object result = DataAccessUtils.requiredSingleResult(results);
|
|
|
|
Object result = DataAccessUtils.requiredSingleResult(results);
|
|
|
|
builder.withDetail("hello", result);
|
|
|
|
builder.withDetail("hello", result);
|
|
|
@ -127,10 +140,10 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected String detectQuery(String product) {
|
|
|
|
protected String getValidationQuery(String product) {
|
|
|
|
String query = this.query;
|
|
|
|
String query = this.query;
|
|
|
|
if (!StringUtils.hasText(query)) {
|
|
|
|
if (!StringUtils.hasText(query)) {
|
|
|
|
query = queries.get(product);
|
|
|
|
query = PRODUCT_SPECIFIC_QUERIES.get(product);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!StringUtils.hasText(query)) {
|
|
|
|
if (!StringUtils.hasText(query)) {
|
|
|
|
query = DEFAULT_QUERY;
|
|
|
|
query = DEFAULT_QUERY;
|
|
|
@ -147,18 +160,18 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Set a specific validation query to use to validate a connection. If
|
|
|
|
* Set a specific validation query to use to validate a connection. If none is set, a
|
|
|
|
* none is set, a default validation query is used.
|
|
|
|
* default validation query is used.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void setQuery(String query) {
|
|
|
|
public void setQuery(String query) {
|
|
|
|
this.query = query;
|
|
|
|
this.query = query;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Return the specific validation query, if any.
|
|
|
|
* Return the validation query or {@code null}.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public String getQuery() {
|
|
|
|
public String getQuery() {
|
|
|
|
return query;
|
|
|
|
return this.query;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|