Drools integration problem
anikulin Apr 1, 2013 1:56 PMHi
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