3 Replies Latest reply on Apr 2, 2013 5:21 PM by David Ward

    Drools integration problem

    Anton Nikulin Newbie

      Hi

       

      We are developing one system which uses Switchyard and Drools frameworks and as a repository for rules we use Guvnor. In Switchyard application we have independent service which works with Guvnor and fires rules (we have to create our own cause default switchyard's implementation for drools doesn't allow to work with global variables and KnowledgeAgent).

       

      At the developing process we faced with a problem when Switchyard service doesn't properly work with KnowledgeAgent and sometimes doesn't generate KnowledgeBase and it causes exceptions. Moreover, such situation occurs only when we deploy application on Switchyard-AS7 server, as standalone application it works fine.

       

      We have such ServiceBean:

       

      @Service(DroolsService.class)

      public class DroolsServiceBean implements DroolsService {

       

          private KnowledgeAgent kagent;

       

          public DroolsServiceBean() {

              initialize();

          }

       

          public void initialize() {

              ResourceChangeScannerConfiguration sconf = ResourceFactory

                      .getResourceChangeScannerService()

                      .newResourceChangeScannerConfiguration();

              sconf.setProperty("drools.resource.scanner.interval", "5");

              ResourceFactory.getResourceChangeScannerService().configure(sconf);

       

              KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory

                      .newKnowledgeAgentConfiguration();

              aconf.setProperty("drools.agent.scanDirectories", "true");

              aconf.setProperty("drools.agent.scanResources", "true");

              aconf.setProperty("drools.agent.newInstance", "true");

       

              kagent = KnowledgeAgentFactory.newKnowledgeAgent("changeSetAgent",

                      aconf);

       

              kagent.applyChangeSet(ResourceFactory

                      .newClassPathResource("ChangeSet.xml"));

          }

       

          @Override

          public synchronized void fireRules(String o) {

       

              StatefulKnowledgeSession session = kagent.getKnowledgeBase()

                      .newStatefulKnowledgeSession();

              session.setGlobal("modifiedOrderList", new ArrayList<String>());

              session.insert(o);

              session.fireAllRules();

              session.dispose();

          }

       

      }

       

      And such UnitTest for it:

       

      @RunWith(SwitchYardRunner.class)

      @SwitchYardTestCaseConfig(config = SwitchYardTestCaseConfig.SWITCHYARD_XML, mixins = { CDIMixIn.class }, scanners = { BeanSwitchYardScanner.class })

      public class DroolsServiceTest {

       

          @ServiceOperation("DroolsService")

          private Invoker service;

       

          @Test

          public void testFireRules() throws Exception {

              service.operation("fireRules").sendInOnly(new String("123"));

          }

      }

       

      When I run this test, everything is ok, rules are fired and i can see the result.
      But when I use the same service deployed in switchyard-as7 i have such error (i have a rest binding for it and invoke it in that way):

       

       

      23:41:58,728 WARN  [org.switchyard.component.bean.ServiceProxyHandler] (http-localhost-127.0.0.1-8080-1) Invocation of operation 'fireRules' on bean component 'com.example.switchyard.droolsAgentError.DroolsServiceBeanfailed.: java.lang.reflect.InvocationTargetException

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_30]

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_30]

      ...

      Caused by: java.lang.RuntimeException: Unexpected global [modifiedOrderList]

          at org.drools.common.AbstractWorkingMemory.setGlobal(AbstractWorkingMemory.java:588) [drools-core-5.5.0.Final.jar:5.5.0.Final]

          at org.drools.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:346) [drools-core-5.5.0.Final.jar:5.5.0.Final]

          at com.example.switchyard.droolsAgentError.DroolsServiceBean.fireRules(DroolsServiceBean.java:46) [droolsAgentError.jar:]

          ... 83 more

       

      It says that i don't have modifiedOrderList in my rules, but i checked many times, i have it and test, which also set it, works fine. Even if i delete line where global variable is set, this error doesn't appear, but rules are also not fired and it seems like KnowledgeBase is empty.

       

      Moreover, one interesting thing, if i move initialize() method invocation from constructor to fireRules() method, system works fine both on server and as standalone. but in this case i recreate a KnowledgeAgent.
      I added an if section like this in fireRules() method:

       

      if (agent == null){

          initialize();

      }

       

      I this case we don't recreate KnowledgeAgent, but it works until the first agent update.  So if KnowledgeAgent is updated every 5 seconds, first methods invocation works ok and than it fails with the same error.
      So we can say that it worked only with new KnowledgeAgent before it checks updates, but we can't undestand why.


      Can you help us please?

       

      Regards, Anton

        • 1. Re: Drools integration problem
          David Ward Master

          What version of SwitchYard are you using?  I ask because we've long since moved to KIE/Drools/jBPM 6 in our SwitchYard+AS7 bundle.  Are you manually changing the Drools version back to 5.5 in AS7?  (In Drools 6+, the KnowledgeAgent is deprecated functionality...)

           

          Also, I see that you're manually doing all the setup work too of the agent.  If you use the OOTB SwitchYard Rules component, and it's KieContainer functionality, then we can do the work of setting up a KieScanner to poll for changes to your rules.  Unfortunately, I don't know how well that works with current versions of Guvnor; you're catching the Drools/jBPM project at a time when there's a lot of flux.  And that can mean temporary incompatibility between their projects. (In this case, the runtime that SwitchYard is using, and Guvnor.)

           

          Before I go any further with how to use the KieContainer/KieScanner, however, it would be good to know what your'e doing with versions and dependencies.

          • 2. Re: Drools integration problem
            Anton Nikulin Newbie

            As Drools haven't present 6 version officiently yet and there is no guvnor 6, we are using Drools 5.5.0 Final and Guvnor 5.5.0 Final. Yes, for these we changed drools jar in server drools' module.

             

            We had to create our own Drools implementation and configuration cause in SY6 there was no possibility to change scanningIntervalTime for KnowledgeAgent and was no way to get global variables after rules invocation. Have SY7 and 8 got such options

             

            Regards, Anton

            • 3. Re: Drools integration problem
              David Ward Master

              It sounds like you will indeed need to invoke drools manually then, as the SY rules component only supports Drools 6 now.