0 Replies Latest reply: May 8, 2012 5:12 AM by Stephan Leutenmayr RSS

Missing Dependency Injection in Bean called by Drools event rule

Stephan Leutenmayr Newbie

Hello,

 

I am developing a Seam application that enables users to trade shares on a virtual market. In this application, I want to employ Drools for triggering actions given certain patterns in the stream of trading events. I use Seam 2.2.0 and JBoss 4.2. In this version of Seam, the provided Drools can only be used as a rule base end engine but not for processing event streams as this requires the usage of the Drools knowledge base and working memory entry points. I already replaced the Seam provided Drools jars with the Drools 5.2 jars. However, Seam does not provide for configuring knowledge bases, only rule bases. Thus, I manually create the required knowledge base, knowledge session and working memory entry points in an application scoped bean (tradeExecutionBean). Upon executing a trade, I insert the trade event into the working memory entry point and the rule engine executes the matching rule. A call to System.out.println works fine from the rule. However, I want to trigger another execution of a trade by calling executeTransaction from within the rule. Thus, I made the tradeExecutionBean available to the session by setGlobal. The method is then executed, but the entityManager does not get injected to the tradeExecutionBean, but resolves to null. How should I best trigger the execution of this method from within the rule? Should I try to get the entityManager injected, or should I follow a different approach not calling the method from within the rule?

 

Thank you

 

Stephan

 

 

@Name("tradeExecutionBean")
@Scope(ScopeType.APPLICATION)
@Startup
@Synchronized
public class TradeExecutionBean
{
          @In
          private EntityManager entityManager;


          private StatefulKnowledgeSession kSession;
          private WorkingMemoryEntryPoint tradeEntryPoint;


          @Create
          public void create()
          {
                    KnowledgeAgent agent = KnowledgeAgentFactory.newKnowledgeAgent("knowledgeAgent");
                    agent.monitorResourceChangeEvents(true);
                    agent.applyChangeSet(ResourceFactory.newClassPathResource("changeset.xml"));


                    KnowledgeBase kbase = agent.getKnowledgeBase();

                    kSession = kbase.newStatefulKnowledgeSession();
                    kSession.setGlobal("tradeExecutionBean", this);
                    tradeEntryPoint = kSession.getWorkingMemoryEntryPoint("transactionStream");

                    // Fire rules in session until halt in a separate thread
                    new Thread(new Runnable()
                    {
                              public void run()
                              {
                                        kSession.fireUntilHalt();
                              }
                    }).start();
          }

          @Transactional(TransactionPropagationType.REQUIRED)
          public void executeTransaction(..)
          {
                    int holdingsQuantity;
                    try
                    {
                              System.out.println(entityManager);
                              holdingsQuantity = (Integer) entityManager.createQuery("SELECT h.quantity FROM Holdings AS h WHERE h.person.id = :personid AND h.stock.id = :stockid").setParameter("stockid", stock.getId()).setParameter("personid", person.getId()).getSingleResult();
                    }
                    catch (NoResultException e)
                    {
                              holdingsQuantity = 0;
                    }
                    //create transaction event here..
                    tradeEntryPoint.insert(transaction);
          }
}

 

rule TransactionNotification
  when
  t: Transaction() from entry-point "transactionStream"
  then 
  tradeExecutionBean.executeTransaction(..);
end