use of com.googlecode.aviator.Expression in project jcasbin by casbin.
the class CoreEnforcer method enforce.
/**
* enforce use a custom matcher to decide whether a "subject" can access a "object" with the operation "action",
* input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "" or null.
*
* @param matcher the custom matcher.
* @param rvals the request needs to be mediated, usually an array
* of strings, can be class instances if ABAC is used.
* @return whether to allow the request.
*/
private boolean enforce(String matcher, Object... rvals) {
if (!enabled) {
return true;
}
boolean compileCached = true;
if (fm.isModify) {
compileCached = false;
initBuiltInFunction();
fm.isModify = false;
}
Map<String, AviatorFunction> gFunctions = new HashMap<>();
if (model.model.containsKey("g")) {
for (Map.Entry<String, Assertion> entry : model.model.get("g").entrySet()) {
String key = entry.getKey();
Assertion ast = entry.getValue();
RoleManager rm = ast.rm;
AviatorFunction aviatorFunction = BuiltInFunctions.GenerateGFunctionClass.generateGFunction(key, rm);
gFunctions.put(key, aviatorFunction);
}
}
for (AviatorFunction f : gFunctions.values()) {
if (!aviatorEval.containsFunction(f.getName())) {
aviatorEval.addFunction(f);
compileCached = false;
}
}
fm.setAviatorEval(aviatorEval);
String rType = "r", pType = "p", eType = "e", mType = "m";
if (rvals.length != 0) {
if (rvals[0] instanceof EnforceContext) {
EnforceContext enforceContext = (EnforceContext) rvals[0];
rType = enforceContext.getrType();
pType = enforceContext.getpType();
eType = enforceContext.geteType();
mType = enforceContext.getmType();
rvals = Arrays.copyOfRange(rvals, 1, rvals.length);
}
}
String expString;
if (matcher == null || "".equals(matcher)) {
expString = model.model.get("m").get(mType).value;
} else {
expString = Util.removeComments(Util.escapeAssertion(matcher));
}
expString = Util.convertInSyntax(expString);
// Use md5 encryption as cacheKey to prevent expString from being too long
Expression expression = aviatorEval.compile(Util.md5(expString), expString, compileCached);
StreamEffector streamEffector = null;
try {
streamEffector = this.eft.newStreamEffector(model.model.get("e").get(eType).value);
} catch (Exception e) {
if (!(e instanceof UnsupportedOperationException)) {
throw new CasbinEffectorException(e);
}
}
Effect[] policyEffects;
float[] matcherResults;
int policyLen;
if ((policyLen = model.model.get("p").get(pType).policy.size()) != 0) {
policyEffects = new Effect[policyLen];
matcherResults = new float[policyLen];
for (int i = 0; i < model.model.get("p").get(pType).policy.size(); i++) {
List<String> pvals = model.model.get("p").get(pType).policy.get(i);
// Util.logPrint("Policy Rule: " + pvals);
// Select the rule based on request size
Map<String, Object> parameters = new HashMap<>();
getRTokens(parameters, rvals);
for (int j = 0; j < model.model.get("p").get(pType).tokens.length; j++) {
String token = model.model.get("p").get(pType).tokens[j];
parameters.put(token, pvals.get(j));
}
Object result = expression.execute(parameters);
if (result instanceof Boolean) {
if (!((boolean) result)) {
policyEffects[i] = Effect.Indeterminate;
} else {
policyEffects[i] = Effect.Allow;
}
if (streamEffector == null) {
continue;
}
} else if (result instanceof Float) {
if ((float) result == 0) {
policyEffects[i] = Effect.Indeterminate;
} else {
matcherResults[i] = (float) result;
policyEffects[i] = Effect.Allow;
}
if (streamEffector == null) {
continue;
}
} else {
throw new CasbinMatcherException("matcher result should be bool, int or float");
}
if (policyEffects[i] == Effect.Allow && parameters.containsKey(pType + "_eft")) {
String eft = (String) parameters.get(pType + "_eft");
if ("allow".equals(eft)) {
policyEffects[i] = Effect.Allow;
} else if ("deny".equals(eft)) {
policyEffects[i] = Effect.Deny;
} else {
policyEffects[i] = Effect.Indeterminate;
}
}
if (streamEffector != null) {
boolean done = streamEffector.push(policyEffects[i], i, policyLen);
if (done) {
break;
}
} else {
if ("priority(p_eft) || deny".equals(model.model.get("e").get(eType).value)) {
break;
}
}
}
} else {
policyEffects = new Effect[1];
matcherResults = new float[1];
Map<String, Object> parameters = new HashMap<>();
for (int j = 0; j < model.model.get("r").get(rType).tokens.length; j++) {
String token = model.model.get("r").get(rType).tokens[j];
parameters.put(token, rvals[j]);
}
for (int j = 0; j < model.model.get("p").get(pType).tokens.length; j++) {
String token = model.model.get("p").get(pType).tokens[j];
parameters.put(token, "");
}
Object result = expression.execute(parameters);
if (streamEffector != null) {
if ((boolean) result) {
streamEffector.push(Effect.Allow, 0, 1);
} else {
streamEffector.push(Effect.Indeterminate, 0, 1);
}
} else {
if ((boolean) result) {
policyEffects[0] = Effect.Allow;
} else {
policyEffects[0] = Effect.Indeterminate;
}
}
}
boolean result;
if (streamEffector != null && streamEffector.current() != null) {
result = streamEffector.current().hasEffect();
} else {
result = eft.mergeEffects(model.model.get("e").get(eType).value, policyEffects, matcherResults);
}
StringBuilder reqStr = new StringBuilder("Request: ");
for (int i = 0; i < rvals.length; i++) {
String rval = rvals[i].toString();
if (i != rvals.length - 1) {
reqStr.append(String.format("%s, ", rval));
} else {
reqStr.append(String.format("%s", rval));
}
}
reqStr.append(String.format(" ---> %s", result));
Util.logPrint(reqStr.toString());
return result;
}
use of com.googlecode.aviator.Expression in project hertzbeat by dromara.
the class CalculateAlarm method calculate.
private void calculate(CollectRep.MetricsData metricsData) {
long currentTimeMilli = System.currentTimeMillis();
long monitorId = metricsData.getId();
String app = metricsData.getApp();
String metrics = metricsData.getMetrics();
// 先判断调度优先级为0的指标组采集响应数据状态 UN_REACHABLE/UN_CONNECTABLE 则需发最高级别告警进行监控状态变更
if (metricsData.getPriority() == 0) {
if (metricsData.getCode() != CollectRep.Code.SUCCESS) {
// 采集异常
if (metricsData.getCode() == CollectRep.Code.UN_AVAILABLE) {
// todo 采集器不可用
} else if (metricsData.getCode() == CollectRep.Code.UN_REACHABLE) {
// UN_REACHABLE 对端不可达(网络层icmp)
handlerMonitorStatusAlert(String.valueOf(monitorId), app, metricsData.getCode());
} else if (metricsData.getCode() == CollectRep.Code.UN_CONNECTABLE) {
// UN_CONNECTABLE 对端连接失败(传输层tcp,udp)
handlerMonitorStatusAlert(String.valueOf(monitorId), app, metricsData.getCode());
} else {
// 其他异常
handlerMonitorStatusAlert(String.valueOf(monitorId), app, metricsData.getCode());
}
return;
} else {
// 判断关联监控之前是否有可用性或者不可达告警,发送恢复告警进行监控状态恢复
Alert preAlert = triggeredAlertMap.remove(String.valueOf(monitorId));
if (preAlert != null && preAlert.getStatus() == CommonConstants.ALERT_STATUS_CODE_PENDING) {
// 发送告警恢复
Map<String, String> tags = new HashMap<>(6);
tags.put(CommonConstants.TAG_MONITOR_ID, String.valueOf(monitorId));
tags.put(CommonConstants.TAG_MONITOR_APP, app);
String target = CommonConstants.AVAILABLE;
String content = this.bundle.getString("alerter.availability.resolved");
if (CommonConstants.REACHABLE.equals(preAlert.getTarget())) {
target = CommonConstants.REACHABLE;
content = this.bundle.getString("alerter.reachability.resolved");
}
Alert resumeAlert = Alert.builder().tags(tags).target(target).content(content).priority(CommonConstants.ALERT_PRIORITY_CODE_WARNING).status(CommonConstants.ALERT_STATUS_CODE_RESTORED).firstTriggerTime(currentTimeMilli).lastTriggerTime(currentTimeMilli).times(1).build();
dataQueue.addAlertData(resumeAlert);
}
}
}
// 查出此监控类型下的此指标集合下关联配置的告警定义信息
// field - define[]
Map<String, List<AlertDefine>> defineMap = alertDefineService.getMonitorBindAlertDefines(monitorId, app, metrics);
if (defineMap == null || defineMap.isEmpty()) {
return;
}
List<CollectRep.Field> fields = metricsData.getFieldsList();
Map<String, Object> fieldValueMap = new HashMap<>(16);
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
if (!valueRow.getColumnsList().isEmpty()) {
fieldValueMap.clear();
String instance = valueRow.getInstance();
if (!"".equals(instance)) {
fieldValueMap.put("instance", instance);
}
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
String valueStr = valueRow.getColumns(index);
CollectRep.Field field = fields.get(index);
if (field.getType() == CommonConstants.TYPE_NUMBER) {
Double doubleValue = CommonUtil.parseDoubleStr(valueStr);
if (doubleValue != null) {
fieldValueMap.put(field.getName(), doubleValue);
}
} else {
if (!"".equals(valueStr)) {
fieldValueMap.put(field.getName(), valueStr);
}
}
}
for (Map.Entry<String, List<AlertDefine>> entry : defineMap.entrySet()) {
List<AlertDefine> defines = entry.getValue();
for (AlertDefine define : defines) {
String expr = define.getExpr();
try {
Expression expression = AviatorEvaluator.compile(expr, true);
Boolean match = (Boolean) expression.execute(fieldValueMap);
if (match) {
// 阈值规则匹配,判断已触发阈值次数,触发告警
String monitorAlertKey = String.valueOf(monitorId) + define.getId();
Alert triggeredAlert = triggeredAlertMap.get(monitorAlertKey);
if (triggeredAlert != null) {
int times = triggeredAlert.getTimes() + 1;
triggeredAlert.setTimes(times);
triggeredAlert.setLastTriggerTime(currentTimeMilli);
int defineTimes = define.getTimes() == null ? 0 : define.getTimes();
if (times >= defineTimes) {
triggeredAlertMap.remove(monitorAlertKey);
dataQueue.addAlertData(triggeredAlert);
}
} else {
int times = 1;
fieldValueMap.put("app", app);
fieldValueMap.put("metrics", metrics);
fieldValueMap.put("metric", define.getField());
Map<String, String> tags = new HashMap<>(6);
tags.put(CommonConstants.TAG_MONITOR_ID, String.valueOf(monitorId));
tags.put(CommonConstants.TAG_MONITOR_APP, app);
Alert alert = Alert.builder().tags(tags).alertDefineId(define.getId()).priority(define.getPriority()).status(CommonConstants.ALERT_STATUS_CODE_PENDING).target(app + "." + metrics + "." + define.getField()).times(times).firstTriggerTime(currentTimeMilli).lastTriggerTime(currentTimeMilli).content(AlertTemplateUtil.render(define.getTemplate(), fieldValueMap)).build();
int defineTimes = define.getTimes() == null ? 0 : define.getTimes();
if (times >= defineTimes) {
dataQueue.addAlertData(alert);
} else {
triggeredAlertMap.put(monitorAlertKey, alert);
}
}
// 此优先级以下的阈值规则则忽略
break;
}
} catch (Exception e) {
log.warn(e.getMessage());
}
}
}
}
}
}
use of com.googlecode.aviator.Expression in project hertzbeat by dromara.
the class MetricsCollect method calculateFields.
/**
* Calculate the real indicator (fields) value according to the calculates and aliasFields configuration
* Calculate instance instance value
* <p>
* 根据 calculates 和 aliasFields 配置计算出真正的指标(fields)值
* 计算instance实例值
*
* @param metrics Metric group configuration 指标组配置
* @param collectData Data collection 采集数据
*/
private void calculateFields(Metrics metrics, CollectRep.MetricsData.Builder collectData) {
collectData.setPriority(metrics.getPriority());
List<CollectRep.Field> fieldList = new LinkedList<>();
for (Metrics.Field field : metrics.getFields()) {
fieldList.add(CollectRep.Field.newBuilder().setName(field.getField()).setType(field.getType()).build());
}
collectData.addAllFields(fieldList);
List<CollectRep.ValueRow> aliasRowList = collectData.getValuesList();
if (aliasRowList == null || aliasRowList.isEmpty()) {
return;
}
collectData.clearValues();
// Preprocess calculates first 先预处理 calculates
if (metrics.getCalculates() == null) {
metrics.setCalculates(Collections.emptyList());
}
// eg: database_pages=Database pages unconventional mapping 非常规映射
Map<String, String> fieldAliasMap = new HashMap<>(8);
Map<String, Expression> fieldExpressionMap = metrics.getCalculates().stream().map(cal -> {
int splitIndex = cal.indexOf("=");
String field = cal.substring(0, splitIndex).trim();
String expressionStr = cal.substring(splitIndex + 1).trim();
Expression expression = null;
try {
expression = AviatorEvaluator.compile(expressionStr, true);
} catch (Exception e) {
fieldAliasMap.put(field, expressionStr);
return null;
}
return new Object[] { field, expression };
}).filter(Objects::nonNull).collect(Collectors.toMap(arr -> (String) arr[0], arr -> (Expression) arr[1]));
List<Metrics.Field> fields = metrics.getFields();
List<String> aliasFields = metrics.getAliasFields();
Map<String, String> aliasFieldValueMap = new HashMap<>(16);
Map<String, Object> fieldValueMap = new HashMap<>(16);
CollectRep.ValueRow.Builder realValueRowBuilder = CollectRep.ValueRow.newBuilder();
for (CollectRep.ValueRow aliasRow : aliasRowList) {
for (int aliasIndex = 0; aliasIndex < aliasFields.size(); aliasIndex++) {
String aliasFieldValue = aliasRow.getColumns(aliasIndex);
if (!CommonConstants.NULL_VALUE.equals(aliasFieldValue)) {
aliasFieldValueMap.put(aliasFields.get(aliasIndex), aliasFieldValue);
}
}
StringBuilder instanceBuilder = new StringBuilder();
for (Metrics.Field field : fields) {
String realField = field.getField();
Expression expression = fieldExpressionMap.get(realField);
String value = null;
if (expression != null) {
// 存在计算表达式 则计算值
if (CommonConstants.TYPE_NUMBER == field.getType()) {
for (String variable : expression.getVariableNames()) {
Double doubleValue = CommonUtil.parseDoubleStr(aliasFieldValueMap.get(variable));
if (doubleValue != null) {
fieldValueMap.put(variable, doubleValue);
}
}
} else {
for (String variable : expression.getVariableNames()) {
String strValue = aliasFieldValueMap.get(variable);
if (strValue != null && !"".equals(strValue)) {
fieldValueMap.put(variable, strValue);
}
}
}
try {
Object objValue = expression.execute(fieldValueMap);
if (objValue != null) {
value = String.valueOf(objValue);
}
} catch (Exception e) {
log.warn(e.getMessage());
}
} else {
// does not exist then map the alias value
// 不存在 则映射别名值
String aliasField = fieldAliasMap.get(realField);
if (aliasField != null) {
value = aliasFieldValueMap.get(aliasField);
} else {
value = aliasFieldValueMap.get(realField);
}
}
// 处理可能带单位的指标数值 比如 34%, 34Mb,并将数值小数点限制到4位
if (CommonConstants.TYPE_NUMBER == field.getType()) {
value = CommonUtil.parseDoubleStr(value, field.getUnit());
}
if (value == null) {
value = CommonConstants.NULL_VALUE;
}
realValueRowBuilder.addColumns(value);
fieldValueMap.clear();
if (field.isInstance() && !CommonConstants.NULL_VALUE.equals(value)) {
instanceBuilder.append(value);
}
}
aliasFieldValueMap.clear();
// set instance 设置实例instance
realValueRowBuilder.setInstance(instanceBuilder.toString());
collectData.addValues(realValueRowBuilder.build());
realValueRowBuilder.clear();
}
}
use of com.googlecode.aviator.Expression in project MyJavaProject by ykdsg.
the class TestExpress method testAviator.
@Test
public void testAviator() {
long start = new Date().getTime();
Map<String, Object> env = new HashMap<String, Object>();
// 编译表达式
Expression compiledExp = AviatorEvaluator.compile(expression);
for (int i = 0; i < TIMES; i++) {
AviatorEvaluator.exec(expression, name1);
// env.put(YOUR_NAME, name1);
// compiledExp.execute(env);
// System.out.println(i+"name1="+compiledExp.execute(env));
AviatorEvaluator.exec(expression, name2);
// env.put(YOUR_NAME, name2);
// compiledExp.execute(env);
// System.out.println(i + "name2=" + compiledExp.execute(env));
AviatorEvaluator.exec(expression, name3);
// env.put(YOUR_NAME, name3);
// compiledExp.execute(env);
// System.out.println(i + "name3=" + compiledExp.execute(env));
}
System.out.println("aviator cost=" + (new Date().getTime() - start));
}
use of com.googlecode.aviator.Expression in project code-study by chenyaoBOY.
the class App method main.
public static void main(String[] args) throws InterruptedException {
Thread.sleep(10_000);
Map<String, Object> map = new HashMap<>();
map.put("key1", new Object());
map.put("key2", 1011);
map.put("key3", "String");
int count = 1000_000;
/**
* 不加缓存的情况下 会发生元空间FULL-GC
* 大量类被加载
*/
while (count > 0) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Expression expression = AviatorEvaluator.compile(entry.getKey(), false);
System.out.println(expression.execute(map));
}
count--;
Thread.sleep(5);
}
}
Aggregations