From b32ec31c0b67706e224ae732186f1edba83bd585 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 2 Aug 2013 19:45:51 +0800 Subject: [PATCH] fixed timeBetweenEvictionRunsMillis defaultValues --- .../alibaba/druid/filter/FilterManager.java | 303 ++++----- .../druid/pool/DruidAbstractDataSource.java | 10 +- .../alibaba/druid/pool/DruidDataSource.java | 42 +- .../vendor/MySqlValidConnectionChecker.java | 271 ++++---- .../vendor/OracleValidConnectionChecker.java | 251 +++---- .../com/alibaba/druid/proxy/DruidDriver.java | 641 +++++++++--------- .../java/com/alibaba/druid/util/IOUtils.java | 84 ++- .../com/alibaba/druid/util/JdbcUtils.java | 27 - .../com/alibaba/druid/wall/WallFilter.java | 50 +- .../druid/wall/WallProviderStatTimer.java | 70 +- .../druid/bvt/bug/Bug_for_JeffYin.java | 3 +- .../bvt/proxy/utils/DruidLoaderUtilsTest.java | 210 +++--- 12 files changed, 1047 insertions(+), 915 deletions(-) diff --git a/src/main/java/com/alibaba/druid/filter/FilterManager.java b/src/main/java/com/alibaba/druid/filter/FilterManager.java index 0aacf25f70..db4b489bdf 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterManager.java +++ b/src/main/java/com/alibaba/druid/filter/FilterManager.java @@ -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 aliasMap = new ConcurrentHashMap(16, 0.75f, 1); - - static { - try { - Properties filterProperties = loadFilterConfig(); - for (Map.Entry 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 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 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 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 aliasMap = new ConcurrentHashMap(16, 0.75f, 1); + + static { + try { + Properties filterProperties = loadFilterConfig(); + for (Map.Entry 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 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 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 filterList, String filterClassName) { + for (Filter filter : filterList) { + String itemFilterClassName = filter.getClass().getName(); + if (itemFilterClassName.equalsIgnoreCase(filterClassName)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 726753a29a..0481983c3d 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -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 { diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 3f0aad82b2..69f4b8a5af 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -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); } } } diff --git a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java index e4609cfb2c..68f316b08a 100644 --- a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java +++ b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java @@ -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); + } + + } + +} diff --git a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java index 6973dbfa87..e9f4c2f4da 100644 --- a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java +++ b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java @@ -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; + } +} diff --git a/src/main/java/com/alibaba/druid/proxy/DruidDriver.java b/src/main/java/com/alibaba/druid/proxy/DruidDriver.java index 3472728d46..7fd4b8c2b4 100644 --- a/src/main/java/com/alibaba/druid/proxy/DruidDriver.java +++ b/src/main/java/com/alibaba/druid/proxy/DruidDriver.java @@ -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 - */ -public class DruidDriver implements Driver, DruidDriverMBean { - - private static Log LOG; // lazy init - - private final static DruidDriver instance = new DruidDriver(); - - private final static ConcurrentMap proxyDataSources = new ConcurrentHashMap(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 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 + */ +public class DruidDriver implements Driver, DruidDriverMBean { + + private static Log LOG; // lazy init + + private final static DruidDriver instance = new DruidDriver(); + + private final static ConcurrentMap proxyDataSources = new ConcurrentHashMap(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 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(); + } +} diff --git a/src/main/java/com/alibaba/druid/util/IOUtils.java b/src/main/java/com/alibaba/druid/util/IOUtils.java index 4a8f2af165..187c4eed9f 100644 --- a/src/main/java/com/alibaba/druid/util/IOUtils.java +++ b/src/main/java/com/alibaba/druid/util/IOUtils.java @@ -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; + } + } } diff --git a/src/main/java/com/alibaba/druid/util/JdbcUtils.java b/src/main/java/com/alibaba/druid/util/JdbcUtils.java index 4af08bb45d..74add42b75 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcUtils.java +++ b/src/main/java/com/alibaba/druid/util/JdbcUtils.java @@ -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 data) throws SQLException { Connection conn = null; diff --git a/src/main/java/com/alibaba/druid/wall/WallFilter.java b/src/main/java/com/alibaba/druid/wall/WallFilter.java index c6b769d779..9a56bc5c4f 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFilter.java +++ b/src/main/java/com/alibaba/druid/wall/WallFilter.java @@ -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; } diff --git a/src/main/java/com/alibaba/druid/wall/WallProviderStatTimer.java b/src/main/java/com/alibaba/druid/wall/WallProviderStatTimer.java index b256f7fd6b..9bb9826fd9 100644 --- a/src/main/java/com/alibaba/druid/wall/WallProviderStatTimer.java +++ b/src/main/java/com/alibaba/druid/wall/WallProviderStatTimer.java @@ -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 providers = new CopyOnWriteArrayList(); + private ScheduledExecutorService scheduler; + private int threadCount = 1; + private long period = 60 * 5; + private TimeUnit unit = TimeUnit.SECONDS; - private WallProviderStatLogger statLogger; + private final List providers = new CopyOnWriteArrayList(); + + 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 getProviders() { return providers; } + + public void register(WallProvider provider) { + this.providers.add(provider); + } public void setProviders(List 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"); diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Bug_for_JeffYin.java b/src/test/java/com/alibaba/druid/bvt/bug/Bug_for_JeffYin.java index 1c1f61ed0c..60c6e27161 100644 --- a/src/test/java/com/alibaba/druid/bvt/bug/Bug_for_JeffYin.java +++ b/src/test/java/com/alibaba/druid/bvt/bug/Bug_for_JeffYin.java @@ -20,6 +20,7 @@ import java.sql.Driver; import junit.framework.Assert; import junit.framework.TestCase; +import com.alibaba.druid.util.IOUtils; import com.alibaba.druid.util.JdbcUtils; public class Bug_for_JeffYin extends TestCase { @@ -27,7 +28,7 @@ public class Bug_for_JeffYin extends TestCase { public void test_0() throws Exception { String url = "jdbc:sqlserver://localhost:1433;"; String driverClassName = JdbcUtils.getDriverClassName(url); - Class driverClass = JdbcUtils.loadDriverClass(driverClassName); + Class driverClass = IOUtils.loadClass(driverClassName); Assert.assertNotNull(driverClass); Driver driver = (Driver) driverClass.newInstance(); diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/utils/DruidLoaderUtilsTest.java b/src/test/java/com/alibaba/druid/bvt/proxy/utils/DruidLoaderUtilsTest.java index 81dafda2d1..eece1db374 100644 --- a/src/test/java/com/alibaba/druid/bvt/proxy/utils/DruidLoaderUtilsTest.java +++ b/src/test/java/com/alibaba/druid/bvt/proxy/utils/DruidLoaderUtilsTest.java @@ -1,105 +1,105 @@ -/* - * 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.bvt.proxy.utils; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.druid.bvt.proxy.DruidDriverTest.PublicJdbcFilterAdapter; -import com.alibaba.druid.filter.Filter; -import com.alibaba.druid.filter.FilterManager; -import com.alibaba.druid.util.JdbcUtils; - -/** - * druidLoader util 测试 - * - * @author gang.su - */ -public class DruidLoaderUtilsTest extends TestCase { - - public void testLoadFilter() throws SQLException { - - List filters = new ArrayList(); - // log4j - String filterItem = "log4j"; - FilterManager.loadFilter(filters, filterItem); - Filter filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.logging.Log4jFilter", filterConfig.getClass().getName()); - // stat - filterItem = "stat"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); - // default - filterItem = "default"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); - // counter - filterItem = "stat"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); - // commonLogging - filterItem = "commonLogging"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.logging.CommonsLogFilter", filterConfig.getClass().getName()); - // encoding - filterItem = "encoding"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterConfig = filters.get(0); - Assert.assertNotNull(filterConfig); - Assert.assertEquals("com.alibaba.druid.filter.encoding.EncodingConvertFilter", - filterConfig.getClass().getName()); - // 判定重复 - filterItem = "stat"; - filters.clear(); - FilterManager.loadFilter(filters, filterItem); - filterItem = "default"; - FilterManager.loadFilter(filters, filterItem); - for (Iterator iterator = filters.iterator(); iterator.hasNext();) { - Filter filter = (Filter) iterator.next(); - System.out.println(filter.getClass().getName()); - } - // default - } - - public void twest_loadClass() throws Exception { - Assert.assertEquals(null, JdbcUtils.loadDriverClass(null)); - Assert.assertEquals(null, JdbcUtils.loadDriverClass("xxx")); - Assert.assertEquals(PublicJdbcFilterAdapter.class, - JdbcUtils.loadDriverClass(PublicJdbcFilterAdapter.class.getName())); - Assert.assertNull(JdbcUtils.loadDriverClass(null)); - Assert.assertNull(JdbcUtils.loadDriverClass("")); - } - -} +/* + * 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.bvt.proxy.utils; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.bvt.proxy.DruidDriverTest.PublicJdbcFilterAdapter; +import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.FilterManager; +import com.alibaba.druid.util.IOUtils; + +/** + * druidLoader util 测试 + * + * @author gang.su + */ +public class DruidLoaderUtilsTest extends TestCase { + + public void testLoadFilter() throws SQLException { + + List filters = new ArrayList(); + // log4j + String filterItem = "log4j"; + FilterManager.loadFilter(filters, filterItem); + Filter filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.logging.Log4jFilter", filterConfig.getClass().getName()); + // stat + filterItem = "stat"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); + // default + filterItem = "default"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); + // counter + filterItem = "stat"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.stat.StatFilter", filterConfig.getClass().getName()); + // commonLogging + filterItem = "commonLogging"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.logging.CommonsLogFilter", filterConfig.getClass().getName()); + // encoding + filterItem = "encoding"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterConfig = filters.get(0); + Assert.assertNotNull(filterConfig); + Assert.assertEquals("com.alibaba.druid.filter.encoding.EncodingConvertFilter", + filterConfig.getClass().getName()); + // 判定重复 + filterItem = "stat"; + filters.clear(); + FilterManager.loadFilter(filters, filterItem); + filterItem = "default"; + FilterManager.loadFilter(filters, filterItem); + for (Iterator iterator = filters.iterator(); iterator.hasNext();) { + Filter filter = (Filter) iterator.next(); + System.out.println(filter.getClass().getName()); + } + // default + } + + public void twest_loadClass() throws Exception { + Assert.assertEquals(null, IOUtils.loadClass(null)); + Assert.assertEquals(null, IOUtils.loadClass("xxx")); + Assert.assertEquals(PublicJdbcFilterAdapter.class, + IOUtils.loadClass(PublicJdbcFilterAdapter.class.getName())); + Assert.assertNull(IOUtils.loadClass(null)); + Assert.assertNull(IOUtils.loadClass("")); + } + +}