繁体   English   中英

Drools KModule持久性配置

[英]Drools KModule persistence configuration

我正在尝试设置具有持久性的kmodule。 我在内部使用guice,因此spring示例对我不是很有帮助。

我当前的设置如下所示:

  • 我有一个管理会议的核心项目
  • 我还有多个其他项目通过META-INF / kmodule.xml文件贡献了会议

这可以正常工作,但是我只是以编程方式(设置环境的EntityManager和TransactionManager)来完成此操作。 现在,我想在kmodule中拥有此配置,以便模块本身可以定义是否要持久化。

问题是,我不知道如何为此创建会话或如何配置模块。 例如,我可以找到的最简单的代码片段如下所示:

<kmodule
        xmlns="http://jboss.org/kie/6.0.0/kmodule">

    <kbase name="kbase1">
        <ksession name="ksession1"/>
    </kbase>

</kmodule>

此时将以如下方式创建会话:

    KieServices ks = KieServices.Factory.get();
    KieContainer kContainer = ks.getKieClasspathContainer();
    KieSession kSession = kContainer.newKieSession(name);

但是,如何在模块中配置持久性,或者如果不可能,则如何在程序设置中传递正确的会话名称。 我所拥有的是:

        // Guice inject Entitymanager and TransactionManager and setup the Environment variable env
        KieSessionConfiguration ksconf = ks.newKieSessionConfiguration();
        ksconf.setOption(ClockTypeOption.get("realtime"));
        JPAKnowledgeService.newStatefulKnowledgeSession(kbase, ksconf, env);

我在想,也许有一种方法可以通过KieSessionConfiguraton将会话名称传递给JPAKnowledgeService类,但我似乎找不到任何方法。

另外,在kmodule本身中配置它甚至会更酷。 我可以使用spring方法,但是我有点怀疑注入是否会那样工作。 据我所知,Spring中的后处理器将进行持久性注入。 我不认为guice即使提供它们也无法做到这一点?

谢谢

因此,我调查了一下,并研究了很多口水的代码,以尝试并解决这个问题。

KieContainer#newSession所做的全部工作就是查询模型,然后向数据库询问具有会话配置的新会话:

public KieSession newKieSession(String kSessionName, Environment environment, KieSessionConfiguration conf) {
    KieSessionModelImpl kSessionModel = (KieSessionModelImpl) getKieSessionModel(kSessionName);
    if ( kSessionModel == null ) {
        log.error("Unknown KieSession name: " + kSessionName);
        return null;
    }
    if (kSessionModel.getType() == KieSessionModel.KieSessionType.STATELESS) {
        throw new RuntimeException("Trying to create a stateful KieSession from a stateless KieSessionModel: " + kSessionName);
    }
    KieBase kBase = getKieBase( kSessionModel.getKieBaseModel().getName() );
    if ( kBase == null ) {
        log.error("Unknown KieBase name: " + kSessionModel.getKieBaseModel().getName());
        return null;
    }

    KieSession kSession = kBase.newKieSession( conf != null ? conf : getKnowledgeSessionConfiguration(kSessionModel), environment );
    wireListnersAndWIHs(kSessionModel, kSession);
    registerLoggers(kSessionModel, kSession);
    kSessions.put(kSessionName, kSession);
    return kSession;
}

同时,这正是StoreService实现的功能,并带有一些高级的哈利波特代码来使事情持久化。 但是它忽略了会话的配置,我几乎可以说这是一个错误..(此后可能会引发一个错误)

但是,无论如何,由KieContainer创建的配置仅考虑两个选项:

private KieSessionConfiguration getKnowledgeSessionConfiguration(KieSessionModelImpl kSessionModel) {
    KieSessionConfiguration ksConf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
    ksConf.setOption( kSessionModel.getClockType() );
    ksConf.setOption( kSessionModel.getBeliefSystem() );
    return ksConf;
}

这意味着,我将有2个解决方案:

要么编写我自己的KieContainerImpl做正确的事情(为什么要打扰...),要么模拟会话配置。 我决定做第二个。

public KieSession createJPASession(final String kieBaseId, Optional<String> clockType, Optional<String> beliefSystem) {
    log.info(String.format("Creating JPA Session for kieBase %s, clockType %s, beliefSystem %s", kieBaseId, clockType, beliefSystem));
    KieBase kieBase = kContainer.getKieBase(kieBaseId);
    KieSessionConfiguration ksConf = ks.newKieSessionConfiguration();

    // Set this thing up manually. Looking at the impl/docs these are the only two options available to set.
    // The Storage service will remove those options from a default session for whatever reason, however we can set this manually
    // This means we can use the base configuration and have things run in a normal way

    if (clockType.isPresent()) {
        ksConf.setOption(ClockTypeOption.get(clockType.get()));
    }
    if (beliefSystem.isPresent()) {
        ksConf.setOption(BeliefSystemTypeOption.get(beliefSystem.get()));
    }

    KieSession jpaSession = ks.getStoreServices().newKieSession(kieBase, ksConf, env);
    sessions.put(jpaSession.getIdentifier(), jpaSession);
    return jpaSession;
}

最后一个代码片段将创建配置的会话,同时使其持久化。

或者,通过将KieContainer强制转换为KieContainerImpl,可以访问查询KieModule中的KieSession对象所需的公共方法。 (这是很多Kie的东西)这样一来,便可以使用相同的方法并访问XML配置。 我的方法是多种多样的(使用KieBase / Module的xml config编程设置信念系统和时钟类型)。 原因是我不想依赖内部实现,也不想打扰实现自己的KieContainer并将其连接。

我希望这可以帮助某人。 如果其他人知道这样做的“正确”方法,请发布它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM