diff --git a/alerter/src/test/java/org/dromara/hertzbeat/alert/service/AlertDefineServiceTest.java b/alerter/src/test/java/org/dromara/hertzbeat/alert/service/AlertDefineServiceTest.java index d713675444d..83ffe0d63f9 100644 --- a/alerter/src/test/java/org/dromara/hertzbeat/alert/service/AlertDefineServiceTest.java +++ b/alerter/src/test/java/org/dromara/hertzbeat/alert/service/AlertDefineServiceTest.java @@ -110,7 +110,7 @@ void deleteAlertDefine() { @Test void getAlertDefine() { long id = 1L; - AlertDefine alertDefine = AlertDefine.builder().id(1L).build(); + AlertDefine alertDefine = AlertDefine.builder().id(id).build(); when(alertDefineDao.findById(id)).thenReturn(Optional.of(alertDefine)); assertDoesNotThrow(() -> alertDefineService.getAlertDefine(id)); } diff --git a/common/src/main/java/org/dromara/hertzbeat/common/config/AviatorConfiguration.java b/common/src/main/java/org/dromara/hertzbeat/common/config/AviatorConfiguration.java index b81423d784b..3a0985930df 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/config/AviatorConfiguration.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/config/AviatorConfiguration.java @@ -22,10 +22,12 @@ import com.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.type.*; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Map; +import java.util.regex.Pattern; /** * @author tomsun28 @@ -43,6 +45,8 @@ public void configAviatorEvaluator() { AviatorEvaluator.getInstance() .useLRUExpressionCache(AVIATOR_LRU_CACHE_SIZE) .addFunction(new StrEqualFunction()); + + // 配置自定义aviator函数 AviatorEvaluator.getInstance().addOpFunction(OperatorType.BIT_OR, new AbstractFunction() { @Override public AviatorObject call(final Map env, final AviatorObject arg1, @@ -66,6 +70,10 @@ public String getName() { return OperatorType.BIT_OR.getToken(); } }); + + AviatorEvaluator.getInstance().addFunction(new StrContainsFunction()); + AviatorEvaluator.getInstance().addFunction(new StrExistsFunction()); + AviatorEvaluator.getInstance().addFunction(new StrMatchesFunction()); } /** @@ -75,12 +83,12 @@ private static class StrEqualFunction extends AbstractFunction { @Override public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { if (arg1 == null || arg2 == null) { - return AviatorBoolean.valueOf(false); + return AviatorBoolean.FALSE; } Object leftTmp = arg1.getValue(env); Object rightTmp = arg2.getValue(env); if (leftTmp == null || rightTmp == null) { - return AviatorBoolean.valueOf(false); + return AviatorBoolean.FALSE; } String left = String.valueOf(leftTmp); String right = String.valueOf(rightTmp); @@ -91,4 +99,76 @@ public String getName() { return "equals"; } } + + /** + * 自定义aviator判断字符串1是否包含字符串2 (case-insensitive) + */ + private static class StrContainsFunction extends AbstractFunction { + @Override + public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { + if (arg1 == null || arg2 == null) { + return AviatorBoolean.FALSE; + } + Object leftTmp = arg1.getValue(env); + Object rightTmp = arg2.getValue(env); + if (leftTmp == null || rightTmp == null) { + return AviatorBoolean.FALSE; + } + String left = String.valueOf(leftTmp); + String right = String.valueOf(rightTmp); + return AviatorBoolean.valueOf(StringUtils.containsIgnoreCase(left, right)); + } + @Override + public String getName() { + return "contains"; + } + } + + /** + * 自定义aviator判断环境中是否存在字符串 + */ + private static class StrExistsFunction extends AbstractFunction { + @Override + public AviatorObject call(Map env, AviatorObject arg) { + if (arg == null) { + return AviatorBoolean.FALSE; + } + Object keyTmp = arg.getValue(env); + if (keyTmp == null) { + return AviatorBoolean.FALSE; + } + String key = String.valueOf(keyTmp); + return AviatorBoolean.valueOf(env.containsKey(key)); + } + @Override + public String getName() { + return "exists"; + } + } + + /** + * 自定义aviator判断字符串是否匹配regex + * - regex需要加上""或者'' + */ + private static class StrMatchesFunction extends AbstractFunction { + @Override + public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { + if (arg1 == null || arg2 == null) { + return AviatorBoolean.FALSE; + } + Object strTmp = arg1.getValue(env); + Object regexTmp = arg2.getValue(env); + if (strTmp == null || regexTmp == null) { + return AviatorBoolean.FALSE; + } + String str = String.valueOf(strTmp); + String regex = String.valueOf(regexTmp); + boolean isMatch = Pattern.compile(regex).matcher(str).matches(); + return AviatorBoolean.valueOf(isMatch); + } + @Override + public String getName() { + return "matches"; + } + } } diff --git a/common/src/test/java/org/dromara/hertzbeat/common/config/AviatorConfigurationTest.java b/common/src/test/java/org/dromara/hertzbeat/common/config/AviatorConfigurationTest.java new file mode 100644 index 00000000000..aaef4635d64 --- /dev/null +++ b/common/src/test/java/org/dromara/hertzbeat/common/config/AviatorConfigurationTest.java @@ -0,0 +1,91 @@ +package org.dromara.hertzbeat.common.config; + +import com.googlecode.aviator.AviatorEvaluator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author mikezzb + * + */ +class AviatorConfigurationTest { + + @BeforeAll + static void setUp() { + AviatorConfiguration aviatorConfig = new AviatorConfiguration(); + aviatorConfig.configAviatorEvaluator(); + } + + @Test + void testCustomStringFunctions() { + Map env = new HashMap<>(); + env.put("k1", "Intel"); + env.put("k2", "intel"); + env.put("k3", "Ubuntu 18.04.6 LTS"); + env.put("k4", "ubuntu"); + env.put("k5", "Ubntu"); + env.put("k6", null); + + // test StrEqualFunction + String expr1 = "equals(k1,k2)"; // case-insensitive + Boolean res1 = (Boolean) AviatorEvaluator.compile(expr1).execute(env); + Assertions.assertTrue(res1); + + String expr2 = "equals(k1,k3)"; + Boolean res2 = (Boolean) AviatorEvaluator.compile(expr2).execute(env); + Assertions.assertFalse(res2); + + // test StrContainsFunction + String expr3 = "contains(k3,k4)"; // case-insensitive + Boolean res3 = (Boolean) AviatorEvaluator.compile(expr3).execute(env); + Assertions.assertTrue(res3); + + String expr4 = "contains(k4,k3)"; + Boolean res4 = (Boolean) AviatorEvaluator.compile(expr4).execute(env); + Assertions.assertFalse(res4); + + String expr5 = "contains(k3,k5)"; // subsequence + Boolean res5 = (Boolean) AviatorEvaluator.compile(expr5).execute(env); + Assertions.assertFalse(res5); + + // test StrExistsFunction + String expr6 = "exists('DNE_Key1')"; + Boolean res6 = (Boolean) AviatorEvaluator.compile(expr6).execute(env); + Assertions.assertFalse(res6); + + String expr7 = "exists('k6')"; + Boolean res7 = (Boolean) AviatorEvaluator.compile(expr7).execute(env); + Assertions.assertTrue(res7); + + // test StrMatchesFunction + String regex1 = "'^[a-zA-Z0-9]+$'"; // only alphanumeric + String expr8 = "matches(k6," + regex1 + ")"; + env.put("k6", "Ubntu50681269"); + Boolean res8 = (Boolean) AviatorEvaluator.compile(expr8).execute(env); + Assertions.assertTrue(res8); + env.put("k6", "Ubnt_u50681269"); + Boolean res9 = (Boolean) AviatorEvaluator.compile(expr8).execute(env); + Assertions.assertFalse(res9); + + String regex2 = "'^Ubuntu.*'"; // starts with + String expr9 = "matches(k3," + regex2 + ")"; + Boolean res10 = (Boolean) AviatorEvaluator.compile(expr9).execute(env); + Assertions.assertTrue(res10); + env.put("k3", "Ubunt_u50681269"); + Boolean res11 = (Boolean) AviatorEvaluator.compile(expr9).execute(env); + Assertions.assertFalse(res11); + + String regex3 = "\"^\\\\[LOG\\\\].*error$\""; // starts & ends with + String expr10 = "matches(k7," + regex3 + ")"; + env.put("k7", "[LOG] detected system error"); + Boolean res12 = (Boolean) AviatorEvaluator.compile(expr10).execute(env); + Assertions.assertTrue(res12); + env.put("k7", "[LOG detected system error"); + Boolean res13 = (Boolean) AviatorEvaluator.compile(expr10).execute(env); + Assertions.assertFalse(res13); + } +} \ No newline at end of file