Orden
Este artículo estudia principalmente el CanalEventFilter de Canal
CanalEventFilter
canal-1.1.4 / filter / src / main / java / com / alibaba / otter / canal / filter / CanalEventFilter.java
public interface CanalEventFilter<T> {
boolean filter(T event) throws CanalFilterException;
}
复制代码
- La interfaz CanalEventFilter define el método de filtro
AviaterELFilter
canal-1.1.4 / filter / src / main / java / com / alibaba / otter / canal / filter / aviater / AviaterELFilter.java
public class AviaterELFilter implements CanalEventFilter<CanalEntry.Entry> {
public static final String ROOT_KEY = "entry";
private String expression;
public AviaterELFilter(String expression){
this.expression = expression;
}
public boolean filter(CanalEntry.Entry entry) throws CanalFilterException {
if (StringUtils.isEmpty(expression)) {
return true;
}
Map<String, Object> env = new HashMap<String, Object>();
env.put(ROOT_KEY, entry);
return (Boolean) AviatorEvaluator.execute(expression, env);
}
}
复制代码
- AviaterELFilter implementa la interfaz CanalEventFilter, su constructor recibe el parámetro de expresión y su método de filtro calcula el resultado a través de AviatorEvaluator.execute (expresión, env)
AviaterSimpleFilter
canal-1.1.4 / filter / src / main / java / com / alibaba / otter / canal / filter / aviater / AviaterSimpleFilter.java
public class AviaterSimpleFilter implements CanalEventFilter<String> {
private static final String SPLIT = ",";
private static final String FILTER_EXPRESSION = "include(list,target)";
private final Expression exp = AviatorEvaluator.compile(FILTER_EXPRESSION, true);
private final List<String> list;
public AviaterSimpleFilter(String filterExpression){
if (StringUtils.isEmpty(filterExpression)) {
list = new ArrayList<String>();
} else {
String[] ss = filterExpression.toLowerCase().split(SPLIT);
list = Arrays.asList(ss);
}
}
public boolean filter(String filtered) throws CanalFilterException {
if (list.isEmpty()) {
return true;
}
if (StringUtils.isEmpty(filtered)) {
return true;
}
Map<String, Object> env = new HashMap<String, Object>();
env.put("list", list);
env.put("target", filtered.toLowerCase());
return (Boolean) exp.execute(env);
}
}
复制代码
- AviaterSimpleFilter implementa la interfaz CanalEventFilter; define la propiedad Expression, su valor es AviatorEvaluator.compile (FILTER_EXPRESSION, true); su constructor recibe filterExpression; su método de filtro devuelve el resultado a través de exp.execute (env)
AviaterRegexFilter
canal-1.1.4 / filter / src / main / java / com / alibaba / otter / canal / filter / aviater / AviaterRegexFilter.java
public class AviaterRegexFilter implements CanalEventFilter<String> {
private static final String SPLIT = ",";
private static final String PATTERN_SPLIT = "|";
private static final String FILTER_EXPRESSION = "regex(pattern,target)";
private static final RegexFunction regexFunction = new RegexFunction();
private final Expression exp = AviatorEvaluator.compile(FILTER_EXPRESSION, true);
static {
AviatorEvaluator.addFunction(regexFunction);
}
private static final Comparator<String> COMPARATOR = new StringComparator();
final private String pattern;
final private boolean defaultEmptyValue;
public AviaterRegexFilter(String pattern){
this(pattern, true);
}
public AviaterRegexFilter(String pattern, boolean defaultEmptyValue){
this.defaultEmptyValue = defaultEmptyValue;
List<String> list = null;
if (StringUtils.isEmpty(pattern)) {
list = new ArrayList<String>();
} else {
String[] ss = StringUtils.split(pattern, SPLIT);
list = Arrays.asList(ss);
}
// 对pattern按照从长到短的排序
// 因为 foo|foot 匹配 foot 会出错,原因是 foot 匹配了 foo 之后,会返回 foo,但是 foo 的长度和 foot
// 的长度不一样
Collections.sort(list, COMPARATOR);
// 对pattern进行头尾完全匹配
list = completionPattern(list);
this.pattern = StringUtils.join(list, PATTERN_SPLIT);
}
public boolean filter(String filtered) throws CanalFilterException {
if (StringUtils.isEmpty(pattern)) {
return defaultEmptyValue;
}
if (StringUtils.isEmpty(filtered)) {
return defaultEmptyValue;
}
Map<String, Object> env = new HashMap<String, Object>();
env.put("pattern", pattern);
env.put("target", filtered.toLowerCase());
return (Boolean) exp.execute(env);
}
//......
@Override
public String toString() {
return pattern;
}
}
复制代码
- AviaterRegexFilter implementa la interfaz CanalEventFilter; define la propiedad Expression, su valor es AviatorEvaluator.compile (FILTER_EXPRESSION, true); su constructor recibe el parámetro de patrón, primero ordenará y modificará el patrón; su método de filtro es a través de exp.execute (env ) Resultado devuelto
Resumen
La interfaz CanalEventFilter define el método de filtro; sus tres clases de implementación son AviaterELFilter, AviaterSimpleFilter, AviaterRegexFilter