用Aviator判断风控规则
原创大约 4 分钟
Aviator自定义函数
在大多数系统中,都是通过Aviator自定义函数来实现关系表达式运算的。
Aviator有两种自定义函数。
AbstractFunction
:它实现的自定义函数,其call()
方法接受1 ~ 20
个参数。

AbstractVariadicFunction
:它的variadicCall()
方法的参数是可变的。
通过AbstractFunction
实现不可变参数Aviator自定义函数的代码。
package aviator;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorDouble;
import com.googlecode.aviator.runtime.type.AviatorObject;
import java.util.Map;
/**
* Aviator自定义函数(不可变参数)
* 1. 自定义函数
* 1). 继承AbstractFunction
* 2). 实现getName():定义函数名
* 3). 实现call():定义函数逻辑
* 4). 在AviatorEvaluator注册
* 2. 自定义函数的入参
* AbstractFunction可输入1~20个AviatorObject入参
* AbstractVariadicFunction提供可变数量的入参
*
*/
public class AviatorCustomFunction extends AbstractFunction {
/**
* 实现函数逻辑
*
*/
@Override
public AviatorObject call(Map<String, Object> map, AviatorObject arg1, AviatorObject arg2) {
Number num1 = FunctionUtils.getNumberValue(arg1, map);
Number num2 = FunctionUtils.getNumberValue(arg2, map);
return new AviatorDouble(num1.doubleValue() + num2.doubleValue());
}
/**
* 定义函数名
*
*/
@Override
public String getName() {
return "add";
}
}
通过AbstractVariadicFunction
实现可变参数Aviator自定义函数的代码。
/**
* Aviator自定义函数(可变参数)
*
*/
public class AviatorCustomFunctionArgs extends AbstractVariadicFunction {
@Override
public AviatorObject variadicCall(Map<String, Object> map, AviatorObject... args) {
double sum = 0d;
for (AviatorObject arg : args) {
Number a = FunctionUtils.getNumberValue(arg, map);
sum += a.doubleValue();
}
return new AviatorDouble(sum);
}
@Override
public String getName() {
return "customArgs";
}
}
调用Aviator的自定义函数。
package aviator;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import java.util.HashMap;
import java.util.Map;
/**
* 调用Aviator的自定义函数
*
*/
public class AviatorMain {
public static void main(String[] args) {
// 自定义函数的调用
AviatorEvaluator.addFunction(new AviatorCustomFunction());
String exp6 = "add(a, b)";
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("a", 1d);
map1.put("b", 2d);
// compile()可以缓存字符串表达式
// compile的用法步骤:生成Expression对象,然后执行Expression对象的execute()传入变量值
Expression compileExp = AviatorEvaluator.compile(exp6, true);
System.out.println(compileExp.execute(map1));
// 自定义函数的调用 (可变参数)
AviatorEvaluator.addFunction(new AviatorCustomFunctionArgs());
String exp7 = "customArgs(a, b, c)";
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("a", 1d);
map2.put("b", 2d);
map2.put("c", 3d);
Expression compileExp7 = AviatorEvaluator.compile(exp7, true);
System.out.println(compileExp7.execute(map2));
}
}
封装工具类
package com.itechthink.risk.flink.utils;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import java.util.Map;
/**
* 应用于规则条件判断的Aviator工具类
*
*/
public class AviatorUtil {
/**
* 方法重载,解析字符串表达式
*
*/
public static Object execute(String str) {
// 执行AviatorEvaluator对象的execute(),获取表达式运算结果
return AviatorEvaluator.execute(str);
}
/**
* 方法重载,解析字符串表达式
*
*/
public static Object execute(String str, Map<String, Object> map) {
// 将字符串表达式解析为Expression对象
Expression compileExp = AviatorEvaluator.compile(str, true);
// 执行Expression对象的execute(),获取表达式运算结果
return compileExp.execute(map);
}
/**
* 方法重载,解析字符串表达式
*
*/
public static Object execute(String str, AbstractFunction func) {
// 注册自定义函数
AviatorEvaluator.addFunction(func);
// 将字符串表达式解析为Expression对象
Expression compileExp = AviatorEvaluator.compile(str, true);
// 执行Expression对象的execute(),获取表达式运算结果
return compileExp.execute();
}
}
应用于规则判断
package com.itechthink.risk.flink.job.process;
import com.itechthink.risk.commons.constants.ConstantsUtil;
import com.itechthink.risk.flink.job.aviator.MetricRedisFunction;
import com.itechthink.risk.flink.utils.AviatorUtil;
import com.itechthink.risk.model.ActionPO;
import com.itechthink.risk.model.EventPO;
import com.itechthink.risk.model.RiskInfoPO;
import com.itechthink.risk.model.SingleRulePO;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;
/**
* 规则判断:输出规则命中后的动作
*
*/
public class WarningKeyedProcessFunction extends KeyedProcessFunction<Integer, EventPO, ActionPO> {
@Override
public void processElement(EventPO eventPO, KeyedProcessFunction<Integer, EventPO, ActionPO>.Context context, Collector<ActionPO> collector) throws Exception {
SingleRulePO rule = eventPO.getSingleRule();
String is_enable = rule.getEnabled();
// 判断规则是否启用
if (is_enable.equals("true")) {
// 取出规则的表达式 (包含了指标,关系运算符,阈值)
String expression = rule.getExpression();
// 将表达式按|分割成数组 格式:函数|运算符和阈值 (限定单一条件)
String[] arg = expression.split("\\|");
/*
* 使用aviator对表达式进行解析
*
*/
// 反射得到Aviator自定义函数实例
Class<?> clazz = Class.forName(ConstantsUtil.PATH_CLASS_METRIC_REDIS_FUNCTION);
MetricRedisFunction metricRedisFunction = (MetricRedisFunction) clazz.newInstance();
// 组装得到Aviator自定义函数实例
String funcName = arg[0] + arg[1];
// 执行自定义函数表达式,获取指标值
Object metric = AviatorUtil.execute(funcName, metricRedisFunction);
String metric_value = metric.toString();
// 指标值和关系运算符,阈值组装得到条件关系表达式
String exp = metric_value + arg[2];
// Aviator解析这个关系表达式,返回true或false
boolean b = (boolean) AviatorUtil.execute(exp);
// 规则命中,输出策略动作
if (b) {
RiskInfoPO info = new RiskInfoPO();
info.setUserid(eventPO.getUserid());
ActionPO action = new ActionPO();
action.setAction(rule.getAction());
action.setInfo(info);
// 输出策略动作
collector.collect(action);
}
}
}
}
感谢支持
更多内容,请移步《超级个体》。