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

发布于 2024-11-05 00:07:03 字数 2368 浏览 2 评论 0原文

背景

我正在开发一个应用程序,该应用程序根据一组 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

以下是调用规则的代码:

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;
}

问题:

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

问题

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

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

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.

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.

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?

EDIT:
Do I need to use a drools query?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

素年丶 2024-11-12 00:07:03

我继续使用了一个流口水查询。我会将代码发布给其他来的人。

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

query "GetOutputObj"
    baseTrade: BaseTrade()
end

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

    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();
        }
    }

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

Query added to the rules above (The objects extend 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();
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文