From 72ef1a1532a914c18988bda65187c30365c5cc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Sat, 17 Mar 2012 13:00:25 +0800 Subject: [PATCH] refactor --- .../java/com/alibaba/druid/filter/Filter.java | 2 + .../alibaba/druid/filter/FilterAdapter.java | 5 +++ .../alibaba/druid/filter/stat/StatFilter.java | 15 ++++++- .../alibaba/druid/filter/wall/WallConfig.java | 8 ++-- .../alibaba/druid/filter/wall/WallFilter.java | 33 +++++++++++--- .../alibaba/druid/pool/DruidDataSource.java | 4 ++ .../druid/sql/visitor/SchemaStatVisitor.java | 4 ++ .../com/alibaba/druid/stat/JdbcSqlStat.java | 3 +- .../bvt/pool/DruidDataSourceFilterTest.java | 19 +++++--- .../com/alibaba/druid/bvt/pool/ParamTest.java | 43 +++++++++++++------ 10 files changed, 103 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/alibaba/druid/filter/Filter.java b/src/main/java/com/alibaba/druid/filter/Filter.java index eee0cea9ba..83032e8822 100644 --- a/src/main/java/com/alibaba/druid/filter/Filter.java +++ b/src/main/java/com/alibaba/druid/filter/Filter.java @@ -59,6 +59,8 @@ import com.alibaba.druid.proxy.jdbc.StatementProxy; public interface Filter { void init(DataSourceProxy dataSource); + + void destory(); ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException; diff --git a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java index d6c1c5fa34..662f942388 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java @@ -67,6 +67,11 @@ public abstract class FilterAdapter extends NotificationBroadcasterSupport imple public void init(DataSourceProxy dataSource) { this.dataSource = dataSource; } + + @Override + public void destory() { + + } @Override public Array callableStatement_getArray(FilterChain chain, CallableStatementProxy statement, int parameterIndex) diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index b361788214..431f185399 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -123,7 +123,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } @Override - public void init(DataSourceProxy dataSource) { + public synchronized void init(DataSourceProxy dataSource) { this.dataSource = dataSource; ConcurrentMap dataSourceStats = JdbcStatManager.getInstance().getDataSources(); @@ -136,6 +136,19 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { } this.dataSourceStat = stat; } + + @Override + public synchronized void destory() { + if (dataSource == null) { + return; + } + + ConcurrentMap dataSourceStats = JdbcStatManager.getInstance().getDataSources(); + String url = dataSource.getUrl(); + dataSourceStats.remove(url); + + dataSource = null; + } public ConnectionProxy connection_connect(FilterChain chain, Properties info) throws SQLException { ConnectionProxy connection = null; diff --git a/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java b/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java index 428ed7d2d3..cac7b1b4a0 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java +++ b/src/main/java/com/alibaba/druid/filter/wall/WallConfig.java @@ -32,8 +32,6 @@ public class WallConfig { protected final Set permitNames = new HashSet(); protected final Set permitObjects = new HashSet(); - - public void loadDefault(String dir) { if (dir.endsWith("/")) { dir = dir.substring(0, dir.length() - 1); @@ -49,7 +47,7 @@ public class WallConfig { if (dir.endsWith("/")) { dir = dir.substring(0, dir.length() - 1); } - + loadResource(getPermitNames(), dir + "permit-name.txt"); loadResource(getPermitSchemas(), dir + "permit-schema.txt"); loadResource(getPermitFunctions(), dir + "permit-function.txt"); @@ -172,7 +170,7 @@ public class WallConfig { public Set getPermitObjects() { return permitObjects; } - + public boolean isPermitObjects(String name) { name = WallVisitorUtils.form(name); return permitObjects.contains(name); @@ -182,7 +180,7 @@ public class WallConfig { name = WallVisitorUtils.form(name); return this.permitSchemas.contains(name); } - + public boolean isPermitFunction(String name) { name = WallVisitorUtils.form(name); return this.permitFunctions.contains(name); diff --git a/src/main/java/com/alibaba/druid/filter/wall/WallFilter.java b/src/main/java/com/alibaba/druid/filter/wall/WallFilter.java index 90068c6c72..db1fcac6cd 100644 --- a/src/main/java/com/alibaba/druid/filter/wall/WallFilter.java +++ b/src/main/java/com/alibaba/druid/filter/wall/WallFilter.java @@ -8,6 +8,8 @@ import com.alibaba.druid.filter.FilterAdapter; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.filter.wall.spi.MySqlWallProvider; import com.alibaba.druid.filter.wall.spi.OracleWallProvider; +import com.alibaba.druid.logging.Log; +import com.alibaba.druid.logging.LogFactory; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; import com.alibaba.druid.proxy.jdbc.DataSourceProxy; @@ -18,15 +20,19 @@ import com.alibaba.druid.util.JdbcUtils; public class WallFilter extends FilterAdapter { - private boolean inited = false; + private final static Log LOG = LogFactory.getLog(WallFilter.class); - private WallProvider provider; + private boolean inited = false; - private boolean loadDefault; + private WallProvider provider; - private boolean loadExtend; + private boolean loadDefault; - private WallConfig config = new WallConfig(); + private boolean loadExtend; + + private boolean logViolation = false; + + private WallConfig config = new WallConfig(); @Override public void init(DataSourceProxy dataSource) { @@ -37,6 +43,14 @@ public class WallFilter extends FilterAdapter { this.inited = true; } + public boolean isLogViolation() { + return logViolation; + } + + public void setLogViolation(boolean logViolation) { + this.logViolation = logViolation; + } + public WallProvider getProvider() { return provider; } @@ -210,7 +224,14 @@ public class WallFilter extends FilterAdapter { } public void check(ConnectionProxy connection, String sql) throws SQLException { - provider.check(sql, true); + try { + provider.check(sql, true); + } catch (WallRuntimeException e) { + if (isLogViolation()) { + LOG.error("sql injection violation : " + sql, e); + } + throw e; + } } public WallProvider createWallProvider(String dbType) { diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 61473b16ed..7db9dd6102 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -687,6 +687,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat notEmptySignalCount++; this.closed = true; + + for (Filter filter : filters) { + filter.destory(); + } } finally { lock.unlock(); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index 557dee300b..1fa89ebf3f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -671,6 +671,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLExprTableSource x) { if (isSimpleExprTableSource(x)) { String ident = x.getExpr().toString(); + + if (variants.containsKey(ident)) { + return false; + } if (subQueryMap.containsKey(ident)) { return false; diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 4992699ba7..971b841f24 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -391,7 +391,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { // 25 - new ArrayType(SimpleType.LONG, true), // - new ArrayType(SimpleType.STRING, true), // + new ArrayType(SimpleType.STRING, false), // }; String[] indexNames = { @@ -490,6 +490,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("InTransactionCount", getInTransactionCount()); map.put("Histogram", this.histogram.toArray()); + map.put("LastSlowParameters", lastSlowParameters); return map; diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java index 32288d2acf..f1f591608c 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceFilterTest.java @@ -7,6 +7,7 @@ import junit.framework.TestCase; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.stat.DruidDataSourceStatManager; +import com.alibaba.druid.stat.JdbcDataSourceStat; import com.alibaba.druid.stat.JdbcStatManager; public class DruidDataSourceFilterTest extends TestCase { @@ -52,20 +53,24 @@ public class DruidDataSourceFilterTest extends TestCase { dataSource.setFilters("stat"); JdbcStatManager.getInstance().reset(); + + dataSource.init(); + Assert.assertEquals(1, JdbcStatManager.getInstance().getDataSources().size()); + JdbcDataSourceStat dataSourceStat = JdbcStatManager.getInstance().getDataSources().values().iterator().next(); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + Assert.assertEquals(0, dataSourceStat.getConnectionStat().getConnectCount()); Assert.assertEquals(1, dataSource.getProxyFilters().size()); for (int i = 0; i < 2; ++i) { Connection conn = dataSource.getConnection(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); + Assert.assertEquals(1, dataSourceStat.getConnectionStat().getConnectCount()); + Assert.assertEquals(0, dataSourceStat.getConnectionStat().getCloseCount()); conn.close(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); // logic + Assert.assertEquals(1, dataSourceStat.getConnectionStat().getConnectCount()); + Assert.assertEquals(0, dataSourceStat.getConnectionStat().getCloseCount()); // logic // close不会导致计数器+1 } @@ -73,7 +78,7 @@ public class DruidDataSourceFilterTest extends TestCase { dataSource.close(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); + Assert.assertEquals(1, dataSourceStat.getConnectionStat().getConnectCount()); + Assert.assertEquals(1, dataSourceStat.getConnectionStat().getCloseCount()); } } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/ParamTest.java b/src/test/java/com/alibaba/druid/bvt/pool/ParamTest.java index dec7c18d72..4363a8a08b 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/ParamTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/ParamTest.java @@ -7,6 +7,7 @@ import junit.framework.TestCase; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.stat.DruidDataSourceStatManager; +import com.alibaba.druid.stat.JdbcDataSourceStat; import com.alibaba.druid.stat.JdbcStatManager; public class ParamTest extends TestCase { @@ -29,31 +30,39 @@ public class ParamTest extends TestCase { JdbcStatManager.getInstance().reset(); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + dataSource.init(); + Assert.assertEquals(1, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + Assert.assertEquals(1, JdbcStatManager.getInstance().getDataSources().size()); + + JdbcDataSourceStat stat = JdbcStatManager.getInstance().getDataSources().values().iterator().next(); + + Assert.assertEquals(0, stat.getConnectionStat().getConnectCount()); Assert.assertEquals(1, dataSource.getProxyFilters().size()); for (int i = 0; i < 2; ++i) { Connection conn = dataSource.getConnection(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); + Assert.assertEquals(1, stat.getConnectionStat().getConnectCount()); + Assert.assertEquals(0, stat.getConnectionStat().getCloseCount()); conn.close(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); // logic - // close不会导致计数器+1 + Assert.assertEquals(1, stat.getConnectionStat().getConnectCount()); + Assert.assertEquals(0, stat.getConnectionStat().getCloseCount()); // logic + // close不会导致计数器+1 } dataSource.close(); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(1, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); + Assert.assertEquals(0, JdbcStatManager.getInstance().getDataSources().size()); + + Assert.assertEquals(1, stat.getConnectionStat().getConnectCount()); + Assert.assertEquals(1, stat.getConnectionStat().getCloseCount()); JdbcStatManager.getInstance().reset(); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getCloseCount()); + Assert.assertEquals(1, stat.getConnectionStat().getConnectCount()); + Assert.assertEquals(1, stat.getConnectionStat().getCloseCount()); } public void test_zero() throws Exception { @@ -70,7 +79,9 @@ public class ParamTest extends TestCase { JdbcStatManager.getInstance().reset(); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + Assert.assertEquals(0, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + Assert.assertEquals(0, JdbcStatManager.getInstance().getDataSources().size()); + Assert.assertEquals(1, dataSource.getProxyFilters().size()); Exception error = null; @@ -96,15 +107,21 @@ public class ParamTest extends TestCase { Assert.assertEquals(1, dataSource.getProxyFilters().size()); JdbcStatManager.getInstance().reset(); + + dataSource.init(); + Assert.assertEquals(1, DruidDataSourceStatManager.getInstance().getDataSourceList().size()); + Assert.assertEquals(1, JdbcStatManager.getInstance().getDataSources().size()); - Assert.assertEquals(0, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + JdbcDataSourceStat stat = JdbcStatManager.getInstance().getDataSources().values().iterator().next(); + + Assert.assertEquals(10, stat.getConnectionStat().getConnectCount()); for (int i = 0; i < 10; ++i) { Connection conn = dataSource.getConnection(); conn.close(); } - Assert.assertEquals(10, JdbcStatManager.getInstance().getConnectionstat().getConnectCount()); + Assert.assertEquals(10, stat.getConnectionStat().getConnectCount()); dataSource.close(); }