java 如何在运行时将事实添加到 Drools DRL 中的工作内存并在无状态会话的执行结果中检索它们?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5872215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:13:24  来源:igfitidea点击:

How do I add facts to working memory at runtime in the Drools DRL and retrieve them in the execution results of a stateless session?

javadrools

提问by gregwhitaker

Background:

背景:

I'm working on an application that transforms an input object into one of two output objects based upon a set of drools rules. The output object is not known until runtime and it is created in the first rule to execute.

我正在开发一个应用程序,该应用程序根据一组 drools 规则将输入对象转换为两个输出对象之一。输出对象直到运行时才知道,它是在要执行的第一个规则中创建的。

Here is the rule that creates the output object and an example transformation rule:

这是创建输出对象的规则和示例转换规则:

rule "Initialization"
    dialect "java"
    salience 1000
    no-loop true
    when
        t : Trade()
    then 
        if(t.getTran().getInsType().equalsIgnoreCase("EEO") ||
           t.getTran().getInsType().equalsIgnoreCase("EEF"))
        {
            insert(new Option());
        }
        else
        {
            insert(new Swap());
        }
end

rule "Example Rule"
    dialect "java"
    when
        t : Trade()
        opt : Option()
    then
        opt.setCounterpartyName(t.getTran().getCParty());
end

Here is the code that is calling the rules:

这是调用规则的代码:

private void test(){
    for(File xmlFile : getXmlFilesFromDirectory(XML_DIRECTORY))
    {
        Trade trade = (Trade)unmarshall(xmlFile, Trade.class);

        KnowledgeBase kbase = readKnowledgeBase();

        StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
        KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);

        List<Command> commands = new ArrayList<Command>();
        commands.add(CommandFactory.newInsert(trade, "trade"));
        commands.add(CommandFactory.newFireAllRules());

        ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands));
        logger.close();
    }
 }

private static KnowledgeBase readKnowledgeBase() throws Exception 
{
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newClassPathResource("security-transformation.drl"), ResourceType.DRL);
    KnowledgeBuilderErrors errors = kbuilder.getErrors();
    if (errors.size() > 0) 
    {
        for (KnowledgeBuilderError error: errors) 
        {
            System.err.println(error);
        }

        throw new IllegalArgumentException("Could not parse knowledge.");
    }

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    return kbase;
}

Problem:

问题:

When I execute the rules I am not receiving the output object in my returned facts. I receive the trade object back but I do not get back the Option or the Swap object depending on which was added to working memory by the first rule.

当我执行规则时,我没有在返回的事实中收到输出对象。我收到了交易对象,但我没有取回 Option 或 Swap 对象,具体取决于第一个规则将哪个对象添加到工作内存中。

Question:

问题:

How do I add facts to working memory at runtime in the drl and retrieve them in the execution results of a stateless session?

如何在运行时将事实添加到 drl 中的工作内存并在无状态会话的执行结果中检索它们?

EDIT: Do I need to use a drools query?

编辑:我需要使用 drools 查询吗?

回答by gregwhitaker

I went ahead and used a drools query. I'll post the code for anyone else who comes along.

我继续使用了drools查询。我会为其他任何人发布代码。

Query added to the rules above (The objects extend BaseTrade):

添加到上述规则的查询(对象扩展BaseTrade):

query "GetOutputObj"
    baseTrade: BaseTrade()
end

Code to retrieve the query results from the execution results:

从执行结果中检索查询结果的代码:

    StatelessKnowledgeSession ksession = this.kbase.newStatelessKnowledgeSession();

    KnowledgeRuntimeLogger klogger = configureKnowledgeRuntimeLogger(ksession);

    List<Command> commands = new ArrayList<Command>();
    commands.add(CommandFactory.newInsert(inputObj, "inputObj"));
    commands.add(CommandFactory.newFireAllRules());
    commands.add(CommandFactory.newQuery("outputObj", "GetOutputObj"));

    ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands));

    QueryResults queryResults = ((NativeQueryResults)results.getValue("baseTrade")).getResults();

    try
    {
        Iterator iter = queryResults.iterator();
        while(iter.hasNext())
        {
            QueryResult result = iter.next();

            //There can be only one... just like Highlander
            //Could switch this up and return a list, but we only expect one thing from here.
            return (BaseTrade) result.get("baseTrade");
        }
    }
    finally
    {
        if(klogger != null)
        {
            klogger.close();
        }
    }