0 Replies Latest reply on May 8, 2012 5:12 AM by leutenmayr

    Missing Dependency Injection in Bean called by Drools event rule

    leutenmayr

      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

       

       

      {code}

      @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);

                }

      }

      {code}

       

      {code}

      rule TransactionNotification

        when

        t: Transaction() from entry-point "transactionStream"

        then

        tradeExecutionBean.executeTransaction(..);

      end

      {code}