KIE 执行服务器 - 引导规则插入事实 - 如何在 Java 中获取它?
KIE execution server - guided rule inserted fact - how to get it in Java?
我正在使用 6.3.0 Drools Workbench 和 KIE 执行服务器,通过 REST 从 JAVA 应用程序到 KIE 执行服务器的通信。
我是使用 Drools 的新手。
下面是类似的问题,但没有解决问题(尤其是REST和6.3.0的结合):
- Access to Drools returned fact object in Java Code
- Drools: How to retrieve the fact in response from Kie Execution Server?
好吧,既然我们把地基给定了,这真的不可能吗?还是我们都理解错了?还有别的吗? :)
问题是,这是应该经常遇到的事情,因为当您在 Drools Workbench 中使用引导规则时,它仅在规则的 THEN 部分提供这种操作:"Insert Fact ..." 和 "Logically insert fact ..." (和调用方法)。
添加事实时(在我的例子中是 "Transaction"),它会生成如下规则代码:
import java.lang.Number;
rule "BigAmount"
dialect "mvel"
when
Transaction( amount > 10000.0 )
then
Transaction fact0 = new Transaction();
fact0.setActivatedRule( "BigAmount" );
insert( fact0 );
end
人们希望在 Java 中恢复这一事实。
Java 结果是这样的:
<fact-handle identifier="Transaction" external-form="0:9:338894407:338894407:9:DEFAULT:NON_TRAIT:hr.company.Transaction"/>
当试图像这样检索它时,你得到 NULL:
... before is request sent ...
KieServerCommand call = new CallContainerCommand(containerId, xStreamXml);
List<KieServerCommand> cmds = Arrays.asList(call);
CommandScript script = new CommandScript(cmds);
for (int i=0; i<1; i++) {
ServiceResponsesList reply = client.executeScript(script);
for (ServiceResponse<? extends Object> r : reply.getResponses()) {
System.out.println(r.getResult());
ExecutionResultImpl result = (ExecutionResultImpl) BatchExecutionHelper.newXStreamMarshaller().fromXML( (String) r.getResult() );
DefaultFactHandle obj = (DefaultFactHandle) result.getFactHandle("Transaction");
Transaction t = (Transaction) obj.getObject();
System.out.println("BU!");
}
};
或者这只是错误的方法?
谢谢!
玩了一段时间,这是我发现的...
我不确定提到的问题和答案中的建议解决方案是否因 Drools/KIE 版本不同或这是与 KIE 服务器的 REST 通信而有所不同,但它们不适用于此处。
在规则中获取插入的对象(事实)
如果您有这样的规则:
rule "BigAmount"
dialect "mvel"
when
Transaction( amount > 10000.0 )
then
Transaction fact0 = new Transaction();
fact0.setActivatedRule( "BigAmount" );
insert( fact0 );
end
并且您想通过 REST 在 JAVA 中检索它,您需要在 BatchExecutionCommand 中插入 GetObjects 命令:
Transaction trans = new Transaction();
trans.setAmount(new Double(10001));
// define commands
InsertObjectCommand insertObjectCommand = new InsertObjectCommand(trans, "InputTransaction");
GetObjectsCommand getObjectsCommand = new GetObjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand("RunAllRules");
// insert commands into Command object (BatchExecutionCommand)
List<GenericCommand<?>> commands = new ArrayList<GenericCommand<?>>();
commands.add(insertObjectCommand);
commands.add(fireAllRulesCommand);
commands.add(getObjectsCommand);
BatchExecutionCommand command = new BatchExecutionCommandImpl(commands);
String xStreamXml = BatchExecutionHelper.newXStreamMarshaller().toXML(command); // actual XML request
所以,重要的部分是:
GetObjectsCommand getObjectsCommand = new GetbjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
这将告诉 KIE 服务器 return 您在 XML 中分离节点 - ,您将在 KIE 会话中找到所有对象:
<execution-results>
<result identifier="InputTransaction">
<com.company.fm.Transaction>
<amount>10001.0</amount>
<activatedRule>
<string>BigAmount</string>
</activatedRule>
</com.company.fm.Transaction>
</result>
<result identifier="RunAllRules">
<int>1</int>
</result>
<result identifier="objects">
<list>
... all objects ...
</list>
</result>
<fact-handle identifier="InputTransaction" external-form="0:1:226077856:226077856:1:DEFAULT:NON_TRAIT:com.company.fm.Transaction"/>
</execution-results>
之后,您可以从会话中获取所有对象:
// define kie client
KieServicesConfiguration config = KieServicesFactory.newRestConfiguration(
"http://docklin:8180/kie-server/services/rest/server",
"ks-user", //user must have role "kie-server" assigned
"ks-user");
config.setMarshallingFormat(MarshallingFormat.XSTREAM);
KieServicesClient client = KieServicesFactory.newKieServicesClient(config);
// set container for execution and prepare the call
String containerId = "fm";
KieServerCommand call = new CallContainerCommand(containerId, xStreamXml);
List<KieServerCommand> cmds = Arrays.asList(call);
CommandScript script = new CommandScript(cmds);
ServiceResponsesList reply = client.executeScript(script);
for (ServiceResponse<? extends Object> r : reply.getResponses()) {
System.out.println(r.getResult());
if (r.getResult() != null) {
ExecutionResultImpl result = (ExecutionResultImpl) BatchExecutionHelper.newXStreamMarshaller().fromXML((String) r.getResult());
// getting the same object that was sent but with filled in values
trans = (Transaction) result.getResults().get("InputTransaction");
// Objects From insert(fact0) in rule. The problem is that they are staying and multiplying there in Drools, don't know yet how to manage it. ToDo.
ArrayList<Object> objects = (ArrayList<Object>) result.getResults().get("objects");
System.out.println(objects);
}
else
System.out.println("Empty result...?");
}
如评论中所述,这将 return 会话中的所有对象。如果多次调用该程序,它会将对象添加到会话中而不删除旧对象。我没有更多的时间来玩弄它来弄清楚如何解决这个问题,只从这个单一的电话中获得那些。收回什么的可能。
我实际上发现我根本不需要这个(并且 insert(fact) 可能不适合我的用例)但是我想要返回我发送的带有填充值的相同输入对象属性。
正在为发送的输入对象设置属性并将该对象检索回 Java
我发现(告诉过你我是 Drools 的新手)我实际上可以在 Drools workbench->Guided Rule 中为对象分配一个变量。当您通过 "Add a condition to the rule..." 在规则的 "WHEN" 部分添加对象时,您只需设置变量名称(在弹出窗口的底部),它将在 "THEN" 部分提供其他选项,例如 "Modify", "Change field values of ", ...
如果您选择 "Change field ..." 它将创建这样的规则:
rule "BigAmount"
dialect "mvel"
when
f : Transaction( amount >= 10000 )
then
f.addActivatedRule( "BigAmount" );
end
然后你实际上会在你发送的输入对象中得到这个值(在我的例子中是"InputTransaction"),这实际上是我的目标,并且不会插入新对象(事实) 在会话中。
也就是代码中的这一部分:
// getting the same object that was sent but with filled in values
trans = (Transaction) result.getResults().get("InputTransaction");
我希望这对某人有所帮助。
此致,
艾迪
我正在使用 6.3.0 Drools Workbench 和 KIE 执行服务器,通过 REST 从 JAVA 应用程序到 KIE 执行服务器的通信。
我是使用 Drools 的新手。
下面是类似的问题,但没有解决问题(尤其是REST和6.3.0的结合):
- Access to Drools returned fact object in Java Code
- Drools: How to retrieve the fact in response from Kie Execution Server?
好吧,既然我们把地基给定了,这真的不可能吗?还是我们都理解错了?还有别的吗? :)
问题是,这是应该经常遇到的事情,因为当您在 Drools Workbench 中使用引导规则时,它仅在规则的 THEN 部分提供这种操作:"Insert Fact ..." 和 "Logically insert fact ..." (和调用方法)。
添加事实时(在我的例子中是 "Transaction"),它会生成如下规则代码:
import java.lang.Number;
rule "BigAmount"
dialect "mvel"
when
Transaction( amount > 10000.0 )
then
Transaction fact0 = new Transaction();
fact0.setActivatedRule( "BigAmount" );
insert( fact0 );
end
人们希望在 Java 中恢复这一事实。 Java 结果是这样的:
<fact-handle identifier="Transaction" external-form="0:9:338894407:338894407:9:DEFAULT:NON_TRAIT:hr.company.Transaction"/>
当试图像这样检索它时,你得到 NULL:
... before is request sent ...
KieServerCommand call = new CallContainerCommand(containerId, xStreamXml);
List<KieServerCommand> cmds = Arrays.asList(call);
CommandScript script = new CommandScript(cmds);
for (int i=0; i<1; i++) {
ServiceResponsesList reply = client.executeScript(script);
for (ServiceResponse<? extends Object> r : reply.getResponses()) {
System.out.println(r.getResult());
ExecutionResultImpl result = (ExecutionResultImpl) BatchExecutionHelper.newXStreamMarshaller().fromXML( (String) r.getResult() );
DefaultFactHandle obj = (DefaultFactHandle) result.getFactHandle("Transaction");
Transaction t = (Transaction) obj.getObject();
System.out.println("BU!");
}
};
或者这只是错误的方法?
谢谢!
玩了一段时间,这是我发现的...
我不确定提到的问题和答案中的建议解决方案是否因 Drools/KIE 版本不同或这是与 KIE 服务器的 REST 通信而有所不同,但它们不适用于此处。
在规则中获取插入的对象(事实)
如果您有这样的规则:
rule "BigAmount"
dialect "mvel"
when
Transaction( amount > 10000.0 )
then
Transaction fact0 = new Transaction();
fact0.setActivatedRule( "BigAmount" );
insert( fact0 );
end
并且您想通过 REST 在 JAVA 中检索它,您需要在 BatchExecutionCommand 中插入 GetObjects 命令:
Transaction trans = new Transaction();
trans.setAmount(new Double(10001));
// define commands
InsertObjectCommand insertObjectCommand = new InsertObjectCommand(trans, "InputTransaction");
GetObjectsCommand getObjectsCommand = new GetObjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
FireAllRulesCommand fireAllRulesCommand = new FireAllRulesCommand("RunAllRules");
// insert commands into Command object (BatchExecutionCommand)
List<GenericCommand<?>> commands = new ArrayList<GenericCommand<?>>();
commands.add(insertObjectCommand);
commands.add(fireAllRulesCommand);
commands.add(getObjectsCommand);
BatchExecutionCommand command = new BatchExecutionCommandImpl(commands);
String xStreamXml = BatchExecutionHelper.newXStreamMarshaller().toXML(command); // actual XML request
所以,重要的部分是:
GetObjectsCommand getObjectsCommand = new GetbjectsCommand();
getObjectsCommand.setOutIdentifier("objects");
这将告诉 KIE 服务器 return 您在 XML 中分离节点 -
<execution-results>
<result identifier="InputTransaction">
<com.company.fm.Transaction>
<amount>10001.0</amount>
<activatedRule>
<string>BigAmount</string>
</activatedRule>
</com.company.fm.Transaction>
</result>
<result identifier="RunAllRules">
<int>1</int>
</result>
<result identifier="objects">
<list>
... all objects ...
</list>
</result>
<fact-handle identifier="InputTransaction" external-form="0:1:226077856:226077856:1:DEFAULT:NON_TRAIT:com.company.fm.Transaction"/>
</execution-results>
之后,您可以从会话中获取所有对象:
// define kie client
KieServicesConfiguration config = KieServicesFactory.newRestConfiguration(
"http://docklin:8180/kie-server/services/rest/server",
"ks-user", //user must have role "kie-server" assigned
"ks-user");
config.setMarshallingFormat(MarshallingFormat.XSTREAM);
KieServicesClient client = KieServicesFactory.newKieServicesClient(config);
// set container for execution and prepare the call
String containerId = "fm";
KieServerCommand call = new CallContainerCommand(containerId, xStreamXml);
List<KieServerCommand> cmds = Arrays.asList(call);
CommandScript script = new CommandScript(cmds);
ServiceResponsesList reply = client.executeScript(script);
for (ServiceResponse<? extends Object> r : reply.getResponses()) {
System.out.println(r.getResult());
if (r.getResult() != null) {
ExecutionResultImpl result = (ExecutionResultImpl) BatchExecutionHelper.newXStreamMarshaller().fromXML((String) r.getResult());
// getting the same object that was sent but with filled in values
trans = (Transaction) result.getResults().get("InputTransaction");
// Objects From insert(fact0) in rule. The problem is that they are staying and multiplying there in Drools, don't know yet how to manage it. ToDo.
ArrayList<Object> objects = (ArrayList<Object>) result.getResults().get("objects");
System.out.println(objects);
}
else
System.out.println("Empty result...?");
}
如评论中所述,这将 return 会话中的所有对象。如果多次调用该程序,它会将对象添加到会话中而不删除旧对象。我没有更多的时间来玩弄它来弄清楚如何解决这个问题,只从这个单一的电话中获得那些。收回什么的可能。
我实际上发现我根本不需要这个(并且 insert(fact) 可能不适合我的用例)但是我想要返回我发送的带有填充值的相同输入对象属性。
正在为发送的输入对象设置属性并将该对象检索回 Java
我发现(告诉过你我是 Drools 的新手)我实际上可以在 Drools workbench->Guided Rule 中为对象分配一个变量。当您通过 "Add a condition to the rule..." 在规则的 "WHEN" 部分添加对象时,您只需设置变量名称(在弹出窗口的底部),它将在 "THEN" 部分提供其他选项,例如 "Modify", "Change field values of ", ...
如果您选择 "Change field ..." 它将创建这样的规则:
rule "BigAmount"
dialect "mvel"
when
f : Transaction( amount >= 10000 )
then
f.addActivatedRule( "BigAmount" );
end
然后你实际上会在你发送的输入对象中得到这个值(在我的例子中是"InputTransaction"),这实际上是我的目标,并且不会插入新对象(事实) 在会话中。 也就是代码中的这一部分:
// getting the same object that was sent but with filled in values
trans = (Transaction) result.getResults().get("InputTransaction");
我希望这对某人有所帮助。
此致, 艾迪