mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improve sql-wall
This commit is contained in:
@@ -527,5 +527,11 @@
|
||||
<version>2.0.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.1.29</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -18,7 +18,9 @@ package com.alibaba.druid.util;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
|
||||
import com.alibaba.druid.stat.JdbcSqlStat;
|
||||
@@ -75,4 +77,20 @@ public class JdbcSqlStatUtils {
|
||||
return updater.get(stat);
|
||||
}
|
||||
}
|
||||
|
||||
public static long get(AtomicLong counter, boolean reset) {
|
||||
if (reset) {
|
||||
return counter.getAndSet(0);
|
||||
} else {
|
||||
return counter.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static int get(AtomicInteger counter, boolean reset) {
|
||||
if (reset) {
|
||||
return counter.getAndSet(0);
|
||||
} else {
|
||||
return counter.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.JdbcSqlStatUtils.get;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
@@ -47,4 +49,9 @@ public class WallFunctionStat {
|
||||
return map;
|
||||
}
|
||||
|
||||
public WallFunctionStatValue getStatValue(boolean reset) {
|
||||
WallFunctionStatValue statValue = new WallFunctionStatValue();
|
||||
statValue.setInvokeCount(get(this, invokeCountUpdater, reset));
|
||||
return statValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.wall;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WallFunctionStatValue {
|
||||
|
||||
private String name;
|
||||
private long invokeCount;
|
||||
|
||||
public WallFunctionStatValue(){
|
||||
|
||||
}
|
||||
|
||||
public WallFunctionStatValue(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getInvokeCount() {
|
||||
return invokeCount;
|
||||
}
|
||||
|
||||
public void setInvokeCount(long invokeCount) {
|
||||
this.invokeCount = invokeCount;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>(2);
|
||||
map.put("name", name);
|
||||
map.put("invokeCount", invokeCount);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -15,17 +15,19 @@
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.JdbcSqlStatUtils.get;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
@@ -45,6 +47,11 @@ import com.alibaba.druid.wall.violation.SyntaxErrorViolation;
|
||||
|
||||
public abstract class WallProvider {
|
||||
|
||||
private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>(
|
||||
1,
|
||||
0.75f,
|
||||
1);
|
||||
|
||||
private LRUCache<String, WallSqlStat> whiteList;
|
||||
private LRUCache<String, WallSqlStat> whiteMergedList;
|
||||
|
||||
@@ -92,6 +99,10 @@ public abstract class WallProvider {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.checkCount.set(0);
|
||||
this.hardCheckCount.set(0);
|
||||
@@ -238,6 +249,7 @@ public abstract class WallProvider {
|
||||
if (wallStat == null) {
|
||||
wallStat = new WallSqlStat(tableStats, functionStats, syntaxError);
|
||||
whiteMergedList.put(mergedSql, wallStat);
|
||||
wallStat.setSample(sql);
|
||||
}
|
||||
|
||||
wallStat.incrementAndGetExecuteCount();
|
||||
@@ -275,6 +287,7 @@ public abstract class WallProvider {
|
||||
if (wallStat == null) {
|
||||
wallStat = new WallSqlStat(tableStats, functionStats, violations, syntaxError);
|
||||
blackMergedList.put(mergedSql, wallStat);
|
||||
wallStat.setSample(sql);
|
||||
}
|
||||
|
||||
wallStat.incrementAndGetExecuteCount();
|
||||
@@ -332,34 +345,6 @@ public abstract class WallProvider {
|
||||
return Collections.<String> unmodifiableSet(hashSet);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getBlackListStat() {
|
||||
List<Map<String, Object>> map = new ArrayList<Map<String, Object>>();
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (blackList != null) {
|
||||
for (Map.Entry<String, WallSqlStat> entry : this.blackList.entrySet()) {
|
||||
WallSqlStat sqlStat = entry.getValue();
|
||||
|
||||
Map<String, Object> sqlStatMap = new LinkedHashMap<String, Object>();
|
||||
sqlStatMap.put("sql", entry.getKey());
|
||||
sqlStatMap.put("executeCount", sqlStat.getExecuteCount());
|
||||
sqlStatMap.put("effectRowCount", sqlStat.getEffectRowCount());
|
||||
|
||||
List<Violation> violations = sqlStat.getViolations();
|
||||
if (violations.size() > 0) {
|
||||
sqlStatMap.put("violationMessage", violations.get(0).getMessage());
|
||||
}
|
||||
|
||||
map.add(sqlStatMap);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
@@ -818,39 +803,67 @@ public abstract class WallProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public WallProviderStatValue getStatValue(boolean reset) {
|
||||
WallProviderStatValue statValue = new WallProviderStatValue();
|
||||
|
||||
statValue.setCheckCount(get(checkCount, reset));
|
||||
statValue.setHardCheckCount(get(hardCheckCount, reset));
|
||||
statValue.setViolationCount(get(violationCount, reset));
|
||||
statValue.setViolationEffectRowCount(get(violationEffectRowCount, reset));
|
||||
statValue.setBlackListHitCount(get(blackListHitCount, reset));
|
||||
statValue.setWhiteListHitCount(get(whiteListHitCount, reset));
|
||||
statValue.setSyntaxErrorCount(get(syntaxErrrorCount, reset));
|
||||
|
||||
for (Map.Entry<String, WallTableStat> entry : this.tableStats.entrySet()) {
|
||||
String tableName = entry.getKey();
|
||||
WallTableStat tableStat = entry.getValue();
|
||||
|
||||
WallTableStatValue tableStatValue = tableStat.getStatValue(reset);
|
||||
tableStatValue.setName(tableName);
|
||||
|
||||
statValue.getTables().add(tableStatValue);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, WallFunctionStat> entry : this.functionStats.entrySet()) {
|
||||
String functionName = entry.getKey();
|
||||
WallFunctionStat functionStat = entry.getValue();
|
||||
|
||||
WallFunctionStatValue functionStatValue = functionStat.getStatValue(reset);
|
||||
functionStatValue.setName(functionName);
|
||||
|
||||
statValue.getFunctions().add(functionStatValue);
|
||||
}
|
||||
|
||||
final Lock lock = reset ? this.lock.writeLock() : this.lock.readLock();
|
||||
lock.lock();
|
||||
try {
|
||||
if (this.whiteMergedList != null) {
|
||||
for (Map.Entry<String, WallSqlStat> entry : whiteMergedList.entrySet()) {
|
||||
String sql = entry.getKey();
|
||||
WallSqlStat sqlStat = entry.getValue();
|
||||
WallSqlStatValue sqlStatValue = sqlStat.getStatValue(reset);
|
||||
sqlStatValue.setSql(sql);
|
||||
statValue.getWhiteList().add(sqlStatValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.blackMergedList != null) {
|
||||
for (Map.Entry<String, WallSqlStat> entry : blackMergedList.entrySet()) {
|
||||
String sql = entry.getKey();
|
||||
WallSqlStat sqlStat = entry.getValue();
|
||||
WallSqlStatValue sqlStatValue = sqlStat.getStatValue(reset);
|
||||
sqlStatValue.setSql(sql);
|
||||
statValue.getBlackList().add(sqlStatValue);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return statValue;
|
||||
}
|
||||
|
||||
public Map<String, Object> getStatsMap() {
|
||||
Map<String, Object> info = new LinkedHashMap<String, Object>();
|
||||
|
||||
info.put("checkCount", this.getCheckCount());
|
||||
info.put("hardCheckCount", this.getHardCheckCount());
|
||||
info.put("violationCount", this.getViolationCount());
|
||||
info.put("violationEffectRowCount", this.getViolationEffectRowCount());
|
||||
info.put("blackListHitCount", this.getBlackListHitCount());
|
||||
info.put("blackListSize", this.getBlackList().size());
|
||||
info.put("whiteListHitCount", this.getWhiteListHitCount());
|
||||
info.put("whiteListSize", this.getWhiteList().size());
|
||||
info.put("syntaxErrrorCount", this.getSyntaxErrorCount());
|
||||
|
||||
{
|
||||
List<Map<String, Object>> tables = new ArrayList<Map<String, Object>>();
|
||||
for (Map.Entry<String, WallTableStat> entry : this.tableStats.entrySet()) {
|
||||
Map<String, Object> statMap = entry.getValue().toMap();
|
||||
statMap.put("name", entry.getKey());
|
||||
tables.add(statMap);
|
||||
}
|
||||
info.put("tables", tables);
|
||||
}
|
||||
{
|
||||
List<Map<String, Object>> functions = new ArrayList<Map<String, Object>>();
|
||||
for (Map.Entry<String, WallFunctionStat> entry : this.functionStats.entrySet()) {
|
||||
Map<String, Object> statMap = entry.getValue().toMap();
|
||||
statMap.put("name", entry.getKey());
|
||||
functions.add(statMap);
|
||||
}
|
||||
info.put("functions", functions);
|
||||
}
|
||||
// info.put("whiteList", this.getWhiteList());
|
||||
info.put("blackList", this.getBlackListStat());
|
||||
return info;
|
||||
return getStatValue(false).toMap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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.wall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WallProviderStatValue {
|
||||
|
||||
private long checkCount;
|
||||
private long hardCheckCount;
|
||||
private long violationCount;
|
||||
private long whiteListHitCount;
|
||||
private long blackListHitCount;
|
||||
private long syntaxErrroCount;
|
||||
private long violationEffectRowCount;
|
||||
|
||||
private final List<WallTableStatValue> tables = new ArrayList<WallTableStatValue>();
|
||||
private final List<WallFunctionStatValue> functions = new ArrayList<WallFunctionStatValue>();
|
||||
|
||||
private final List<WallSqlStatValue> whiteList = new ArrayList<WallSqlStatValue>();
|
||||
private final List<WallSqlStatValue> blackList = new ArrayList<WallSqlStatValue>();
|
||||
|
||||
public long getCheckCount() {
|
||||
return checkCount;
|
||||
}
|
||||
|
||||
public void setCheckCount(long checkCount) {
|
||||
this.checkCount = checkCount;
|
||||
}
|
||||
|
||||
public long getHardCheckCount() {
|
||||
return hardCheckCount;
|
||||
}
|
||||
|
||||
public void setHardCheckCount(long hardCheckCount) {
|
||||
this.hardCheckCount = hardCheckCount;
|
||||
}
|
||||
|
||||
public long getViolationCount() {
|
||||
return violationCount;
|
||||
}
|
||||
|
||||
public void setViolationCount(long violationCount) {
|
||||
this.violationCount = violationCount;
|
||||
}
|
||||
|
||||
public long getWhiteListHitCount() {
|
||||
return whiteListHitCount;
|
||||
}
|
||||
|
||||
public void setWhiteListHitCount(long whiteListHitCount) {
|
||||
this.whiteListHitCount = whiteListHitCount;
|
||||
}
|
||||
|
||||
public long getBlackListHitCount() {
|
||||
return blackListHitCount;
|
||||
}
|
||||
|
||||
public void setBlackListHitCount(long blackListHitCount) {
|
||||
this.blackListHitCount = blackListHitCount;
|
||||
}
|
||||
|
||||
public long getSyntaxErrorCount() {
|
||||
return syntaxErrroCount;
|
||||
}
|
||||
|
||||
public void setSyntaxErrorCount(long syntaxErrroCount) {
|
||||
this.syntaxErrroCount = syntaxErrroCount;
|
||||
}
|
||||
|
||||
public long getViolationEffectRowCount() {
|
||||
return violationEffectRowCount;
|
||||
}
|
||||
|
||||
public void setViolationEffectRowCount(long violationEffectRowCount) {
|
||||
this.violationEffectRowCount = violationEffectRowCount;
|
||||
}
|
||||
|
||||
public List<WallTableStatValue> getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
public List<WallFunctionStatValue> getFunctions() {
|
||||
return functions;
|
||||
}
|
||||
|
||||
public List<WallSqlStatValue> getWhiteList() {
|
||||
return whiteList;
|
||||
}
|
||||
|
||||
public List<WallSqlStatValue> getBlackList() {
|
||||
return blackList;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> info = new LinkedHashMap<String, Object>();
|
||||
|
||||
info.put("checkCount", this.getCheckCount());
|
||||
info.put("hardCheckCount", this.getHardCheckCount());
|
||||
info.put("violationCount", this.getViolationCount());
|
||||
info.put("violationEffectRowCount", this.getViolationEffectRowCount());
|
||||
info.put("blackListHitCount", this.getBlackListHitCount());
|
||||
info.put("blackListSize", this.getBlackList().size());
|
||||
info.put("whiteListHitCount", this.getWhiteListHitCount());
|
||||
info.put("whiteListSize", this.getWhiteList().size());
|
||||
info.put("syntaxErrrorCount", this.getSyntaxErrorCount());
|
||||
|
||||
{
|
||||
List<Map<String, Object>> tables = new ArrayList<Map<String, Object>>(this.tables.size());
|
||||
for (WallTableStatValue tableStatValue : this.tables) {
|
||||
Map<String, Object> statMap = tableStatValue.toMap();
|
||||
tables.add(statMap);
|
||||
}
|
||||
info.put("tables", tables);
|
||||
}
|
||||
|
||||
{
|
||||
List<Map<String, Object>> functions = new ArrayList<Map<String, Object>>();
|
||||
for (WallFunctionStatValue funStatValue : this.functions) {
|
||||
Map<String, Object> statMap = funStatValue.toMap();
|
||||
functions.add(statMap);
|
||||
}
|
||||
info.put("functions", functions);
|
||||
}
|
||||
|
||||
{
|
||||
List<Map<String, Object>> blackList = new ArrayList<Map<String, Object>>(this.blackList.size());
|
||||
for (WallSqlStatValue sqlStatValue : this.blackList) {
|
||||
blackList.add(sqlStatValue.toMap());
|
||||
}
|
||||
info.put("blackList", blackList);
|
||||
}
|
||||
|
||||
{
|
||||
List<Map<String, Object>> whiteList = new ArrayList<Map<String, Object>>(this.whiteList.size());
|
||||
for (WallSqlStatValue sqlStatValue : this.whiteList) {
|
||||
whiteList.add(sqlStatValue.toMap());
|
||||
}
|
||||
info.put("whiteList", whiteList);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.JdbcSqlStatUtils.get;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -29,7 +31,7 @@ public class WallSqlStat {
|
||||
"executeCount");
|
||||
final static AtomicLongFieldUpdater<WallSqlStat> effectRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WallSqlStat.class,
|
||||
"effectRowCount");
|
||||
|
||||
|
||||
private final Map<String, WallSqlTableStat> tableStats;
|
||||
|
||||
private final List<Violation> violations;
|
||||
@@ -38,6 +40,8 @@ public class WallSqlStat {
|
||||
|
||||
private final boolean syntaxError;
|
||||
|
||||
private String sample;
|
||||
|
||||
public WallSqlStat(Map<String, WallSqlTableStat> tableStats, Map<String, WallSqlFunctionStat> functionStats,
|
||||
boolean syntaxError){
|
||||
this(tableStats, functionStats, Collections.<Violation> emptyList(), syntaxError);
|
||||
@@ -51,6 +55,14 @@ public class WallSqlStat {
|
||||
this.syntaxError = syntaxError;
|
||||
}
|
||||
|
||||
public String getSample() {
|
||||
return sample;
|
||||
}
|
||||
|
||||
public void setSample(String sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
public long incrementAndGetExecuteCount() {
|
||||
return executeCountUpdater.incrementAndGet(this);
|
||||
}
|
||||
@@ -58,15 +70,15 @@ public class WallSqlStat {
|
||||
public long getExecuteCount() {
|
||||
return executeCount;
|
||||
}
|
||||
|
||||
|
||||
public long incrementAndGetEffectRowCount() {
|
||||
return effectRowCountUpdater.incrementAndGet(this);
|
||||
}
|
||||
|
||||
|
||||
public long addAndGetEffectRowCount(long delta) {
|
||||
return effectRowCountUpdater.addAndGet(this, delta);
|
||||
}
|
||||
|
||||
|
||||
public long getEffectRowCount() {
|
||||
return effectRowCount;
|
||||
}
|
||||
@@ -86,4 +98,19 @@ public class WallSqlStat {
|
||||
public boolean isSyntaxError() {
|
||||
return syntaxError;
|
||||
}
|
||||
|
||||
public WallSqlStatValue getStatValue(boolean reset) {
|
||||
final WallSqlStatValue statValue = new WallSqlStatValue();
|
||||
|
||||
statValue.setExecuteCount(get(this, executeCountUpdater, reset));
|
||||
statValue.setEffectRowCount(get(this, effectRowCountUpdater, reset));
|
||||
statValue.setSyntaxError(this.syntaxError);
|
||||
statValue.setSqlSample(sample);
|
||||
if (violations.size() > 0) {
|
||||
String violationMessage = violations.get(0).getMessage();
|
||||
statValue.setViolationMessage(violationMessage);
|
||||
}
|
||||
|
||||
return statValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.wall;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WallSqlStatValue {
|
||||
|
||||
private String sql;
|
||||
private String sqlSample;
|
||||
private long executeCount;
|
||||
private long effectRowCount;
|
||||
private boolean syntaxError;
|
||||
private String violationMessage;
|
||||
|
||||
public WallSqlStatValue(){
|
||||
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public void setSql(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public String getSqlSample() {
|
||||
return sqlSample;
|
||||
}
|
||||
|
||||
public void setSqlSample(String sqlSample) {
|
||||
this.sqlSample = sqlSample;
|
||||
}
|
||||
|
||||
public long getExecuteCount() {
|
||||
return executeCount;
|
||||
}
|
||||
|
||||
public void setExecuteCount(long executeCount) {
|
||||
this.executeCount = executeCount;
|
||||
}
|
||||
|
||||
public long getEffectRowCount() {
|
||||
return effectRowCount;
|
||||
}
|
||||
|
||||
public void setEffectRowCount(long effectRowCount) {
|
||||
this.effectRowCount = effectRowCount;
|
||||
}
|
||||
|
||||
public boolean isSyntaxError() {
|
||||
return syntaxError;
|
||||
}
|
||||
|
||||
public void setSyntaxError(boolean syntaxError) {
|
||||
this.syntaxError = syntaxError;
|
||||
}
|
||||
|
||||
public String getViolationMessage() {
|
||||
return violationMessage;
|
||||
}
|
||||
|
||||
public void setViolationMessage(String violationMessage) {
|
||||
this.violationMessage = violationMessage;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> sqlStatMap = new LinkedHashMap<String, Object>();
|
||||
sqlStatMap.put("sql", sql);
|
||||
if (sql != sqlSample) {
|
||||
sqlStatMap.put("sample", sqlSample);
|
||||
}
|
||||
sqlStatMap.put("executeCount", getExecuteCount());
|
||||
sqlStatMap.put("effectRowCount", getEffectRowCount());
|
||||
sqlStatMap.put("violationMessage", getViolationMessage());
|
||||
|
||||
return sqlStatMap;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,3 @@
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
|
||||
import com.alibaba.druid.support.json.JSONUtils;
|
||||
|
||||
/*
|
||||
* Copyright 1999-2011 Alibaba Group Holding Ltd.
|
||||
*
|
||||
@@ -21,6 +13,16 @@ import com.alibaba.druid.support.json.JSONUtils;
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.wall;
|
||||
|
||||
import static com.alibaba.druid.util.JdbcSqlStatUtils.get;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
|
||||
import com.alibaba.druid.support.json.JSONUtils;
|
||||
|
||||
public class WallTableStat {
|
||||
|
||||
private volatile long selectCount;
|
||||
@@ -124,7 +126,7 @@ public class WallTableStat {
|
||||
public long getUpdateDataCount() {
|
||||
return this.updateDataCount;
|
||||
}
|
||||
|
||||
|
||||
public long getInsertDataCount() {
|
||||
return this.insertDataCount;
|
||||
}
|
||||
@@ -132,7 +134,7 @@ public class WallTableStat {
|
||||
public void addInsertDataCount(long delta) {
|
||||
insertDataCountUpdater.addAndGet(this, delta);
|
||||
}
|
||||
|
||||
|
||||
public void addUpdateDataCount(long delta) {
|
||||
updateDataCountUpdater.addAndGet(this, delta);
|
||||
}
|
||||
@@ -220,43 +222,26 @@ public class WallTableStat {
|
||||
return toMap(map);
|
||||
}
|
||||
|
||||
public WallTableStatValue getStatValue(boolean reset) {
|
||||
WallTableStatValue statValue = new WallTableStatValue();
|
||||
|
||||
statValue.setSelectCount(get(this, selectCountUpdater, reset));
|
||||
statValue.setDeleteCount(get(this, deleteCountUpdater, reset));
|
||||
statValue.setInsertCount(get(this, insertCountUpdater, reset));
|
||||
statValue.setUpdateCount(get(this, updateCountUpdater, reset));
|
||||
statValue.setAlterCount(get(this, alterCountUpdater, reset));
|
||||
statValue.setDropCount(get(this, dropCountUpdater, reset));
|
||||
statValue.setCreateCount(get(this, createCountUpdater, reset));
|
||||
statValue.setTruncateCount(get(this, truncateCountUpdater, reset));
|
||||
statValue.setReplaceCount(get(this, replaceCountUpdater, reset));
|
||||
statValue.setDeleteDataCount(get(this, deleteDataCountUpdater, reset));
|
||||
statValue.setFetchRowCount(get(this, fetchRowCountUpdater, reset));
|
||||
statValue.setUpdateDataCount(get(this, updateDataCountUpdater, reset));
|
||||
|
||||
return statValue;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap(Map<String, Object> map) {
|
||||
if (selectCount > 0) {
|
||||
map.put("selectCount", selectCount);
|
||||
}
|
||||
if (deleteCount > 0) {
|
||||
map.put("deleteCount", deleteCount);
|
||||
}
|
||||
if (insertCount > 0) {
|
||||
map.put("insertCount", insertCount);
|
||||
}
|
||||
if (updateCount > 0) {
|
||||
map.put("updateCount", updateCount);
|
||||
}
|
||||
if (alterCount > 0) {
|
||||
map.put("alterCount", alterCount);
|
||||
}
|
||||
if (dropCount > 0) {
|
||||
map.put("dropCount", dropCount);
|
||||
}
|
||||
if (createCount > 0) {
|
||||
map.put("createCount", createCount);
|
||||
}
|
||||
if (truncateCount > 0) {
|
||||
map.put("truncateCount", truncateCount);
|
||||
}
|
||||
if (replaceCount > 0) {
|
||||
map.put("replaceCount", replaceCount);
|
||||
}
|
||||
if (deleteDataCount > 0) {
|
||||
map.put("deleteDataCount", deleteDataCount);
|
||||
}
|
||||
if (fetchRowCount > 0) {
|
||||
map.put("fetchRowCount", fetchRowCount);
|
||||
}
|
||||
if (updateDataCount > 0) {
|
||||
map.put("updateDataCount", updateDataCount);
|
||||
}
|
||||
return map;
|
||||
return getStatValue(false).toMap(map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.wall;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WallTableStatValue {
|
||||
|
||||
private String name;
|
||||
|
||||
private long selectCount;
|
||||
private long selectIntoCount;
|
||||
private long insertCount;
|
||||
private long updateCount;
|
||||
private long deleteCount;
|
||||
private long truncateCount;
|
||||
private long createCount;
|
||||
private long alterCount;
|
||||
private long dropCount;
|
||||
private long replaceCount;
|
||||
private long deleteDataCount;
|
||||
private long updateDataCount;
|
||||
private long insertDataCount;
|
||||
private long fetchRowCount;
|
||||
|
||||
public WallTableStatValue(){
|
||||
this(null);
|
||||
}
|
||||
|
||||
public WallTableStatValue(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getSelectCount() {
|
||||
return selectCount;
|
||||
}
|
||||
|
||||
public void setSelectCount(long selectCount) {
|
||||
this.selectCount = selectCount;
|
||||
}
|
||||
|
||||
public long getSelectIntoCount() {
|
||||
return selectIntoCount;
|
||||
}
|
||||
|
||||
public void setSelectIntoCount(long selectIntoCount) {
|
||||
this.selectIntoCount = selectIntoCount;
|
||||
}
|
||||
|
||||
public long getInsertCount() {
|
||||
return insertCount;
|
||||
}
|
||||
|
||||
public void setInsertCount(long insertCount) {
|
||||
this.insertCount = insertCount;
|
||||
}
|
||||
|
||||
public long getUpdateCount() {
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
public void setUpdateCount(long updateCount) {
|
||||
this.updateCount = updateCount;
|
||||
}
|
||||
|
||||
public long getDeleteCount() {
|
||||
return deleteCount;
|
||||
}
|
||||
|
||||
public void setDeleteCount(long deleteCount) {
|
||||
this.deleteCount = deleteCount;
|
||||
}
|
||||
|
||||
public long getTruncateCount() {
|
||||
return truncateCount;
|
||||
}
|
||||
|
||||
public void setTruncateCount(long truncateCount) {
|
||||
this.truncateCount = truncateCount;
|
||||
}
|
||||
|
||||
public long getCreateCount() {
|
||||
return createCount;
|
||||
}
|
||||
|
||||
public void setCreateCount(long createCount) {
|
||||
this.createCount = createCount;
|
||||
}
|
||||
|
||||
public long getAlterCount() {
|
||||
return alterCount;
|
||||
}
|
||||
|
||||
public void setAlterCount(long alterCount) {
|
||||
this.alterCount = alterCount;
|
||||
}
|
||||
|
||||
public long getDropCount() {
|
||||
return dropCount;
|
||||
}
|
||||
|
||||
public void setDropCount(long dropCount) {
|
||||
this.dropCount = dropCount;
|
||||
}
|
||||
|
||||
public long getReplaceCount() {
|
||||
return replaceCount;
|
||||
}
|
||||
|
||||
public void setReplaceCount(long replaceCount) {
|
||||
this.replaceCount = replaceCount;
|
||||
}
|
||||
|
||||
public long getDeleteDataCount() {
|
||||
return deleteDataCount;
|
||||
}
|
||||
|
||||
public void setDeleteDataCount(long deleteDataCount) {
|
||||
this.deleteDataCount = deleteDataCount;
|
||||
}
|
||||
|
||||
public long getUpdateDataCount() {
|
||||
return updateDataCount;
|
||||
}
|
||||
|
||||
public void setUpdateDataCount(long updateDataCount) {
|
||||
this.updateDataCount = updateDataCount;
|
||||
}
|
||||
|
||||
public long getInsertDataCount() {
|
||||
return insertDataCount;
|
||||
}
|
||||
|
||||
public void setInsertDataCount(long insertDataCount) {
|
||||
this.insertDataCount = insertDataCount;
|
||||
}
|
||||
|
||||
public long getFetchRowCount() {
|
||||
return fetchRowCount;
|
||||
}
|
||||
|
||||
public void setFetchRowCount(long fetchRowCount) {
|
||||
this.fetchRowCount = fetchRowCount;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
toMap(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap(Map<String, Object> map) {
|
||||
if (selectCount > 0) {
|
||||
map.put("selectCount", selectCount);
|
||||
}
|
||||
if (deleteCount > 0) {
|
||||
map.put("deleteCount", deleteCount);
|
||||
}
|
||||
if (insertCount > 0) {
|
||||
map.put("insertCount", insertCount);
|
||||
}
|
||||
if (updateCount > 0) {
|
||||
map.put("updateCount", updateCount);
|
||||
}
|
||||
if (alterCount > 0) {
|
||||
map.put("alterCount", alterCount);
|
||||
}
|
||||
if (dropCount > 0) {
|
||||
map.put("dropCount", dropCount);
|
||||
}
|
||||
if (createCount > 0) {
|
||||
map.put("createCount", createCount);
|
||||
}
|
||||
if (truncateCount > 0) {
|
||||
map.put("truncateCount", truncateCount);
|
||||
}
|
||||
if (replaceCount > 0) {
|
||||
map.put("replaceCount", replaceCount);
|
||||
}
|
||||
if (deleteDataCount > 0) {
|
||||
map.put("deleteDataCount", deleteDataCount);
|
||||
}
|
||||
if (fetchRowCount > 0) {
|
||||
map.put("fetchRowCount", fetchRowCount);
|
||||
}
|
||||
if (updateDataCount > 0) {
|
||||
map.put("updateDataCount", updateDataCount);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.wall.spi;
|
||||
|
||||
public interface WallStatLogger {
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.alibaba.druid.bvt.filter.wall;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -24,25 +23,26 @@ public class WallStatTest_statMap extends TestCase {
|
||||
WallContext.clearContext();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMySql() throws Exception {
|
||||
WallProvider providerA = new MySqlWallProvider();
|
||||
|
||||
{
|
||||
String sql = "select * from t where len(fname) = 1 OR 1 = 1";
|
||||
String sql = "select * from t where len(fname1) = 1 OR 1 = 1";
|
||||
Assert.assertFalse(providerA.checkValid(sql));
|
||||
providerA.addViolationEffectRowCount(10);
|
||||
}
|
||||
|
||||
WallProvider providerB = new MySqlWallProvider();
|
||||
{
|
||||
String sql = "select * from t where len(fname) = 2 OR 1 = 1";
|
||||
String sql = "select * from t where len(fname2) = 2 OR 1 = 1";
|
||||
Assert.assertFalse(providerB.checkValid(sql));
|
||||
providerB.addViolationEffectRowCount(11);
|
||||
}
|
||||
|
||||
WallProvider providerC = new MySqlWallProvider();
|
||||
{
|
||||
String sql = "select * from t where len(fname) = 2 OR 1 = 1";
|
||||
String sql = "select * from t where len(fname2) = 2 OR 1 = 1";
|
||||
Assert.assertFalse(providerC.checkValid(sql));
|
||||
providerC.addViolationEffectRowCount(12);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user