【问题标题】:KIE execution server - guided rule inserted fact - how to get it in Java?KIE 执行服务器 - 引导规则插入事实 - 如何在 Java 中获取它?
【发布时间】:2016-03-24 05:29:02
【问题描述】:

我正在使用 6.3.0 Drools Workbench 和 KIE 执行服务器,通过 REST 从 JAVA 应用程序到 KIE 执行服务器进行通信。

我是使用 Drools 的新手。

这里有类似的问题,但没有解决问题(尤其是对于 REST 和 6.3.0 的组合):

好的,既然我们已经奠定了基础,这真的不可能吗?还是我们都理解错了?还有什么? :)

问题是这是应该经常遇到的事情,因为当您在 Drools Workbench 中使用引导规则时,它只在规则的 THEN 部分提供这种操作:“插入事实......”和“逻辑插入事实...”(并调用方法)。

当添加事实(在我的例子中是“交易”)时,它会生成如下规则代码:

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!");
        }
    };

或者这只是错误的方法?

谢谢!

【问题讨论】:

  • 您引用的第一个问题已完全回答并接受。第二个问题的 cmets 提到了 getObjects 命令,用于检索事实。其他命令也可用于从 Drools 服务器返回信息。
  • @laune 你是在暗示这是重复的,应该关闭吗?
  • 值得商榷。我还在检查它。无论如何,我正在使用 REST,建议的解决方案不起作用。今天我会发表评论,提供更多信息。
  • @kaskelotti 首先,我驳斥了 Eddie 的说法,即第一个问题“未得到解答”。更详细的描述可能会阐明他的问题。
  • 更改了声明的“未回答”部分。谢谢。

标签: java drools kie


【解决方案1】:

玩了一段时间,这是我发现的......

我不确定上述问题和答案中建议的解决方案是否因 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 服务器返回 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...?");
    }

如评论中所述,这将返回会话中的所有对象。如果您多次调用该程序,它会将对象添加到会话中,而不会删除旧对象。我没有更多时间玩它来弄清楚如何解决这个问题,只从这个单一的电话中得到那些。撤回或可能的东西。

我实际上发现我根本不需要这个(并且 insert(fact) 可能不适合我的用例),但我想将我发送的带有填充值的相同输入对象返回到它的属性中。

为发送的输入对象设置属性并将此对象检索回 Java

我发现(告诉你我是 Drools 的新手)我实际上可以在 Drools 工作台->引导规则中为对象分配一个变量。当您通过“向规则添加条件...”在规则的“WHEN”部分添加对象时,您只需设置变量名称(在弹出窗口的底部),它将在“THEN”部分提供其他选项,比如“修改”、“更改字段值”、...

如果您选择“更改字段...”,它将创建如下规则:

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");

我希望这对某人有所帮助。

问候, 埃迪

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 2021-11-30
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    相关资源
    最近更新 更多