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

gre*_*ker 8 java drools

背景:

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

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

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
Run Code Online (Sandbox Code Playgroud)

以下是调用规则的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

问题:

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

题:

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

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

gre*_*ker 10

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

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

query "GetOutputObj"
    baseTrade: BaseTrade()
end
Run Code Online (Sandbox Code Playgroud)

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

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)