簡體   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