Skip to content

Commit

Permalink
MOD: mod some code
Browse files Browse the repository at this point in the history
  • Loading branch information
stalary committed Aug 8, 2021
1 parent 211ac3b commit 80ce658
Show file tree
Hide file tree
Showing 19 changed files with 214 additions and 93 deletions.
2 changes: 1 addition & 1 deletion docs/en/administrator-guide/block-rule/sql-block.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ DROP SQL_BLOCK_RULE test_rule1,test_rule2
## User bind rules
If global=false is configured, the rules binding for the specified user needs to be configured, with multiple rules separated by ', '
```
SET PROPERTY FOR 'jack' 'bind_sql_block_rules' = 'test_rule1,test_rule2'
SET PROPERTY FOR 'jack' 'sql_block_rules' = 'test_rule1,test_rule2'
```
2 changes: 1 addition & 1 deletion docs/zh-CN/administrator-guide/block-rule/sql-block.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ DROP SQL_BLOCK_RULE test_rule1,test_rule2
## 用户规则绑定
如果配置global=false,则需要配置指定用户的规则绑定,多个规则使用`,`分隔
```
SET PROPERTY FOR 'jack' 'bind_sql_block_rules' = 'test_rule1,test_rule2'
SET PROPERTY FOR 'jack' 'sql_block_rules' = 'test_rule1,test_rule2'
```
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

Expand Down Expand Up @@ -88,4 +89,16 @@ public Boolean getEnable() {
public String getSqlHash() {
return sqlHash;
}

@Override
public String toSql() {
// ALTER SQL_BLOCK_RULE test_rule PROPERTIES("sql"="select \\* from test_table","enable"="true")
StringBuilder sb = new StringBuilder();
sb.append("ALTER SQL_BLOCK_RULE ")
.append(ruleName)
.append(" \nPROPERTIES(\n")
.append(new PrintableMap<>(properties, " = ", true, true, true))
.append(")");
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.common.util.Util;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

import com.google.common.collect.ImmutableSet;

import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Optional;

Expand Down Expand Up @@ -59,10 +62,10 @@ public class CreateSqlBlockRuleStmt extends DdlStmt {

private String sqlHash;

// whether effective global
// whether effective global, default is false
private boolean global;

// whether to use the rule
// whether to use the rule, default is true
private boolean enable;

private final Map<String, String> properties;
Expand Down Expand Up @@ -97,6 +100,10 @@ public void analyze(Analyzer analyzer) throws UserException {
private void setProperties(Map<String, String> properties) throws UserException {
this.sql = properties.get(SQL_PROPERTY);
this.sqlHash = properties.get(SQL_HASH_PROPERTY);
if ((StringUtils.isNotEmpty(sql) && StringUtils.isNotEmpty(sqlHash)) || (StringUtils.isEmpty(sql) && StringUtils.isEmpty(sqlHash))) {
throw new AnalysisException("Only one sql or sqlHash can be configured");
}

this.global = Util.getBooleanPropertyOrDefault(properties.get(GLOBAL_PROPERTY), false, GLOBAL_PROPERTY + " should be a boolean");
this.enable = Util.getBooleanPropertyOrDefault(properties.get(ENABLE_PROPERTY), true, ENABLE_PROPERTY + " should be a boolean");
}
Expand Down Expand Up @@ -131,4 +138,15 @@ public boolean isGlobal() {
public boolean isEnable() {
return enable;
}

@Override
public String toSql() {
StringBuilder sb = new StringBuilder();
sb.append("CREATE SQL_BLOCK_RULE ")
.append(ruleName)
.append(" \nPROPERTIES(\n")
.append(new PrintableMap<>(properties, " = ", true, true, true))
.append(")");
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

import org.apache.parquet.Strings;

import java.util.List;

public class DropSqlBlockRuleStmt extends DdlStmt {
Expand All @@ -46,4 +48,11 @@ public DropSqlBlockRuleStmt(List<String> ruleNames) {
public List<String> getRuleNames() {
return ruleNames;
}

@Override
public String toSql() {
StringBuilder sb = new StringBuilder();
sb.append("DROP SQL_BLOCK_RULE ").append(Strings.join(ruleNames, ","));
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@

package org.apache.doris.analysis;

import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.ShowResultSetMetaData;

import org.apache.commons.lang3.StringUtils;

/*
Create sqlBlockRule statement
Expand Down Expand Up @@ -48,8 +56,27 @@ public String getRuleName() {
return ruleName;
}

@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
// check auth
if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN");
}
}

@Override
public ShowResultSetMetaData getMetaData() {
return META_DATA;
}

@Override
public String toSql() {
StringBuilder sb = new StringBuilder();
sb.append("SHOW SQL_BLOCK_RULE");
if (StringUtils.isNotEmpty(ruleName)) {
sb.append(" FOR ").append(ruleName);
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.doris.persist.gson.GsonUtils;

import com.google.common.collect.Lists;
import com.google.gson.annotations.SerializedName;

import java.io.DataInput;
import java.io.DataOutput;
Expand All @@ -37,17 +38,22 @@ public class SqlBlockRule implements Writable {
public static final String DEFAULT_USER = "default";

// the rule name, cluster unique
@SerializedName(value = "name")
private String name;

@SerializedName(value = "sql")
private String sql;

// sql md5
@SerializedName(value = "sqlHash")
private String sqlHash;

// whether effective global
@SerializedName(value = "global")
private Boolean global;

// whether to use the rule
@SerializedName(value = "enable")
private Boolean enable;

public SqlBlockRule(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@
import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.common.io.Text;
import org.apache.doris.common.io.Writable;
import org.apache.doris.metric.MetricRepo;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.persist.gson.GsonUtils;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.annotations.SerializedName;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -55,8 +53,10 @@ public class SqlBlockRuleMgr implements Writable {

private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

@SerializedName(value = "nameToSqlBlockRuleMap")
private Map<String, SqlBlockRule> nameToSqlBlockRuleMap = Maps.newConcurrentMap();

@SerializedName(value = "sqlPatternMap")
private Map<String, Pattern> sqlPatternMap = Maps.newConcurrentMap();

private void writeLock() {
Expand All @@ -71,11 +71,8 @@ public boolean existRule(String name) {
return nameToSqlBlockRuleMap.containsKey(name);
}

public List<SqlBlockRule> get(ShowSqlBlockRuleStmt stmt) throws AnalysisException {
public List<SqlBlockRule> getSqlBlockRule(ShowSqlBlockRuleStmt stmt) throws AnalysisException {
String ruleName = stmt.getRuleName();
if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN");
}
if (StringUtils.isNotEmpty(ruleName)) {
if (nameToSqlBlockRuleMap.containsKey(ruleName)) {
SqlBlockRule sqlBlockRule = nameToSqlBlockRuleMap.get(ruleName);
Expand Down Expand Up @@ -159,75 +156,66 @@ public void dropSqlBlockRule(DropSqlBlockRuleStmt stmt) throws DdlException {
if (!existRule(ruleName)) {
throw new DdlException("the sql block rule " + ruleName + " not exist");
}
SqlBlockRule sqlBlockRule = nameToSqlBlockRuleMap.get(ruleName);
if (sqlBlockRule == null) {
continue;
}
unprotectedDrop(sqlBlockRule);
Catalog.getCurrentCatalog().getEditLog().logDropSqlBlockRule(sqlBlockRule);
}
unprotectedDrop(ruleNames);
Catalog.getCurrentCatalog().getEditLog().logDropSqlBlockRule(ruleNames);
} finally {
writeUnlock();
}
}

public void replayDrop(SqlBlockRule sqlBlockRule) {
unprotectedDrop(sqlBlockRule);
LOG.info("replay drop sql block rule: {}", sqlBlockRule);
public void replayDrop(List<String> ruleNames) {
unprotectedDrop(ruleNames);
LOG.info("replay drop sql block ruleNames: {}", ruleNames);
}

public void unprotectedDrop(SqlBlockRule sqlBlockRule) {
nameToSqlBlockRuleMap.remove(sqlBlockRule.getName());
// todo: remove UserProperty
public void unprotectedDrop(List<String> ruleNames) {
ruleNames.forEach(name -> nameToSqlBlockRuleMap.remove(name));
}

public void matchSql(String sql, String user) throws AnalysisException {
public void matchSql(String sql, String sqlHash, String user) throws AnalysisException {
// match global rule
List<SqlBlockRule> globalRules = nameToSqlBlockRuleMap.values().stream().filter(SqlBlockRule::getGlobal).collect(Collectors.toList());
for (SqlBlockRule rule : globalRules) {
Pattern sqlPattern = sqlPatternMap.get(rule.getSql());
matchSql(rule, sql, sqlPattern);
matchSql(rule, sql, sqlHash, sqlPattern);
}
// match user rule
String binSqlBlockRules = Catalog.getCurrentCatalog().getAuth().getBindSqlBlockRules(user);
if (StringUtils.isNotEmpty(binSqlBlockRules)) {
String[] split = binSqlBlockRules.split(",");
String bindSqlBlockRules = Catalog.getCurrentCatalog().getAuth().getSqlBlockRules(user);
if (StringUtils.isNotEmpty(bindSqlBlockRules)) {
String[] split = bindSqlBlockRules.split(",");
for (String ruleName : split) {
SqlBlockRule rule = nameToSqlBlockRuleMap.get(ruleName);
Pattern sqlPattern = sqlPatternMap.get(rule.getSql());
matchSql(rule, sql, sqlPattern);
matchSql(rule, sql, sqlHash, sqlPattern);
}
}
}

@VisibleForTesting
public static void matchSql(SqlBlockRule rule, String sql, Pattern sqlPattern) throws AnalysisException {
if (rule.getEnable() != null && rule.getEnable()) {
String sqlHash = rule.getSqlHash();
if (sqlHash != null && sqlHash.equals(DigestUtils.md5Hex(sql))) {
public static void matchSql(SqlBlockRule rule, String sql, String sqlHash, Pattern sqlPattern) throws AnalysisException {
if (rule.getEnable()) {
if (StringUtils.isNotEmpty(rule.getSql())) {
if (sqlPattern != null && sqlPattern.matcher(sql).find()) {
MetricRepo.COUNTER_HIT_SQL_BLOCK_RULE.increase(1L);
throw new AnalysisException("sql match regex sql block rule: " + rule.getName());
}
} else if (StringUtils.isNotEmpty(rule.getSqlHash()) && rule.getSqlHash().equals(sqlHash)) {
MetricRepo.COUNTER_HIT_SQL_BLOCK_RULE.increase(1L);
throw new AnalysisException("sql match hash sql block rule: " + rule.getName());
}
if (sqlPattern != null && sqlPattern.matcher(sql).find()) {
MetricRepo.COUNTER_HIT_SQL_BLOCK_RULE.increase(1L);
throw new AnalysisException("sql match regex sql block rule: " + rule.getName());
}
}
}

@Override
public void write(DataOutput out) throws IOException {
out.writeInt(nameToSqlBlockRuleMap.size());
for (SqlBlockRule sqlBlockRule : nameToSqlBlockRuleMap.values()) {
sqlBlockRule.write(out);
}
Text.writeString(out, GsonUtils.GSON.toJson(this));
}

public void readFields(DataInput in) throws IOException {
int size = in.readInt();
for (int i = 0; i < size; i++) {
SqlBlockRule read = SqlBlockRule.read(in);
unprotectedAdd(read);
}
String json = Text.readString(in);
SqlBlockRuleMgr mgr = GsonUtils.GSON.fromJson(json, SqlBlockRuleMgr.class);
this.nameToSqlBlockRuleMap = mgr.nameToSqlBlockRuleMap;
this.sqlPatternMap = mgr.sqlPatternMap;
}
}
11 changes: 1 addition & 10 deletions fe/fe-core/src/main/java/org/apache/doris/common/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -1450,16 +1450,7 @@ public class Config extends ConfigBase {
*/
@ConfField(mutable = false, masterOnly = true)
public static int partition_in_memory_update_interval_secs = 300;
<<<<<<< HEAD


@ConfField(masterOnly = true)
public static boolean enable_concurrent_update = false;
=======

/**
* Whether to enabel block sql
*/
@ConfField(mutable = true, masterOnly = false)
public static boolean enable_sql_block = false;
>>>>>>> 2f8cca53c (ADD: support sql block rule)
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.apache.doris.persist.DropLinkDbAndUpdateDbInfo;
import org.apache.doris.persist.DropPartitionInfo;
import org.apache.doris.persist.DropResourceOperationLog;
import org.apache.doris.persist.DropSqlBlockRuleOperationLog;
import org.apache.doris.persist.GlobalVarPersistInfo;
import org.apache.doris.persist.HbPackage;
import org.apache.doris.persist.ModifyPartitionInfo;
Expand Down Expand Up @@ -633,7 +634,7 @@ public void readFields(DataInput in) throws IOException {
break;
}
case OperationType.OP_DROP_SQL_BLOCK_RULE: {
data = SqlBlockRule.read(in);
data = DropSqlBlockRuleOperationLog.read(in);
isRead = true;
break;
}
Expand Down
Loading

0 comments on commit 80ce658

Please sign in to comment.