如何在简单规则中使用变量?
How to use variables in easy rules?
我正在使用 JSON descriptor
来加载使用 easy-rules 的规则,我想在简单规则 actions
中使用变量。例如,我有一组规则,我在其中定义规则 ID、名称、描述,如下所示
[
{
"id": 1,
"name": "Task using Oracle DB",
"description": "Updated comments to update connector",
"priority": 1,
"condition": "user.getTaskData().getTargetConnectorType().contains(\"Oracle\") || user.getTaskData().getSourceConnectorType().contains(\"Oracle\")",
"actions": [
"user.setRuleDetail([\"impacted_feature\":\"Task using Oracle DB\", \"desc\": \"Updated comments to update connector\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
}
]
下面两种可能吗
-> 使用规则 name
, description
inside actions?
...
[
{
"id": 1,
"name": "Task using Oracle DB",
"description": "Updated comments to update connector",
"priority": 1,
"condition": "user.getTaskData().getTargetConnectorType().contains(\"Oracle\") || user.getTaskData().getSourceConnectorType().contains(\"Oracle\")",
"actions": [
"user.setRuleDetail([\"impacted_feature\":\"+name+\", \"desc\": \"+description+\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
}
]
...
-> 在操作下使用变量?
...
"actions": [
"def name = \"Task using Oracle DB\"",
"def desc = \"Updated comments to update connector\"",
"def connector = \"Oracle\"",
"user.setRuleDetail([\"impacted_feature\":\"+name+\", \"desc\": \"+desc+\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
...
更新
这里我在初始化MVELRuleFactory
def computeRules(UserData userData) {
try {
Facts facts = new Facts()
facts.put("user", userData)
MVELRuleFactory ruleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader())
Rules rules = ruleFactory.createRules(new FileReader("conf/rules.json"))
//create a default rules engine and fire rules on known facts
RulesEngine rulesEngine = new DefaultRulesEngine()
rulesEngine.fire(rules, facts)
} catch(FileNotFoundException fnfe) {
_errorLogger.error("Error in #computeRules {}", fnfe)
} catch(Exception e) {
_errorLogger.error("Error in #computeRules {}", e)
}
return userData.getRuleDetail()
}
//UserData POJO
@CompileStatic
class UserData {
String orgKey
TaskData taskData
List<Map> ruleDetail
UserData(String orgKey, TaskData taskData) {
this.orgKey = orgKey
this.taskData = taskData
}
String getOrgKey() {
return orgKey
}
void setOrgKey(String orgKey) {
this.orgKey = orgKey
}
TaskData getTaskData() {
return taskData
}
void setTaskData(TaskData taskData) {
this.taskData = taskData
}
List<Map> getRuleDetail() {
return ruleDetail
}
void setRuleDetail(Map ruleData) {
if (this.ruleDetail == null)
this.ruleDetail = []
this.ruleDetail.add(ruleData)
}
@Override
public String toString() {
return "UserData{" +
"orgKey='" + orgKey + '\'' +
", taskData=" + taskData +
", ruleDetail=" + ruleDetail +
'}';
}
}
总结一下,没有也有!
要了解如何,您必须了解只要变量以 Fact
形式存在或以某种方式存在于 MVEL
上下文中,就可以解析。
这里有详细的解答-
Use rule name
, description
inside actions?
没有。您不能在 Action
中使用 Rule
的 name
和 description
。要在规则中使用外部变量,您必须将它们添加为事实。如果您想要这种能力,请使用 drools
,它 feature rich 和 heavy framework.
Use a variable under actions?
这你可以做到,但不是你所拥有的方式。 def
在MVEL
里面有特殊的含义。所以要使用变量,你可以做这些事情中的任何一个-
将变量定义为单独的操作项:
"actions": [
"name=\"....\"",
"description=\"....\"",
"user.setRuleDetail([\"impacted_feature\": name, \"desc\": description, \"impact\": \"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
添加行内变量:
"actions": [
"name=\"....\";description=\"....\";user.setRuleDetail([\"impacted_feature\": name, \"desc\": description, \"impact\": \"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
注意在动作中使用它们时不需要额外的 quotes
。
希望对您有所帮助!
您基本上是在尝试访问 condition/action 内的规则信息,或者换句话说,让 condition/action 了解该规则。您可以使用规则侦听器来做到这一点,该侦听器在规则执行之前将规则作为事实并在之后将其删除。这是一个简单的例子:
public class MyListener implements RuleListener {
@Override
public void beforeExecute(Rule rule, Facts facts) {
facts.put("rule", rule);
}
@Override
public void onSuccess(Rule rule, Facts facts) {
facts.remove("rule");
}
@Override
public void onFailure(Rule rule, Facts facts, Exception exception) {
facts.remove("rule");
}
// implement other methods if needed
}
下面是如何使用它:给定以下规则描述文件 rule-aware-action.json
:
[
{
"name": "rule aware action",
"description": "a rule where the action is aware of the rule",
"condition": "true",
"actions": [
"System.out.println(rule.name);"
]
}
]
以下示例打印 rule aware action
:
import java.io.FileReader;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.RuleListener;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.mvel.MVELRuleFactory;
import org.jeasy.rules.support.reader.JsonRuleDefinitionReader;
public class RuleAwareActionExample {
public static void main(String[] args) throws Exception {
MVELRuleFactory mvelRuleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader());
Rules rules = mvelRuleFactory.createRules(new FileReader("rule-aware-action.json"));
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRuleListener(new MyListener());
Facts facts = new Facts();
rulesEngine.fire(rules, facts);
}
}
这意味着操作能够访问它所属的规则的名称。该示例展示了如何使操作了解其规则,但它也应该适用于条件。
我正在使用 JSON descriptor
来加载使用 easy-rules 的规则,我想在简单规则 actions
中使用变量。例如,我有一组规则,我在其中定义规则 ID、名称、描述,如下所示
[
{
"id": 1,
"name": "Task using Oracle DB",
"description": "Updated comments to update connector",
"priority": 1,
"condition": "user.getTaskData().getTargetConnectorType().contains(\"Oracle\") || user.getTaskData().getSourceConnectorType().contains(\"Oracle\")",
"actions": [
"user.setRuleDetail([\"impacted_feature\":\"Task using Oracle DB\", \"desc\": \"Updated comments to update connector\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
}
]
下面两种可能吗
-> 使用规则 name
, description
inside actions?
...
[
{
"id": 1,
"name": "Task using Oracle DB",
"description": "Updated comments to update connector",
"priority": 1,
"condition": "user.getTaskData().getTargetConnectorType().contains(\"Oracle\") || user.getTaskData().getSourceConnectorType().contains(\"Oracle\")",
"actions": [
"user.setRuleDetail([\"impacted_feature\":\"+name+\", \"desc\": \"+description+\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
}
]
...
-> 在操作下使用变量?
...
"actions": [
"def name = \"Task using Oracle DB\"",
"def desc = \"Updated comments to update connector\"",
"def connector = \"Oracle\"",
"user.setRuleDetail([\"impacted_feature\":\"+name+\", \"desc\": \"+desc+\", \"impact\":\"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);"
]
...
更新
这里我在初始化MVELRuleFactory
def computeRules(UserData userData) {
try {
Facts facts = new Facts()
facts.put("user", userData)
MVELRuleFactory ruleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader())
Rules rules = ruleFactory.createRules(new FileReader("conf/rules.json"))
//create a default rules engine and fire rules on known facts
RulesEngine rulesEngine = new DefaultRulesEngine()
rulesEngine.fire(rules, facts)
} catch(FileNotFoundException fnfe) {
_errorLogger.error("Error in #computeRules {}", fnfe)
} catch(Exception e) {
_errorLogger.error("Error in #computeRules {}", e)
}
return userData.getRuleDetail()
}
//UserData POJO
@CompileStatic
class UserData {
String orgKey
TaskData taskData
List<Map> ruleDetail
UserData(String orgKey, TaskData taskData) {
this.orgKey = orgKey
this.taskData = taskData
}
String getOrgKey() {
return orgKey
}
void setOrgKey(String orgKey) {
this.orgKey = orgKey
}
TaskData getTaskData() {
return taskData
}
void setTaskData(TaskData taskData) {
this.taskData = taskData
}
List<Map> getRuleDetail() {
return ruleDetail
}
void setRuleDetail(Map ruleData) {
if (this.ruleDetail == null)
this.ruleDetail = []
this.ruleDetail.add(ruleData)
}
@Override
public String toString() {
return "UserData{" +
"orgKey='" + orgKey + '\'' +
", taskData=" + taskData +
", ruleDetail=" + ruleDetail +
'}';
}
}
总结一下,没有也有!
要了解如何,您必须了解只要变量以 Fact
形式存在或以某种方式存在于 MVEL
上下文中,就可以解析。
这里有详细的解答-
Use rule
name
,description
inside actions?
没有。您不能在 Action
中使用 Rule
的 name
和 description
。要在规则中使用外部变量,您必须将它们添加为事实。如果您想要这种能力,请使用 drools
,它 feature rich 和 heavy framework.
Use a variable under actions?
这你可以做到,但不是你所拥有的方式。 def
在MVEL
里面有特殊的含义。所以要使用变量,你可以做这些事情中的任何一个-
将变量定义为单独的操作项:
"actions": [ "name=\"....\"", "description=\"....\"", "user.setRuleDetail([\"impacted_feature\": name, \"desc\": description, \"impact\": \"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);" ]
添加行内变量:
"actions": [ "name=\"....\";description=\"....\";user.setRuleDetail([\"impacted_feature\": name, \"desc\": description, \"impact\": \"low\", \"count\":\"Using \"+user.getTaskDetail().getConnBucketData().get(\"Oracle\")+\" connector type\",\"id\":1, \"extra_detail\":\"{\\"impacted_connectors\\":[\\"Oracle\\"]}\"]);" ]
注意在动作中使用它们时不需要额外的
quotes
。
希望对您有所帮助!
您基本上是在尝试访问 condition/action 内的规则信息,或者换句话说,让 condition/action 了解该规则。您可以使用规则侦听器来做到这一点,该侦听器在规则执行之前将规则作为事实并在之后将其删除。这是一个简单的例子:
public class MyListener implements RuleListener {
@Override
public void beforeExecute(Rule rule, Facts facts) {
facts.put("rule", rule);
}
@Override
public void onSuccess(Rule rule, Facts facts) {
facts.remove("rule");
}
@Override
public void onFailure(Rule rule, Facts facts, Exception exception) {
facts.remove("rule");
}
// implement other methods if needed
}
下面是如何使用它:给定以下规则描述文件 rule-aware-action.json
:
[
{
"name": "rule aware action",
"description": "a rule where the action is aware of the rule",
"condition": "true",
"actions": [
"System.out.println(rule.name);"
]
}
]
以下示例打印 rule aware action
:
import java.io.FileReader;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.api.RuleListener;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.mvel.MVELRuleFactory;
import org.jeasy.rules.support.reader.JsonRuleDefinitionReader;
public class RuleAwareActionExample {
public static void main(String[] args) throws Exception {
MVELRuleFactory mvelRuleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader());
Rules rules = mvelRuleFactory.createRules(new FileReader("rule-aware-action.json"));
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRuleListener(new MyListener());
Facts facts = new Facts();
rulesEngine.fire(rules, facts);
}
}
这意味着操作能够访问它所属的规则的名称。该示例展示了如何使操作了解其规则,但它也应该适用于条件。