mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
fixed timeBetweenEvictionRunsMillis defaultValues
This commit is contained in:
@@ -1,151 +1,152 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class FilterManager {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(FilterManager.class);
|
||||
|
||||
private static final ConcurrentHashMap<String, String> aliasMap = new ConcurrentHashMap<String, String>(16, 0.75f, 1);
|
||||
|
||||
static {
|
||||
try {
|
||||
Properties filterProperties = loadFilterConfig();
|
||||
for (Map.Entry<Object, Object> entry : filterProperties.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
if (key.startsWith("druid.filters.")) {
|
||||
String name = key.substring("druid.filters.".length());
|
||||
aliasMap.put(name, (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("load filter config error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String getFilter(String alias) {
|
||||
return aliasMap.get(alias);
|
||||
}
|
||||
|
||||
public static Properties loadFilterConfig() throws IOException {
|
||||
Properties filterProperties = new Properties();
|
||||
|
||||
loadFilterConfig(filterProperties, ClassLoader.getSystemClassLoader());
|
||||
loadFilterConfig(filterProperties, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
return filterProperties;
|
||||
}
|
||||
|
||||
private static void loadFilterConfig(Properties filterProperties, ClassLoader classLoader) throws IOException {
|
||||
if (classLoader == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Enumeration<URL> e = classLoader.getResources("META-INF/druid-filter.properties"); e.hasMoreElements();) {
|
||||
URL url = e.nextElement();
|
||||
|
||||
Properties property = new Properties();
|
||||
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = url.openStream();
|
||||
property.load(is);
|
||||
} finally {
|
||||
JdbcUtils.close(is);
|
||||
}
|
||||
|
||||
filterProperties.putAll(property);
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadFilter(List<Filter> filters, String filterName) throws SQLException {
|
||||
if (filterName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String filterClassNames = getFilter(filterName);
|
||||
|
||||
if (filterClassNames != null) {
|
||||
for (String filterClassName : filterClassNames.split(",")) {
|
||||
if (existsFilter(filters, filterClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?> filterClass = JdbcUtils.loadDriverClass(filterClassName);
|
||||
|
||||
if (filterClass == null) {
|
||||
LOG.error("load filter error, filter not found : " + filterClassName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Filter filter;
|
||||
|
||||
try {
|
||||
filter = (Filter) filterClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
}
|
||||
|
||||
filters.add(filter);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (existsFilter(filters, filterName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> filterClass = JdbcUtils.loadDriverClass(filterName);
|
||||
if (filterClass == null) {
|
||||
LOG.error("load filter error, filter not found : " + filterName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Filter filter = (Filter) filterClass.newInstance();
|
||||
filters.add(filter);
|
||||
} catch (Exception e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean existsFilter(List<Filter> filterList, String filterClassName) {
|
||||
for (Filter filter : filterList) {
|
||||
String itemFilterClassName = filter.getClass().getName();
|
||||
if (itemFilterClassName.equalsIgnoreCase(filterClassName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class FilterManager {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(FilterManager.class);
|
||||
|
||||
private static final ConcurrentHashMap<String, String> aliasMap = new ConcurrentHashMap<String, String>(16, 0.75f, 1);
|
||||
|
||||
static {
|
||||
try {
|
||||
Properties filterProperties = loadFilterConfig();
|
||||
for (Map.Entry<Object, Object> entry : filterProperties.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
if (key.startsWith("druid.filters.")) {
|
||||
String name = key.substring("druid.filters.".length());
|
||||
aliasMap.put(name, (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("load filter config error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String getFilter(String alias) {
|
||||
return aliasMap.get(alias);
|
||||
}
|
||||
|
||||
public static Properties loadFilterConfig() throws IOException {
|
||||
Properties filterProperties = new Properties();
|
||||
|
||||
loadFilterConfig(filterProperties, ClassLoader.getSystemClassLoader());
|
||||
loadFilterConfig(filterProperties, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
return filterProperties;
|
||||
}
|
||||
|
||||
private static void loadFilterConfig(Properties filterProperties, ClassLoader classLoader) throws IOException {
|
||||
if (classLoader == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Enumeration<URL> e = classLoader.getResources("META-INF/druid-filter.properties"); e.hasMoreElements();) {
|
||||
URL url = e.nextElement();
|
||||
|
||||
Properties property = new Properties();
|
||||
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = url.openStream();
|
||||
property.load(is);
|
||||
} finally {
|
||||
JdbcUtils.close(is);
|
||||
}
|
||||
|
||||
filterProperties.putAll(property);
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadFilter(List<Filter> filters, String filterName) throws SQLException {
|
||||
if (filterName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String filterClassNames = getFilter(filterName);
|
||||
|
||||
if (filterClassNames != null) {
|
||||
for (String filterClassName : filterClassNames.split(",")) {
|
||||
if (existsFilter(filters, filterClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?> filterClass = IOUtils.loadClass(filterClassName);
|
||||
|
||||
if (filterClass == null) {
|
||||
LOG.error("load filter error, filter not found : " + filterClassName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Filter filter;
|
||||
|
||||
try {
|
||||
filter = (Filter) filterClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
}
|
||||
|
||||
filters.add(filter);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (existsFilter(filters, filterName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> filterClass = IOUtils.loadClass(filterName);
|
||||
if (filterClass == null) {
|
||||
LOG.error("load filter error, filter not found : " + filterName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Filter filter = (Filter) filterClass.newInstance();
|
||||
filters.add(filter);
|
||||
} catch (Exception e) {
|
||||
throw new SQLException("load managed jdbc driver event listener error. " + filterName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean existsFilter(List<Filter> filterList, String filterClassName) {
|
||||
for (Filter filter : filterList) {
|
||||
String itemFilterClassName = filter.getClass().getName();
|
||||
if (itemFilterClassName.equalsIgnoreCase(filterClassName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
public final static boolean DEFAULT_TEST_ON_BORROW = false;
|
||||
public final static boolean DEFAULT_TEST_ON_RETURN = false;
|
||||
public final static boolean DEFAULT_WHILE_IDLE = true;
|
||||
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
|
||||
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 1000L;
|
||||
public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 30 * 1000;
|
||||
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
|
||||
|
||||
@@ -563,7 +563,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
}
|
||||
|
||||
public void setValidConnectionCheckerClassName(String validConnectionCheckerClass) throws Exception {
|
||||
Class<?> clazz = JdbcUtils.loadDriverClass(validConnectionCheckerClass);
|
||||
Class<?> clazz = IOUtils.loadClass(validConnectionCheckerClass);
|
||||
ValidConnectionChecker validConnectionChecker = null;
|
||||
if (clazz != null) {
|
||||
validConnectionChecker = (ValidConnectionChecker) clazz.newInstance();
|
||||
@@ -798,7 +798,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
}
|
||||
|
||||
public void setPasswordCallbackClassName(String passwordCallbackClassName) throws Exception {
|
||||
Class<?> clazz = JdbcUtils.loadDriverClass(passwordCallbackClassName);
|
||||
Class<?> clazz = IOUtils.loadClass(passwordCallbackClassName);
|
||||
if (clazz != null) {
|
||||
this.passwordCallback = (PasswordCallback) clazz.newInstance();
|
||||
} else {
|
||||
@@ -1130,7 +1130,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> clazz = JdbcUtils.loadDriverClass(exceptionSorter);
|
||||
Class<?> clazz = IOUtils.loadClass(exceptionSorter);
|
||||
if (clazz == null) {
|
||||
LOG.error("load exceptionSorter error : " + exceptionSorter);
|
||||
} else {
|
||||
@@ -1475,7 +1475,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
if (sql == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
stmt.execute(sql);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import static com.alibaba.druid.util.IOUtils.getBoolean;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
@@ -154,19 +156,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
public void configFromPropety(Properties properties) {
|
||||
{
|
||||
String property = properties.getProperty("druid.testWhileIdle");
|
||||
if ("true".equals(property)) {
|
||||
this.setTestWhileIdle(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setTestWhileIdle(false);
|
||||
Boolean value = getBoolean(properties, "druid.testWhileIdle");
|
||||
if (value != null) {
|
||||
this.setTestWhileIdle(value);
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = properties.getProperty("druid.testOnBorrow");
|
||||
if ("true".equals(property)) {
|
||||
this.setTestOnBorrow(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setTestOnBorrow(false);
|
||||
Boolean value = getBoolean(properties, "druid.testOnBorrow");
|
||||
if (value != null) {
|
||||
this.setTestOnBorrow(value);
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -176,11 +174,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = properties.getProperty("druid.useGloalDataSourceStat");
|
||||
if ("true".equals(property)) {
|
||||
this.setUseGloalDataSourceStat(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setUseGloalDataSourceStat(false);
|
||||
Boolean value = getBoolean(properties, "druid.useGloalDataSourceStat");
|
||||
if (value != null) {
|
||||
this.setUseGloalDataSourceStat(value);
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -219,19 +215,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = properties.getProperty("druid.clearFiltersEnable");
|
||||
if ("true".equals(property)) {
|
||||
this.setClearFiltersEnable(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setClearFiltersEnable(false);
|
||||
Boolean value = getBoolean(properties, "druid.clearFiltersEnable");
|
||||
if (value != null) {
|
||||
this.setClearFiltersEnable(value);
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = properties.getProperty("druid.resetStatEnable");
|
||||
if ("true".equals(property)) {
|
||||
this.setResetStatEnable(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setResetStatEnable(false);
|
||||
Boolean value = getBoolean(properties, "druid.resetStatEnable");
|
||||
if (value != null) {
|
||||
this.setResetStatEnable(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+136
-135
@@ -1,135 +1,136 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool.vendor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.alibaba.druid.pool.ValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.ValidConnectionCheckerAdapter;
|
||||
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class MySqlValidConnectionChecker extends ValidConnectionCheckerAdapter implements ValidConnectionChecker, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
|
||||
|
||||
private Class<?> clazz;
|
||||
private Method ping;
|
||||
private boolean usePingMethod = false;
|
||||
|
||||
public MySqlValidConnectionChecker(){
|
||||
try {
|
||||
clazz = JdbcUtils.loadDriverClass("com.mysql.jdbc.Connection");
|
||||
ping = clazz.getMethod("ping");
|
||||
if (ping != null) {
|
||||
usePingMethod = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
|
||||
}
|
||||
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configFromProperties(Properties properties) {
|
||||
String property = properties.getProperty("druid.mysql.usePingMethod");
|
||||
if ("true".equals(property)) {
|
||||
setUsePingMethod(true);
|
||||
} else if ("false".equals(property)) {
|
||||
setUsePingMethod(false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsePingMethod() {
|
||||
return usePingMethod;
|
||||
}
|
||||
|
||||
public void setUsePingMethod(boolean usePingMethod) {
|
||||
this.usePingMethod = usePingMethod;
|
||||
}
|
||||
|
||||
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
|
||||
try {
|
||||
if (conn.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
// skip
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usePingMethod) {
|
||||
if (conn instanceof DruidPooledConnection) {
|
||||
conn = ((DruidPooledConnection) conn).getConnection();
|
||||
}
|
||||
|
||||
if (conn instanceof ConnectionProxy) {
|
||||
conn = ((ConnectionProxy) conn).getRawObject();
|
||||
}
|
||||
|
||||
if (clazz.isAssignableFrom(conn.getClass())) {
|
||||
try {
|
||||
ping.invoke(conn);
|
||||
return true;
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof SQLException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Statement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
stmt = conn.createStatement();
|
||||
if (validationQueryTimeout > 0) {
|
||||
stmt.setQueryTimeout(validationQueryTimeout);
|
||||
}
|
||||
rs = stmt.executeQuery(valiateQuery);
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} finally {
|
||||
JdbcUtils.close(rs);
|
||||
JdbcUtils.close(stmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool.vendor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.alibaba.druid.pool.ValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.ValidConnectionCheckerAdapter;
|
||||
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class MySqlValidConnectionChecker extends ValidConnectionCheckerAdapter implements ValidConnectionChecker, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
|
||||
|
||||
private Class<?> clazz;
|
||||
private Method ping;
|
||||
private boolean usePingMethod = false;
|
||||
|
||||
public MySqlValidConnectionChecker(){
|
||||
try {
|
||||
clazz = IOUtils.loadClass("com.mysql.jdbc.Connection");
|
||||
ping = clazz.getMethod("ping");
|
||||
if (ping != null) {
|
||||
usePingMethod = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
|
||||
}
|
||||
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configFromProperties(Properties properties) {
|
||||
String property = properties.getProperty("druid.mysql.usePingMethod");
|
||||
if ("true".equals(property)) {
|
||||
setUsePingMethod(true);
|
||||
} else if ("false".equals(property)) {
|
||||
setUsePingMethod(false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsePingMethod() {
|
||||
return usePingMethod;
|
||||
}
|
||||
|
||||
public void setUsePingMethod(boolean usePingMethod) {
|
||||
this.usePingMethod = usePingMethod;
|
||||
}
|
||||
|
||||
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
|
||||
try {
|
||||
if (conn.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
// skip
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usePingMethod) {
|
||||
if (conn instanceof DruidPooledConnection) {
|
||||
conn = ((DruidPooledConnection) conn).getConnection();
|
||||
}
|
||||
|
||||
if (conn instanceof ConnectionProxy) {
|
||||
conn = ((ConnectionProxy) conn).getRawObject();
|
||||
}
|
||||
|
||||
if (clazz.isAssignableFrom(conn.getClass())) {
|
||||
try {
|
||||
ping.invoke(conn);
|
||||
return true;
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof SQLException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Statement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
stmt = conn.createStatement();
|
||||
if (validationQueryTimeout > 0) {
|
||||
stmt.setQueryTimeout(validationQueryTimeout);
|
||||
}
|
||||
rs = stmt.executeQuery(valiateQuery);
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} finally {
|
||||
JdbcUtils.close(rs);
|
||||
JdbcUtils.close(stmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+126
-125
@@ -1,125 +1,126 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool.vendor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.alibaba.druid.pool.ValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.ValidConnectionCheckerAdapter;
|
||||
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class OracleValidConnectionChecker extends ValidConnectionCheckerAdapter implements ValidConnectionChecker, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2227528634302168877L;
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class);
|
||||
|
||||
private final Class<?> clazz;
|
||||
private final Method ping;
|
||||
private final static Object[] params = new Object[] { new Integer(5000) };
|
||||
|
||||
public OracleValidConnectionChecker(){
|
||||
try {
|
||||
clazz = JdbcUtils.loadDriverClass("oracle.jdbc.driver.OracleConnection");
|
||||
if (clazz != null) {
|
||||
ping = clazz.getMethod("pingDatabase", new Class[] { Integer.TYPE });
|
||||
} else {
|
||||
ping = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to resolve pingDatabase method:", e);
|
||||
}
|
||||
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configFromProperties(Properties properties) {
|
||||
String property = properties.getProperty("druid.oracle.pingTimeout");
|
||||
if (property != null && property.length() > 0) {
|
||||
int value = Integer.parseInt(property);
|
||||
setTimeout(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
params[0] = timeout;
|
||||
}
|
||||
|
||||
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
|
||||
try {
|
||||
if (conn.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
// skip
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn instanceof DruidPooledConnection) {
|
||||
conn = ((DruidPooledConnection) conn).getConnection();
|
||||
}
|
||||
|
||||
if (conn instanceof ConnectionProxy) {
|
||||
conn = ((ConnectionProxy) conn).getRawObject();
|
||||
}
|
||||
|
||||
// unwrap
|
||||
if (clazz != null && clazz.isAssignableFrom(conn.getClass())) {
|
||||
Integer status = (Integer) ping.invoke(conn, params);
|
||||
|
||||
// Error
|
||||
if (status.intValue() < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Statement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
stmt = conn.createStatement();
|
||||
rs = stmt.executeQuery(valiateQuery);
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} finally {
|
||||
JdbcUtils.close(rs);
|
||||
JdbcUtils.close(stmt);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in pingDatabase", e);
|
||||
}
|
||||
|
||||
// OK
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.pool.vendor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.alibaba.druid.pool.ValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.ValidConnectionCheckerAdapter;
|
||||
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class OracleValidConnectionChecker extends ValidConnectionCheckerAdapter implements ValidConnectionChecker, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2227528634302168877L;
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(OracleValidConnectionChecker.class);
|
||||
|
||||
private final Class<?> clazz;
|
||||
private final Method ping;
|
||||
private final static Object[] params = new Object[] { new Integer(5000) };
|
||||
|
||||
public OracleValidConnectionChecker(){
|
||||
try {
|
||||
clazz = IOUtils.loadClass("oracle.jdbc.driver.OracleConnection");
|
||||
if (clazz != null) {
|
||||
ping = clazz.getMethod("pingDatabase", new Class[] { Integer.TYPE });
|
||||
} else {
|
||||
ping = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to resolve pingDatabase method:", e);
|
||||
}
|
||||
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configFromProperties(Properties properties) {
|
||||
String property = properties.getProperty("druid.oracle.pingTimeout");
|
||||
if (property != null && property.length() > 0) {
|
||||
int value = Integer.parseInt(property);
|
||||
setTimeout(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
params[0] = timeout;
|
||||
}
|
||||
|
||||
public boolean isValidConnection(Connection conn, String valiateQuery, int validationQueryTimeout) {
|
||||
try {
|
||||
if (conn.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
// skip
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (conn instanceof DruidPooledConnection) {
|
||||
conn = ((DruidPooledConnection) conn).getConnection();
|
||||
}
|
||||
|
||||
if (conn instanceof ConnectionProxy) {
|
||||
conn = ((ConnectionProxy) conn).getRawObject();
|
||||
}
|
||||
|
||||
// unwrap
|
||||
if (clazz != null && clazz.isAssignableFrom(conn.getClass())) {
|
||||
Integer status = (Integer) ping.invoke(conn, params);
|
||||
|
||||
// Error
|
||||
if (status.intValue() < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Statement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
stmt = conn.createStatement();
|
||||
rs = stmt.executeQuery(valiateQuery);
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in ping", e);
|
||||
return false;
|
||||
} finally {
|
||||
JdbcUtils.close(rs);
|
||||
JdbcUtils.close(stmt);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unexpected error in pingDatabase", e);
|
||||
}
|
||||
|
||||
// OK
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,320 +1,321 @@
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.proxy;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.DriverPropertyInfo;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.filter.FilterManager;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxyImpl;
|
||||
import com.alibaba.druid.stat.JdbcStatManager;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.JMXUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
*/
|
||||
public class DruidDriver implements Driver, DruidDriverMBean {
|
||||
|
||||
private static Log LOG; // lazy init
|
||||
|
||||
private final static DruidDriver instance = new DruidDriver();
|
||||
|
||||
private final static ConcurrentMap<String, DataSourceProxyImpl> proxyDataSources = new ConcurrentHashMap<String, DataSourceProxyImpl>(16, 0.75f, 1);
|
||||
private final static AtomicInteger dataSourceIdSeed = new AtomicInteger(0);
|
||||
private final static AtomicInteger sqlStatIdSeed = new AtomicInteger(0);
|
||||
|
||||
public final static String DEFAULT_PREFIX = "jdbc:wrap-jdbc:";
|
||||
public final static String DRIVER_PREFIX = "driver=";
|
||||
public final static String PASSWORD_CALLBACK_PREFIX = "passwordCallback=";
|
||||
public final static String NAME_PREFIX = "name=";
|
||||
public final static String JMX_PREFIX = "jmx=";
|
||||
public final static String FILTERS_PREFIX = "filters=";
|
||||
|
||||
private final AtomicLong connectCount = new AtomicLong(0);
|
||||
|
||||
private String acceptPrefix = DEFAULT_PREFIX;
|
||||
|
||||
private int majorVersion = 4;
|
||||
|
||||
private int minorVersion = 0;
|
||||
|
||||
private final static String MBEAN_NAME = "com.alibaba.druid:type=DruidDriver";
|
||||
|
||||
static {
|
||||
registerDriver(instance);
|
||||
}
|
||||
|
||||
public static boolean registerDriver(Driver driver) {
|
||||
try {
|
||||
DriverManager.registerDriver(driver);
|
||||
|
||||
try {
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
|
||||
ObjectName objectName = new ObjectName(MBEAN_NAME);
|
||||
if (!mbeanServer.isRegistered(objectName)) {
|
||||
mbeanServer.registerMBean(instance, objectName);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (LOG == null) {
|
||||
LOG = LogFactory.getLog(DruidDriver.class);
|
||||
}
|
||||
LOG.error("register druid-driver mbean error", ex);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
if (LOG == null) {
|
||||
LOG = LogFactory.getLog(DruidDriver.class);
|
||||
}
|
||||
|
||||
LOG.error("registerDriver error", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public DruidDriver(){
|
||||
|
||||
}
|
||||
|
||||
public static DruidDriver getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static int createDataSourceId() {
|
||||
return dataSourceIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
public static int createSqlStatId() {
|
||||
return sqlStatIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsURL(String url) throws SQLException {
|
||||
if (url == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.startsWith(acceptPrefix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
if (!acceptsURL(url)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
connectCount.incrementAndGet();
|
||||
|
||||
DataSourceProxyImpl dataSource = getDataSource(url, info);
|
||||
|
||||
return dataSource.connect(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数定义: com.alibaba.druid.log.LogFilter=filter com.alibaba.druid.log.LogFilter.p1=prop-value
|
||||
* com.alibaba.druid.log.LogFilter.p2=prop-value
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
private DataSourceProxyImpl getDataSource(String url, Properties info) throws SQLException {
|
||||
DataSourceProxyImpl dataSource = proxyDataSources.get(url);
|
||||
|
||||
if (dataSource == null) {
|
||||
DataSourceProxyConfig config = parseConfig(url, info);
|
||||
|
||||
Driver rawDriver = createDriver(config.getRawDriverClassName());
|
||||
|
||||
DataSourceProxyImpl newDataSource = new DataSourceProxyImpl(rawDriver, config);
|
||||
|
||||
{
|
||||
String property = System.getProperty("druid.filters");
|
||||
if (property != null && property.length() > 0) {
|
||||
for (String filterItem : property.split(",")) {
|
||||
FilterManager.loadFilter(config.getFilters(), filterItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int dataSourceId = createDataSourceId();
|
||||
newDataSource.setId(dataSourceId);
|
||||
|
||||
for (Filter filter : config.getFilters()) {
|
||||
filter.init(newDataSource);
|
||||
}
|
||||
}
|
||||
|
||||
DataSourceProxy oldDataSource = proxyDataSources.putIfAbsent(url, newDataSource);
|
||||
if (oldDataSource == null) {
|
||||
if (config.isJmxOption()) {
|
||||
JMXUtils.register("com.alibaba.druid:type=JdbcStat", JdbcStatManager.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
dataSource = proxyDataSources.get(url);
|
||||
}
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public static DataSourceProxyConfig parseConfig(String url, Properties info) throws SQLException {
|
||||
String restUrl = url.substring(DEFAULT_PREFIX.length());
|
||||
|
||||
DataSourceProxyConfig config = new DataSourceProxyConfig();
|
||||
|
||||
if (restUrl.startsWith(DRIVER_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', DRIVER_PREFIX.length());
|
||||
String driverText = restUrl.substring(DRIVER_PREFIX.length(), pos);
|
||||
if (driverText.length() > 0) {
|
||||
config.setRawDriverClassName(driverText.trim());
|
||||
}
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(FILTERS_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', FILTERS_PREFIX.length());
|
||||
String filtersText = restUrl.substring(FILTERS_PREFIX.length(), pos);
|
||||
for (String filterItem : filtersText.split(",")) {
|
||||
FilterManager.loadFilter(config.getFilters(), filterItem);
|
||||
}
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(NAME_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', NAME_PREFIX.length());
|
||||
String name = restUrl.substring(NAME_PREFIX.length(), pos);
|
||||
config.setName(name);
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(JMX_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', JMX_PREFIX.length());
|
||||
String jmxOption = restUrl.substring(JMX_PREFIX.length(), pos);
|
||||
config.setJmxOption(jmxOption);
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
String rawUrl = restUrl;
|
||||
config.setRawUrl(rawUrl);
|
||||
|
||||
if (config.getRawDriverClassName() == null) {
|
||||
String rawDriverClassname = JdbcUtils.getDriverClassName(rawUrl);
|
||||
config.setRawDriverClassName(rawDriverClassname);
|
||||
}
|
||||
|
||||
config.setUrl(url);
|
||||
return config;
|
||||
}
|
||||
|
||||
public Driver createDriver(String className) throws SQLException {
|
||||
Class<?> rawDriverClass = JdbcUtils.loadDriverClass(className);
|
||||
|
||||
if (rawDriverClass == null) {
|
||||
throw new SQLException("jdbc-driver's class not found. '" + className + "'");
|
||||
}
|
||||
|
||||
Driver rawDriver;
|
||||
try {
|
||||
rawDriver = (Driver) rawDriverClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new SQLException("create driver instance error, driver className '" + className + "'", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SQLException("create driver instance error, driver className '" + className + "'", e);
|
||||
}
|
||||
|
||||
return rawDriver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMajorVersion() {
|
||||
return this.majorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinorVersion() {
|
||||
return this.minorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
|
||||
DataSourceProxyImpl dataSource = getDataSource(url, info);
|
||||
return dataSource.getRawDriver().getPropertyInfo(dataSource.getConfig().getRawUrl(), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean jdbcCompliant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getConnectCount() {
|
||||
return connectCount.get();
|
||||
}
|
||||
|
||||
public String getAcceptPrefix() {
|
||||
return acceptPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDataSourceUrls() {
|
||||
return proxyDataSources.keySet().toArray(new String[proxyDataSources.size()]);
|
||||
}
|
||||
|
||||
public static ConcurrentMap<String, DataSourceProxyImpl> getProxyDataSources() {
|
||||
return proxyDataSources;
|
||||
}
|
||||
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetStat() {
|
||||
connectCount.set(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDruidVersion() {
|
||||
return VERSION.getVersionNumber();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.proxy;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.DriverPropertyInfo;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.filter.FilterManager;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig;
|
||||
import com.alibaba.druid.proxy.jdbc.DataSourceProxyImpl;
|
||||
import com.alibaba.druid.stat.JdbcStatManager;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
import com.alibaba.druid.util.JMXUtils;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
*/
|
||||
public class DruidDriver implements Driver, DruidDriverMBean {
|
||||
|
||||
private static Log LOG; // lazy init
|
||||
|
||||
private final static DruidDriver instance = new DruidDriver();
|
||||
|
||||
private final static ConcurrentMap<String, DataSourceProxyImpl> proxyDataSources = new ConcurrentHashMap<String, DataSourceProxyImpl>(16, 0.75f, 1);
|
||||
private final static AtomicInteger dataSourceIdSeed = new AtomicInteger(0);
|
||||
private final static AtomicInteger sqlStatIdSeed = new AtomicInteger(0);
|
||||
|
||||
public final static String DEFAULT_PREFIX = "jdbc:wrap-jdbc:";
|
||||
public final static String DRIVER_PREFIX = "driver=";
|
||||
public final static String PASSWORD_CALLBACK_PREFIX = "passwordCallback=";
|
||||
public final static String NAME_PREFIX = "name=";
|
||||
public final static String JMX_PREFIX = "jmx=";
|
||||
public final static String FILTERS_PREFIX = "filters=";
|
||||
|
||||
private final AtomicLong connectCount = new AtomicLong(0);
|
||||
|
||||
private String acceptPrefix = DEFAULT_PREFIX;
|
||||
|
||||
private int majorVersion = 4;
|
||||
|
||||
private int minorVersion = 0;
|
||||
|
||||
private final static String MBEAN_NAME = "com.alibaba.druid:type=DruidDriver";
|
||||
|
||||
static {
|
||||
registerDriver(instance);
|
||||
}
|
||||
|
||||
public static boolean registerDriver(Driver driver) {
|
||||
try {
|
||||
DriverManager.registerDriver(driver);
|
||||
|
||||
try {
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
|
||||
ObjectName objectName = new ObjectName(MBEAN_NAME);
|
||||
if (!mbeanServer.isRegistered(objectName)) {
|
||||
mbeanServer.registerMBean(instance, objectName);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (LOG == null) {
|
||||
LOG = LogFactory.getLog(DruidDriver.class);
|
||||
}
|
||||
LOG.error("register druid-driver mbean error", ex);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
if (LOG == null) {
|
||||
LOG = LogFactory.getLog(DruidDriver.class);
|
||||
}
|
||||
|
||||
LOG.error("registerDriver error", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public DruidDriver(){
|
||||
|
||||
}
|
||||
|
||||
public static DruidDriver getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static int createDataSourceId() {
|
||||
return dataSourceIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
public static int createSqlStatId() {
|
||||
return sqlStatIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsURL(String url) throws SQLException {
|
||||
if (url == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.startsWith(acceptPrefix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
if (!acceptsURL(url)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
connectCount.incrementAndGet();
|
||||
|
||||
DataSourceProxyImpl dataSource = getDataSource(url, info);
|
||||
|
||||
return dataSource.connect(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数定义: com.alibaba.druid.log.LogFilter=filter com.alibaba.druid.log.LogFilter.p1=prop-value
|
||||
* com.alibaba.druid.log.LogFilter.p2=prop-value
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
private DataSourceProxyImpl getDataSource(String url, Properties info) throws SQLException {
|
||||
DataSourceProxyImpl dataSource = proxyDataSources.get(url);
|
||||
|
||||
if (dataSource == null) {
|
||||
DataSourceProxyConfig config = parseConfig(url, info);
|
||||
|
||||
Driver rawDriver = createDriver(config.getRawDriverClassName());
|
||||
|
||||
DataSourceProxyImpl newDataSource = new DataSourceProxyImpl(rawDriver, config);
|
||||
|
||||
{
|
||||
String property = System.getProperty("druid.filters");
|
||||
if (property != null && property.length() > 0) {
|
||||
for (String filterItem : property.split(",")) {
|
||||
FilterManager.loadFilter(config.getFilters(), filterItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int dataSourceId = createDataSourceId();
|
||||
newDataSource.setId(dataSourceId);
|
||||
|
||||
for (Filter filter : config.getFilters()) {
|
||||
filter.init(newDataSource);
|
||||
}
|
||||
}
|
||||
|
||||
DataSourceProxy oldDataSource = proxyDataSources.putIfAbsent(url, newDataSource);
|
||||
if (oldDataSource == null) {
|
||||
if (config.isJmxOption()) {
|
||||
JMXUtils.register("com.alibaba.druid:type=JdbcStat", JdbcStatManager.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
dataSource = proxyDataSources.get(url);
|
||||
}
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public static DataSourceProxyConfig parseConfig(String url, Properties info) throws SQLException {
|
||||
String restUrl = url.substring(DEFAULT_PREFIX.length());
|
||||
|
||||
DataSourceProxyConfig config = new DataSourceProxyConfig();
|
||||
|
||||
if (restUrl.startsWith(DRIVER_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', DRIVER_PREFIX.length());
|
||||
String driverText = restUrl.substring(DRIVER_PREFIX.length(), pos);
|
||||
if (driverText.length() > 0) {
|
||||
config.setRawDriverClassName(driverText.trim());
|
||||
}
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(FILTERS_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', FILTERS_PREFIX.length());
|
||||
String filtersText = restUrl.substring(FILTERS_PREFIX.length(), pos);
|
||||
for (String filterItem : filtersText.split(",")) {
|
||||
FilterManager.loadFilter(config.getFilters(), filterItem);
|
||||
}
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(NAME_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', NAME_PREFIX.length());
|
||||
String name = restUrl.substring(NAME_PREFIX.length(), pos);
|
||||
config.setName(name);
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
if (restUrl.startsWith(JMX_PREFIX)) {
|
||||
int pos = restUrl.indexOf(':', JMX_PREFIX.length());
|
||||
String jmxOption = restUrl.substring(JMX_PREFIX.length(), pos);
|
||||
config.setJmxOption(jmxOption);
|
||||
restUrl = restUrl.substring(pos + 1);
|
||||
}
|
||||
|
||||
String rawUrl = restUrl;
|
||||
config.setRawUrl(rawUrl);
|
||||
|
||||
if (config.getRawDriverClassName() == null) {
|
||||
String rawDriverClassname = JdbcUtils.getDriverClassName(rawUrl);
|
||||
config.setRawDriverClassName(rawDriverClassname);
|
||||
}
|
||||
|
||||
config.setUrl(url);
|
||||
return config;
|
||||
}
|
||||
|
||||
public Driver createDriver(String className) throws SQLException {
|
||||
Class<?> rawDriverClass = IOUtils.loadClass(className);
|
||||
|
||||
if (rawDriverClass == null) {
|
||||
throw new SQLException("jdbc-driver's class not found. '" + className + "'");
|
||||
}
|
||||
|
||||
Driver rawDriver;
|
||||
try {
|
||||
rawDriver = (Driver) rawDriverClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new SQLException("create driver instance error, driver className '" + className + "'", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SQLException("create driver instance error, driver className '" + className + "'", e);
|
||||
}
|
||||
|
||||
return rawDriver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMajorVersion() {
|
||||
return this.majorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinorVersion() {
|
||||
return this.minorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
|
||||
DataSourceProxyImpl dataSource = getDataSource(url, info);
|
||||
return dataSource.getRawDriver().getPropertyInfo(dataSource.getConfig().getRawUrl(), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean jdbcCompliant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getConnectCount() {
|
||||
return connectCount.get();
|
||||
}
|
||||
|
||||
public String getAcceptPrefix() {
|
||||
return acceptPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDataSourceUrls() {
|
||||
return proxyDataSources.keySet().toArray(new String[proxyDataSources.size()]);
|
||||
}
|
||||
|
||||
public static ConcurrentMap<String, DataSourceProxyImpl> getProxyDataSources() {
|
||||
return proxyDataSources;
|
||||
}
|
||||
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetStat() {
|
||||
connectCount.set(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDruidVersion() {
|
||||
return VERSION.getVersionNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Properties;
|
||||
|
||||
public class IOUtils {
|
||||
|
||||
@@ -39,7 +40,7 @@ public class IOUtils {
|
||||
}
|
||||
return read(reader);
|
||||
}
|
||||
|
||||
|
||||
public static String readFromResource(String resource) throws IOException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
@@ -47,7 +48,7 @@ public class IOUtils {
|
||||
if (in == null) {
|
||||
in = IOUtils.class.getResourceAsStream(resource);
|
||||
}
|
||||
|
||||
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -58,7 +59,7 @@ public class IOUtils {
|
||||
JdbcUtils.close(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] readByteArrayFromResource(String resource) throws IOException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
@@ -66,25 +67,24 @@ public class IOUtils {
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return readByteArray(in);
|
||||
} finally {
|
||||
JdbcUtils.close(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] readByteArray(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
copy(input, output);
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
public static long copy(InputStream input, OutputStream output)
|
||||
throws IOException {
|
||||
|
||||
public static long copy(InputStream input, OutputStream output) throws IOException {
|
||||
final int EOF = -1;
|
||||
|
||||
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
|
||||
|
||||
long count = 0;
|
||||
int n = 0;
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
@@ -157,4 +157,68 @@ public class IOUtils {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static Boolean getBoolean(Properties properties, String key) {
|
||||
String property = properties.getProperty(key);
|
||||
if ("true".equals(property)) {
|
||||
return Boolean.TRUE;
|
||||
} else if ("false".equals(property)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer getInteger(Properties properties, String key) {
|
||||
String property = properties.getProperty(key);
|
||||
|
||||
if (property == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(property);
|
||||
} catch (NumberFormatException ex) {
|
||||
// skip
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Long getLong(Properties properties, String key) {
|
||||
String property = properties.getProperty(key);
|
||||
|
||||
if (property == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(property);
|
||||
} catch (NumberFormatException ex) {
|
||||
// skip
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class<?> loadClass(String className) {
|
||||
Class<?> clazz = null;
|
||||
|
||||
if (className == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (ctxClassLoader != null) {
|
||||
try {
|
||||
clazz = ctxClassLoader.loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
|
||||
if (clazz != null) {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,33 +635,6 @@ public final class JdbcUtils implements JdbcConstants {
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> loadDriverClass(String className) {
|
||||
Class<?> clazz = null;
|
||||
|
||||
if (className == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (ctxClassLoader != null) {
|
||||
try {
|
||||
clazz = ctxClassLoader.loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
|
||||
if (clazz != null) {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertToTable(DataSource dataSource, String tableName, Map<String, Object> data)
|
||||
throws SQLException {
|
||||
Connection conn = null;
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.IOUtils.getBoolean;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Wrapper;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.druid.filter.FilterAdapter;
|
||||
@@ -42,9 +45,9 @@ import com.alibaba.druid.wall.violation.SyntaxErrorViolation;
|
||||
|
||||
public class WallFilter extends FilterAdapter implements WallFilterMBean {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(WallFilter.class);
|
||||
private final static Log LOG = LogFactory.getLog(WallFilter.class);
|
||||
|
||||
private boolean inited = false;
|
||||
private boolean inited = false;
|
||||
|
||||
private WallProvider provider;
|
||||
|
||||
@@ -52,10 +55,38 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
|
||||
|
||||
private WallConfig config;
|
||||
|
||||
private volatile boolean logViolation = false;
|
||||
private volatile boolean throwException = true;
|
||||
private volatile boolean logViolation = false;
|
||||
private volatile boolean throwException = true;
|
||||
|
||||
public final static String ATTR_SQL_STAT = "wall.sqlStat";
|
||||
private boolean autoRegisterToGlobalTimer = false;
|
||||
|
||||
public final static String ATTR_SQL_STAT = "wall.sqlStat";
|
||||
|
||||
public WallFilter(){
|
||||
configFromProperties(System.getProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configFromProperties(Properties properties) {
|
||||
{
|
||||
Boolean value = getBoolean(properties, "druid.wall.logViolation");
|
||||
if (value != null) {
|
||||
this.logViolation = value;
|
||||
}
|
||||
}
|
||||
{
|
||||
Boolean value = getBoolean(properties, "druid.wall.throwException");
|
||||
if (value != null) {
|
||||
this.throwException = value;
|
||||
}
|
||||
}
|
||||
{
|
||||
Boolean value = getBoolean(properties, "druid.wall.autoRegisterToGlobalTimer");
|
||||
if (value != null) {
|
||||
this.autoRegisterToGlobalTimer = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(DataSourceProxy dataSource) {
|
||||
@@ -107,6 +138,15 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
|
||||
throw new IllegalStateException("dbType not support : " + dbType + ", url " + dataSource.getUrl());
|
||||
}
|
||||
|
||||
if (autoRegisterToGlobalTimer) {
|
||||
WallProviderStatTimer timer = WallProviderStatTimer.getInstance();
|
||||
if (timer == null) {
|
||||
timer = new WallProviderStatTimer();
|
||||
timer.start();
|
||||
}
|
||||
timer.register(provider);
|
||||
}
|
||||
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,36 +15,94 @@
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.IOUtils.getInteger;
|
||||
import static com.alibaba.druid.util.IOUtils.getLong;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.IOUtils;
|
||||
|
||||
public class WallProviderStatTimer implements Runnable {
|
||||
|
||||
private ScheduledExecutorService scheduler;
|
||||
private int threadCount = 1;
|
||||
private long period = 60 * 5;
|
||||
private TimeUnit unit = TimeUnit.SECONDS;
|
||||
private final static Log LOG = LogFactory.getLog(WallProviderStatTimer.class);
|
||||
|
||||
private final List<WallProvider> providers = new CopyOnWriteArrayList<WallProvider>();
|
||||
private ScheduledExecutorService scheduler;
|
||||
private int threadCount = 1;
|
||||
private long period = 60 * 5;
|
||||
private TimeUnit unit = TimeUnit.SECONDS;
|
||||
|
||||
private WallProviderStatLogger statLogger;
|
||||
private final List<WallProvider> providers = new CopyOnWriteArrayList<WallProvider>();
|
||||
|
||||
private WallProviderStatLogger statLogger = new WallProviderStatLoggerImpl();
|
||||
|
||||
private static WallProviderStatTimer instance;
|
||||
|
||||
public WallProviderStatTimer(){
|
||||
configFromPropety(System.getProperties());
|
||||
}
|
||||
|
||||
public static WallProviderStatTimer getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void setInstance(WallProviderStatTimer instance) {
|
||||
WallProviderStatTimer.instance = instance;
|
||||
}
|
||||
|
||||
public void configFromPropety(Properties properties) {
|
||||
{
|
||||
Long value = getLong(properties, "druid.wall.timer.period");
|
||||
if (value != null && value.intValue() > 0) {
|
||||
this.period = value.intValue();
|
||||
}
|
||||
}
|
||||
{
|
||||
Integer value = getInteger(properties, "druid.wall.timer.threadCount");
|
||||
if (value != null && value.intValue() > 0) {
|
||||
this.threadCount = value.intValue();
|
||||
}
|
||||
}
|
||||
{
|
||||
String value = properties.getProperty("druid.wall.timer.statLoggerClass");
|
||||
if (value != null && value.length() > 0) {
|
||||
Class<?> clazz = IOUtils.loadClass(value);
|
||||
try {
|
||||
statLogger = (WallProviderStatLogger) clazz.newInstance();
|
||||
} catch (Exception ex) {
|
||||
LOG.error("configStatLogger error", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<WallProvider> getProviders() {
|
||||
return providers;
|
||||
}
|
||||
|
||||
public void register(WallProvider provider) {
|
||||
this.providers.add(provider);
|
||||
}
|
||||
|
||||
public void setProviders(List<WallProvider> providers) {
|
||||
this.providers.clear();
|
||||
this.providers.addAll(providers);
|
||||
}
|
||||
|
||||
public WallProviderStatLogger getStatLogger() {
|
||||
return statLogger;
|
||||
}
|
||||
|
||||
public void setStatLogger(WallProviderStatLogger statLogger) {
|
||||
this.statLogger = statLogger;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (statLogger == null) {
|
||||
throw new IllegalStateException("statLogger is null");
|
||||
|
||||
Reference in New Issue
Block a user