package org.drools.agent; import java.io.File; import java.util.ArrayList; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseFactory; import org.drools.SystemEventListener; import org.drools.io.ResourceFactory; import org.drools.runtime.StatefulKnowledgeSession; public class KnowledgeAgentDisposeTest extends BaseKnowledgeAgentTest { private int resourceChangeNotificationCount = 0; public void testMonitorResourceChangeEvents() throws Exception { //create a basic dsl file this.fileManager.write("myExpander.dsl", this.createCommonDSL(null)); //create a basic dslr file this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); String xml = ""; xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'"; xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'"; xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >"; xml += " <add> "; xml += " <resource source='http://localhost:" + this.getPort() + "/rules.dslr' type='DSLR' />"; xml += " <resource source='http://localhost:" + this.getPort() + "/myExpander.dsl' type='DSL' />"; xml += " </add> "; xml += "</change-set>"; File fxml = fileManager.write( "changeset.xml", xml ); //Create a new Agent with newInstace=true KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); KnowledgeAgent kagent = this.createKAgent(kbase, false); //Agent: take care of them! this.applyChangeSet(kagent, ResourceFactory.newUrlResource(fxml.toURI().toURL())); resourceChangeNotificationCount = 0; //the dsl is now modified. this.fileManager.write("myExpander.dsl", this.createCommonDSL("name == \"John\"")); //the drl file is marked as modified too this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); this.scan(kagent); //two resources were modified, but only one change set is created assertEquals(1, resourceChangeNotificationCount); resourceChangeNotificationCount = 0; //let's add a new rule this.fileManager.write("rules.dslr", this.createCommonDSLRRule(new String[]{"Rule1","Rule2"})); this.scan(kagent); assertEquals(1, resourceChangeNotificationCount); resourceChangeNotificationCount = 0; //the kagent is stopped kagent.monitorResourceChangeEvents(false); //the dsrl file is marked as modified this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); try{ this.scan(kagent); fail("The agent didn't process any change set. This should be failed."); }catch (RuntimeException e){ assertEquals(e.getMessage(), "Event for KnowlegeBase update, due to scan, was never received"); } assertEquals(0, resourceChangeNotificationCount); //let start the agent again kagent.monitorResourceChangeEvents(true); //the dsrl file is marked as modified this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); this.scan(kagent); assertEquals(1, resourceChangeNotificationCount); kagent.monitorResourceChangeEvents(false); } public void testDispose() throws Exception { //create a basic dsl file this.fileManager.write("myExpander.dsl", this.createCommonDSL(null)); //create a basic dslr file this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); String xml = ""; xml += "<change-set xmlns='http://drools.org/drools-5.0/change-set'"; xml += " xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'"; xml += " xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >"; xml += " <add> "; xml += " <resource source='http://localhost:" + this.getPort() + "/rules.dslr' type='DSLR' />"; xml += " <resource source='http://localhost:" + this.getPort() + "/myExpander.dsl' type='DSL' />"; xml += " </add> "; xml += "</change-set>"; File fxml = fileManager.write( "changeset.xml", xml ); //Create a new Agent with newInstace=false KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); KnowledgeAgent kagent = this.createKAgent( kbase, false ); //Agent: take care of them! this.applyChangeSet(kagent,ResourceFactory.newUrlResource(fxml.toURI().toURL())); resourceChangeNotificationCount = 0; //the dsl is now modified. this.fileManager.write("myExpander.dsl", this.createCommonDSL("name == \"John\"")); //We also need to mark the dslr file as modified, so the rules could //be regenerated this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); this.scan(kagent); //two resources were modified, but only one change set is created assertEquals(1, resourceChangeNotificationCount); resourceChangeNotificationCount = 0; //let us create a new ksession and fire all the rules StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.setGlobal("list", new ArrayList<String>()); ksession.fireAllRules(); //let's add a new rule this.fileManager.write("rules.dslr", this.createCommonDSLRRule(new String[]{"Rule1","Rule2"})); this.scan(kagent); assertEquals(1, resourceChangeNotificationCount); resourceChangeNotificationCount = 0; //the old ksession can be reused ksession.fireAllRules(); //We will try to dispose the kagent: but an active stateful ksession exists. try{ kagent.dispose(); fail("The agent should failed"); } catch (IllegalStateException ex){ } //We need to dispose the ksession first ksession.dispose(); //Now it is safe to dispose the kagent kagent.dispose(); //the dsrl file is modified this.fileManager.write("rules.dslr", this.createCommonDSLRRule("Rule1")); try{ this.scan(kagent); fail("The agent didn't process any change set. This should be failed."); }catch (RuntimeException e){ assertEquals(e.getMessage(), "Event for KnowlegeBase update, due to scan, was never received"); } assertEquals(0, resourceChangeNotificationCount); } @Override public KnowledgeAgent createKAgent(KnowledgeBase kbase, boolean newInstance) { KnowledgeAgent kagent = super.createKAgent(kbase, newInstance); kagent.setSystemEventListener(new SystemEventListener() { public void info(String message) { } public void info(String message, Object object) { } public void warning(String message) { } public void warning(String message, Object object) { } public void exception(String message, Throwable e) { } public void exception(Throwable e) { } public void debug(String message) { if ("KnowledgeAgent received ChangeSet changed notification".equals(message)){ resourceChangeNotificationCount++; } } public void debug(String message, Object object) { } }); return kagent; } }