/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.runtime.pipeline.impl; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.TestCase; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLAssert; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; import org.drools.ChangeCollector; import org.drools.Cheese; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseFactory; import org.drools.KnowledgeBaseFactoryService; import org.drools.Person; import org.drools.TestVariable; import org.drools.builder.KnowledgeBuilder; import org.drools.builder.KnowledgeBuilderFactory; import org.drools.builder.KnowledgeBuilderFactoryService; import org.drools.builder.ResourceType; import org.drools.command.runtime.rule.ModifyCommand; import org.drools.common.InternalFactHandle; import org.drools.common.InternalRuleBase; import org.drools.definition.KnowledgePackage; import org.drools.grid.GridNode; import org.drools.grid.impl.GridImpl; import org.drools.grid.service.directory.WhitePages; import org.drools.grid.service.directory.impl.WhitePagesImpl; import org.drools.impl.StatefulKnowledgeSessionImpl; import org.drools.io.Resource; import org.drools.io.ResourceFactory; import org.drools.runtime.ExecutionResults; import org.drools.runtime.StatefulKnowledgeSession; import org.drools.runtime.StatelessKnowledgeSession; import org.drools.runtime.help.BatchExecutionHelper; import org.drools.runtime.pipeline.Action; import org.drools.runtime.pipeline.KnowledgeRuntimeCommand; import org.drools.runtime.pipeline.Pipeline; import org.drools.runtime.pipeline.PipelineFactory; import org.drools.runtime.pipeline.ResultHandler; import org.drools.runtime.pipeline.Transformer; import org.drools.runtime.process.ProcessInstance; import org.drools.runtime.process.WorkItem; import org.drools.runtime.process.WorkItemHandler; import org.drools.runtime.process.WorkItemManager; import org.drools.runtime.process.WorkflowProcessInstance; import org.drools.runtime.rule.FactHandle; import org.jbpm.process.core.context.variable.VariableScope; import org.jbpm.process.instance.context.variable.VariableScopeInstance; import org.xml.sax.SAXException; import com.thoughtworks.xstream.XStream; public class JSonBatchExecutionTest extends TestCase { protected void setUp() throws Exception { XMLUnit.setIgnoreComments( true ); XMLUnit.setIgnoreWhitespace( true ); XMLUnit.setIgnoreAttributeOrder( true ); XMLUnit.setNormalizeWhitespace( true ); XMLUnit.setNormalize( true ); } private void assertXMLEqual(String expectedXml, String resultXml) { try { Diff diff = new Diff( expectedXml, resultXml ); diff.overrideElementQualifier( new RecursiveElementNameAndTextQualifier() ); XMLAssert.assertXMLEqual( diff, true ); } catch ( Exception e ) { throw new RuntimeException( "XML Assertion failure", e ); } } public void testListenForChanges() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "import org.drools.ChangeCollector \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese(price==25) \n"; str += " \n"; str += " then \n"; str += "end\n"; str += "rule rule2 \n"; str += " when \n"; str += " p : Person(name=='mic') \n"; str += " c : Cheese(price != 42) \n"; str += " \n"; str += " then \n"; str += " c.setPrice( 42 ); \n"; str += " update(c); \n"; str += "end\n"; str += "rule rule3 \n"; str += " when \n"; str += " p : Person(name=='mark') \n"; str += " c : Cheese(price == 42) \n"; str += " \n"; str += " then \n"; str += " retract(c); \n"; str += "end\n"; str += "rule ruleBootStrap \n"; str += "salience 10000\n"; str += " when \n"; str += " $c : ChangeCollector() \n"; str += " \n"; str += " then \n"; str += " kcontext.getKnowledgeRuntime().addEventListener($c); \n"; str += "end\n"; str += "rule ruleCleanup \n"; str += "salience -10000\n"; str += " when \n"; str += " $c : ChangeCollector() \n"; str += " \n"; str += " then \n"; str += " kcontext.getKnowledgeRuntime().removeEventListener($c); \n"; str += " retract($c); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"insert\":{\"object\":{\"org.drools.Person\":{\"name\":\"mic\"} }, \"out-identifier\":\"person\" } }"; inXml += ", {\"insert\":{\"object\":{\"org.drools.ChangeCollector\":{} }, \"out-identifier\":\"changes\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); ChangeCollector collector = ( ChangeCollector ) result.getValue( "changes" ); Cheese c = ( Cheese ) collector.getChanges().get( 0 ); assertEquals( 42, c.getPrice() ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"insert\":{\"object\":{\"org.drools.Person\":{\"name\":\"mark\"} }, \"out-identifier\":\"person\" } }"; inXml += ", {\"insert\":{\"object\":{\"org.drools.ChangeCollector\":{} }, \"out-identifier\":\"changes\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); collector = ( ChangeCollector ) result.getValue( "changes" ); assertEquals( "stilton", collector.getRetracted().get( 0 ) ); } public void testInsertWithDefaults() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); Cheese stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); FactHandle factHandle = (FactHandle) result.getFactHandle( "outStilton" ); stilton = (Cheese) ksession.getObject( factHandle ); assertEquals( 30, stilton.getPrice() ); // String expectedXml = ""; // expectedXml = "{\"execution-results\":{\"results\":{\"outStilton\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"oldPrice\":0,\"price\":30}}},\"fact-handles\":{\"outStilton\":\"" + ((InternalFactHandle) result.getFactHandle( "outStilton" )).toExternalForm() + "\"}}}"; // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"outStilton\">\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handle identifier=\"outStilton\" externalForm=\"" + ((InternalFactHandle) result.getFactHandle( "outStilton" )).toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); // JSONAssert.assertEquals( expectedXml, outXml ); } public void testInsertWithReturnObjectFalse() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"return-object\":false, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject ( result ); assertNull( result.getValue( "outStilton" ) ); FactHandle factHandle = (FactHandle) result.getFactHandle( "outStilton" ); Cheese stilton = (Cheese) ksession.getObject( factHandle ); assertEquals( 30, stilton.getPrice() ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <fact-handle identifier=\"outStilton\" externalForm=\"" + ((InternalFactHandle) result.getFactHandle( "outStilton" )).toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } public void testGetObject() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":{\"max\":10}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults) roundTripFromObject( result ); Cheese stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); FactHandle factHandle = (FactHandle) result.getFactHandle( "outStilton" ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"get-object\":{ "; inXml += " \"out-identifier\":'outStilton',"; inXml += " \"fact-handle\":'" + factHandle.toExternalForm() + "'}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults) roundTripFromObject( result ); stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); } public void testRetractObject() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":{\"max\":10}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults) roundTripFromObject( result ); Cheese stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); FactHandle factHandle = (FactHandle) result.getFactHandle( "outStilton" ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " { \"retract\":{\"fact-handle\":'" + factHandle.toExternalForm() + "'}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"get-object\":{ "; inXml += " \"out-identifier\":'outStilton',"; inXml += " \"fact-handle\":'" + factHandle.toExternalForm() + "'}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults) roundTripFromObject( result ); assertNull( result.getValue( "outStilton" ) ); } public void testModifyObject() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); Cheese stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); FactHandle factHandle = ((FactHandle) result.getFactHandle( "outStilton" )); // // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"outStilton\">\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handle identifier=\"outStilton\" externalForm=\"" + factHandle.toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"modify\":{\"fact-handle\":'" + factHandle.toExternalForm() + "'"; inXml += ", \"setters\":[{\"accessor\":\"oldPrice\",\"set\":42}, {\"accessor\":\"price\",\"set\":50}]"; inXml += "} }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"get-object\":{ "; inXml += " \"out-identifier\":'outCheddar',"; inXml += " \"fact-handle\":'" + factHandle.toExternalForm() + "'}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject ( result ); Cheese cheddar = (Cheese) result.getValue( "outCheddar" ); assertEquals( 42, cheddar.getOldPrice() ); assertEquals( 55, cheddar.getPrice() ); //now test for code injection: ModifyCommand.ALLOW_MODIFY_EXPRESSIONS = false; inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"modify\":{\"fact-handle\":'" + factHandle.toExternalForm() + "'"; inXml += ", \"setters\":[{\"accessor\":\"type\",\"set\":\"44; System.exit(1);\"}, {\"accessor\":\"price\",\"set\":50}]"; inXml += "} }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); ModifyCommand.ALLOW_MODIFY_EXPRESSIONS = true; } public void testInsertElements() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += " list1.add( $c );"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"set-global\":{\"identifier\":\"list1\",\"out\"=true"; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += " } } "; // inXml += ", {\"insert-elements\":{\"objects\":["; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":30,\"oldPrice\":0}} "; inXml += " ]}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatelessKnowledgeSession ksession = getSession2( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier='list'>\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>35</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); // ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); List list = (List) result.getValue( "list1" ); Cheese stilton25 = new Cheese( "stilton", 30 ); Cheese stilton30 = new Cheese( "stilton", 35 ); Set expectedList = new HashSet(); expectedList.add( stilton25 ); expectedList.add( stilton30 ); assertEquals( expectedList, new HashSet( list ) ); } public void testFactHandleReturn() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " System.err.println(42); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"get-global\":{\"identifier\":\"list1\",\"out-identifier\":\"out-list\"}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); FactHandle fh = ksession.insert( new Person( "mic", 42 ) ); List<FactHandle> list = new ArrayList<FactHandle>(); list.add( fh ); ksession.setGlobal( "list1", list ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); List outList = ( List ) result.getValue( "out-list" ); assertEquals( 1, outList.size() ); assertEquals( fh.toExternalForm(), ((FactHandle)outList.get(0)).toExternalForm() ); assertNotSame( fh, outList.get( 0 )); // System.err.println( outXml ); // String expectedXml = ""; // expectedXml += "<execution-results>\n" + " <result identifier=\"out-list\">\n" + " <list>\n" + " <fact-handle externalForm=\"" + fh.toExternalForm() + "\"/>\n" + " </list>\n" + " </result>\n" + "</execution-results>"; // // assertXMLEqual( expectedXml, // outXml ); } public void testInsertElementsWithReturnObjects() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += " list1.add( $c );"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"set-global\":{\"identifier\":\"list1\",\"out\"=true"; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += " } } "; // inXml += ", {\"insert-elements\":{\"out-identifier\":\"myfacts\",\"return-objects\":true,\"objects\":["; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":30,\"oldPrice\":0}} "; inXml += " ]}}"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults) roundTripFromObject( result ); List list1 = ( List ) result.getValue( "list1" ); assertEquals( 2, list1.size() ); assertTrue( list1.contains( new Cheese("stilton", 35) ) ); assertTrue( list1.contains( new Cheese("stilton", 30) ) ); List myFacts = ( List ) result.getValue( "myfacts" ); assertEquals( 2, list1.size() ); assertTrue( myFacts.contains( new Cheese("stilton", 35) ) ); assertTrue( myFacts.contains( new Cheese("stilton", 30) ) ); List factHandles = ( List ) result.getFactHandle( "myfacts" ); List list = new ArrayList(); list.add( ksession.getObject( ((InternalFactHandle)factHandles.get( 0 )) ) ); list.add( ksession.getObject( ((InternalFactHandle)factHandles.get( 1 )) ) ); assertTrue( list.contains( new Cheese("stilton", 35) ) ); assertTrue( list.contains( new Cheese("stilton", 30) ) ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier='list'>\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>35</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // // expectedXml += " <result identifier=\"myfacts\">\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese reference=\"../../../result/list/org.drools.Cheese[2]\"/>\n"; // expectedXml += " <org.drools.Cheese reference=\"../../../result/list/org.drools.Cheese\"/>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handles identifier=\"myfacts\">\n"; // for ( FactHandle factHandle : factHandles ) { // if ( ((Cheese) ksession.getObject( factHandle )).getPrice() == 30 ) { // expectedXml += " <fact-handle externalForm=\"" + factHandle.toExternalForm() + "\"/>\n"; // } // } // // for ( FactHandle factHandle : factHandles ) { // if ( ((Cheese) ksession.getObject( factHandle )).getPrice() == 35 ) { // expectedXml += " <fact-handle externalForm=\"" + factHandle.toExternalForm() + "\"/>\n"; // } // } // expectedXml += " </fact-handles>\n"; // // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } public void testSetGlobal() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "global java.util.List list2 \n"; str += "global java.util.List list3 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( 30 ); \n"; str += " list1.add( $c ); \n"; str += " list2.add( $c ); \n"; str += " list3.add( $c ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"set-global\":{\"identifier\":\"list1\""; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += "} } "; inXml += ", {\"set-global\":{\"identifier\":\"list2\",\"out\"=true"; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += "} } "; inXml += ", {\"set-global\":{\"identifier\":\"list3\",\"out-identifier\"=\"outList3\""; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += "} } "; inXml += ", {\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":5}}, \"out-identifier\":\"outStilton\" } }"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatelessKnowledgeSession ksession = getSession2( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier='list2'>\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += " <result identifier='outList3'>\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese reference='../../../result/list/org.drools.Cheese'/>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); // ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); Cheese stilton = new Cheese( "stilton", 30 ); assertNull( result.getValue( "list1" ) ); List list2 = (List) result.getValue( "list2" ); assertEquals( 1, list2.size() ); assertEquals( stilton, list2.get( 0 ) ); List list3 = (List) result.getValue( "outList3" ); assertEquals( 1, list3.size() ); assertEquals( stilton, list3.get( 0 ) ); } public void testGetGlobal() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " list1.add( $c ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"set-global\":{\"identifier\":\"list1\",\"out\"=true"; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += " } } "; // inXml += ", {\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"get-global\":{\"identifier\":\"list1\",\"out-identifier\"=\"out-list\"}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatelessKnowledgeSession ksession = getSession2( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); List resultsList = ( List ) result.getValue("out-list"); assertEquals(1, resultsList.size() ); assertEquals(new Cheese("stilton",25), resultsList.get(0)); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"out-list\">\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>25</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } public void testGetObjects() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml =""; inXml = "{\"batch-execution\":{\"commands\":["; inXml += " {\"insert-elements\":{\"objects\":["; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":30,\"oldPrice\":0}} "; inXml += " ]}}"; inXml += ", {\"get-objects\":{\"out-identifier\":\"list1\"}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatelessKnowledgeSession ksession = getSession2( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); // String expectedXml = ""; // expectedXml += "<execution-results>"; // expectedXml += " <result identifier='list'>"; // expectedXml += " <list>"; // expectedXml += " <org.drools.Cheese>"; // expectedXml += " <type>stilton</type>"; // expectedXml += " <price>30</price>"; // expectedXml += " <oldPrice>0</oldPrice>"; // expectedXml += " </org.drools.Cheese>"; // expectedXml += " <org.drools.Cheese>"; // expectedXml += " <type>stilton</type>"; // expectedXml += " <price>35</price>"; // expectedXml += " <oldPrice>0</oldPrice>"; // expectedXml += " </org.drools.Cheese>"; // expectedXml += " </list>"; // expectedXml += " </result>"; // expectedXml += "</execution-results>"; // // assertXMLEqual( expectedXml, // outXml ); // ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = ( ExecutionResults ) roundTripFromObject( result ); List list = (List) result.getValue( "list1" ); Cheese stilton25 = new Cheese( "stilton", 30 ); Cheese stilton30 = new Cheese( "stilton", 35 ); Set expectedList = new HashSet(); expectedList.add( stilton25 ); expectedList.add( stilton30 ); assertEquals( expectedList, new HashSet( list ) ); } public void testQuery() throws Exception { String str = ""; str += "package org.drools.test \n"; str += "import org.drools.Cheese \n"; str += "query cheeses \n"; str += " stilton : Cheese(type == 'stilton') \n"; str += " cheddar : Cheese(type == 'cheddar', price == stilton.price) \n"; str += "end\n"; str += "query cheesesWithParams(String a, String b) \n"; str += " stilton : Cheese(type == a) \n"; str += " cheddar : Cheese(type == b, price == stilton.price) \n"; str += "end\n"; String inXml =""; inXml = "{\"batch-execution\":{\"commands\":["; inXml += " {\"insert-elements\":{\"objects\":["; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":2}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"cheddar\",\"price\":1}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"cheddar\",\"price\":2}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":1}} "; inXml += " ]}}"; inXml += ", {\"query\":{\"out-identifier\":\"cheeses\",\"name\":\"cheeses\"}}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); // Iterator<QueryResultsRow> it1 = ksession.getQueryResults( "cheeses" ).iterator(); // Iterator<QueryResultsRow> it2 = ksession.getQueryResults( "cheesesWithParams", // new String[]{"stilton", "cheddar"} ).iterator(); // QueryResultsRow row = null; // // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier='cheeses'>\n"; // expectedXml += " <query-results>\n"; // expectedXml += " <identifiers>\n"; // expectedXml += " <identifier>stilton</identifier>\n"; // expectedXml += " <identifier>cheddar</identifier>\n"; // expectedXml += " </identifiers>\n"; // expectedXml += " <row>\n"; // row = it1.next(); // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>1</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "stilton" ).toExternalForm() + "' />"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>cheddar</type>\n"; // expectedXml += " <price>1</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "cheddar" ).toExternalForm() + "' />"; // expectedXml += " </row>\n"; // expectedXml += " <row>\n"; // row = it1.next(); // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>2</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "stilton" ).toExternalForm() + "' />"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>cheddar</type>\n"; // expectedXml += " <price>2</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "cheddar" ).toExternalForm() + "' />"; // expectedXml += " </row>\n"; // expectedXml += " </query-results>\n"; // expectedXml += " </result>\n"; // expectedXml += " <result identifier='cheeses2'>\n"; // expectedXml += " <query-results>\n"; // expectedXml += " <identifiers>\n"; // expectedXml += " <identifier>stilton</identifier>\n"; // expectedXml += " <identifier>cheddar</identifier>\n"; // expectedXml += " </identifiers>\n"; // expectedXml += " <row>\n"; // row = it2.next(); // expectedXml += " <org.drools.Cheese reference=\"../../../../result/query-results/row/org.drools.Cheese\"/>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "stilton" ).toExternalForm() + "' />"; // expectedXml += " <org.drools.Cheese reference=\"../../../../result/query-results/row/org.drools.Cheese[2]\"/>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "cheddar" ).toExternalForm() + "' />"; // expectedXml += " </row>\n"; // expectedXml += " <row>\n"; // row = it2.next(); // expectedXml += " <org.drools.Cheese reference=\"../../../../result/query-results/row[2]/org.drools.Cheese\"/>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "stilton" ).toExternalForm() + "' />"; // expectedXml += " <org.drools.Cheese reference=\"../../../../result/query-results/row[2]/org.drools.Cheese[2]\"/>\n"; // expectedXml += " <fact-handle externalForm='" + row.getFactHandle( "cheddar" ).toExternalForm() + "' />"; // expectedXml += " </row>\n"; // expectedXml += " </query-results>\n"; // expectedXml += " </result>\n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); // ExecutionResults batchResult = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); batchResult = ( ExecutionResults ) roundTripFromObject( batchResult ); Cheese stilton1 = new Cheese( "stilton", 1 ); Cheese cheddar1 = new Cheese( "cheddar", 1 ); Cheese stilton2 = new Cheese( "stilton", 2 ); Cheese cheddar2 = new Cheese( "cheddar", 2 ); Set set = new HashSet(); List list = new ArrayList(); list.add( stilton1 ); list.add( cheddar1 ); set.add( list ); list = new ArrayList(); list.add( stilton2 ); list.add( cheddar2 ); set.add( list ); org.drools.runtime.rule.QueryResults results = (org.drools.runtime.rule.QueryResults) batchResult.getValue( "cheeses" ); assertEquals( 2, results.size() ); assertEquals( 2, results.getIdentifiers().length ); Set newSet = new HashSet(); for ( org.drools.runtime.rule.QueryResultsRow result : results ) { list = new ArrayList(); list.add( result.get( "stilton" ) ); list.add( result.get( "cheddar" ) ); newSet.add( list ); } assertEquals( set, newSet ); } public void testManualFireAllRules() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "global java.util.List list1 \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += " list1.add( $c );"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"set-global\":{\"identifier\":\"list1\",\"out\"=true"; inXml += " ,\"object\":{\"list\":{\"object\":[]}}"; inXml += " } } "; // inXml += ", {\"insert-elements\":{\"objects\":["; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, "; inXml += " { \"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":30,\"oldPrice\":0}} "; inXml += " ]}}"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += ", {\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"brie\",\"price\":10,\"oldPrice\":0}}, \"out-identifier\":\"outBrie\" } }"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); StatelessKnowledgeSession ksession = getSession2( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); FactHandle factHandle = (FactHandle) ((ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml )).getFactHandle( "outBrie" ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier='list'>\n"; // expectedXml += " <list>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>35</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += " <result identifier='outBrie'>\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>brie</type>\n"; // expectedXml += " <price>10</price>\n"; // expectedXml += " <oldPrice>5</oldPrice>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handle identifier=\"outBrie\" externalForm=\"" + factHandle.toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // assertXMLEqual( expectedXml, // outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = (ExecutionResults) roundTripFromObject( result ); // brie should not have been added to the list List list = (List) result.getValue( "list1" ); Cheese stilton25 = new Cheese( "stilton", 30 ); Cheese stilton30 = new Cheese( "stilton", 35 ); Set expectedList = new HashSet(); expectedList.add( stilton25 ); expectedList.add( stilton30 ); assertEquals( expectedList, new HashSet( list ) ); // brie should not have changed Cheese brie10 = new Cheese( "brie", 10 ); brie10.setOldPrice( 5 ); assertEquals( brie10, result.getValue( "outBrie" ) ); } public void testProcess() throws SAXException, IOException { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); String str = ""; str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; str += "<process xmlns=\"http://drools.org/drools-5.0/process\"\n"; str += " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; str += " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n"; str += " type=\"RuleFlow\" name=\"flow\" id=\"org.drools.actions\" package-name=\"org.drools\" version=\"1\" >\n"; str += "\n"; str += " <header>\n"; str += " <imports>\n"; str += " <import name=\"org.drools.TestVariable\" />\n"; str += " </imports>\n"; str += " <globals>\n"; str += " <global identifier=\"list1\" type=\"java.util.List\" />\n"; str += " </globals>\n"; str += " <variables>\n"; str += " <variable name=\"person\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"TestVariable\" />\n"; str += " </variable>\n"; str += " </variables>\n"; str += " </header>\n"; str += "\n"; str += " <nodes>\n"; str += " <start id=\"1\" name=\"Start\" />\n"; str += " <actionNode id=\"2\" name=\"MyActionNode\" >\n"; str += " <action type=\"expression\" dialect=\"mvel\" >System.out.println(\"Triggered\");\n"; str += "list1.add(person.name);\n"; str += "</action>\n"; str += " </actionNode>\n"; str += " <end id=\"3\" name=\"End\" />\n"; str += " </nodes>\n"; str += "\n"; str += " <connections>\n"; str += " <connection from=\"1\" to=\"2\" />\n"; str += " <connection from=\"2\" to=\"3\" />\n"; str += " </connections>\n" + "\n"; str += "</process>"; Reader source = new StringReader( str ); kbuilder.add( ResourceFactory.newReaderResource( source ), ResourceType.DRF ); if ( kbuilder.hasErrors() ) { fail( kbuilder.getErrors().toString() ); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list1", list ); TestVariable person = new TestVariable( "John Doe" ); String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"start-process\":"; inXml += " {\"process-id\":\"org.drools.actions\","; inXml += " \"parameters\":["; inXml += " {\"identifier\":\"person\","; inXml += " \"object\":{\"@class\":\"org.drools.TestVariable\","; inXml += " \"name\":\"John Doe\"}}]}},"; inXml += " {\"get-global\":{\"identifier\":\"list1\",\"out-identifier\":\"out-list\"}}]}}"; inXml = roundTripFromXml( inXml ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipeline( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); outXml = roundTripFromXml( outXml ); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); result = (ExecutionResults) roundTripFromObject( result ); list = (List) result.getValue( "out-list" ); assertEquals( 1, list.size() ); assertEquals( "John Doe", list.get( 0 ) ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"out-list\">\n"; // expectedXml += " <list>\n"; // expectedXml += " <string>John Doe</string>\n"; // expectedXml += " </list>\n"; // expectedXml += " </result>\n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } public void testProcessInstanceSignalEvent() throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); String str = ""; str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; str += "<process xmlns=\"http://drools.org/drools-5.0/process\"\n"; str += " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; str += " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n"; str += " type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n"; str += "\n"; str += " <header>\n"; str += " <variables>\n"; str += " <variable name=\"MyVar\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>SomeText</value>\n"; str += " </variable>\n"; str += " </variables>\n"; str += " </header>\n"; str += "\n"; str += " <nodes>\n"; str += " <start id=\"1\" name=\"Start\" />\n"; str += " <eventNode id=\"2\" name=\"Event\" variableName=\"MyVar\" >\n"; str += " <eventFilters>\n"; str += " <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n"; str += " </eventFilters>\n"; str += " </eventNode>\n"; str += " <join id=\"3\" name=\"Join\" type=\"1\" />\n"; str += " <end id=\"4\" name=\"End\" />\n"; str += " </nodes>\n"; str += "\n"; str += " <connections>\n"; str += " <connection from=\"1\" to=\"3\" />\n"; str += " <connection from=\"2\" to=\"3\" />\n"; str += " <connection from=\"3\" to=\"4\" />\n"; str += " </connections>\n"; str += "\n"; str += "</process>"; kbuilder.add( ResourceFactory.newByteArrayResource( str.getBytes() ), ResourceType.DRF ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ProcessInstance processInstance = ksession.startProcess( "org.drools.event" ); assertEquals( ProcessInstance.STATE_ACTIVE, processInstance.getState() ); String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"signal-event\":{\"process-instance-id\":" + processInstance.getId() +",\"event-type\":\"MyEvent\""; inXml += " ,\"object\":{\"string\":[\"MyValue\"]} } }"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, new ResultHandlerImpl() ); assertEquals( ProcessInstance.STATE_COMPLETED, processInstance.getState() ); assertEquals( "MyValue", ((VariableScopeInstance) ((org.jbpm.process.instance.ProcessInstance) processInstance).getContextInstance( VariableScope.VARIABLE_SCOPE )).getVariable( "MyVar" ) ); } public void testProcessRuntimeSignalEvent() throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); String str = ""; str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; str += "<process xmlns=\"http://drools.org/drools-5.0/process\"\n"; str += " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; str += " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n"; str += " type=\"RuleFlow\" name=\"flow\" id=\"org.drools.event\" package-name=\"org.drools\" version=\"1\" >\n"; str += "\n"; str += " <header>\n"; str += " <variables>\n"; str += " <variable name=\"MyVar\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>SomeText</value>\n"; str += " </variable>\n"; str += " </variables>\n"; str += " </header>\n"; str += "\n"; str += " <nodes>\n"; str += " <start id=\"1\" name=\"Start\" />\n"; str += " <eventNode id=\"2\" name=\"Event\" scope=\"external\" variableName=\"MyVar\" >\n"; str += " <eventFilters>\n"; str += " <eventFilter type=\"eventType\" eventType=\"MyEvent\" />\n"; str += " </eventFilters>\n"; str += " </eventNode>\n"; str += " <join id=\"3\" name=\"Join\" type=\"1\" />\n"; str += " <end id=\"4\" name=\"End\" />\n"; str += " </nodes>\n"; str += "\n"; str += " <connections>\n"; str += " <connection from=\"1\" to=\"3\" />\n"; str += " <connection from=\"2\" to=\"3\" />\n"; str += " <connection from=\"3\" to=\"4\" />\n"; str += " </connections>\n"; str += "\n"; str += "</process>"; kbuilder.add( ResourceFactory.newByteArrayResource( str.getBytes() ), ResourceType.DRF ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ProcessInstance processInstance = ksession.startProcess( "org.drools.event" ); assertEquals( ProcessInstance.STATE_ACTIVE, processInstance.getState() ); String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += " {\"signal-event\":{\"event-type\":\"MyEvent\""; inXml += " ,\"object\":{\"string\":[\"MyValue\"]} } }"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, new ResultHandlerImpl() ); assertEquals( ProcessInstance.STATE_COMPLETED, processInstance.getState() ); assertEquals( "MyValue", ((VariableScopeInstance) ((org.jbpm.process.instance.ProcessInstance) processInstance).getContextInstance( VariableScope.VARIABLE_SCOPE )).getVariable( "MyVar" ) ); } public void testCompleteWorkItem() { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); String str = ""; str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; str += "<process xmlns=\"http://drools.org/drools-5.0/process\"\n"; str += " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; str += " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n"; str += " type=\"RuleFlow\" name=\"flow\" id=\"org.drools.actions\" package-name=\"org.drools\" version=\"1\" >\n"; str += "\n"; str += " <header>\n"; str += " <variables>\n"; str += " <variable name=\"UserName\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>John Doe</value>\n"; str += " </variable>\n"; str += " <variable name=\"Person\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"org.drools.Person\" />\n"; str += " </variable>\n"; str += " <variable name=\"MyObject\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"java.lang.Object\" />\n"; str += " </variable>\n"; str += " <variable name=\"Number\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.IntegerDataType\" />\n"; str += " </variable>\n"; str += " </variables>\n"; str += " </header>\n"; str += "\n"; str += " <nodes>\n"; str += " <start id=\"1\" name=\"Start\" />\n"; str += " <workItem id=\"2\" name=\"HumanTask\" >\n"; str += " <work name=\"Human Task\" >\n"; str += " <parameter name=\"ActorId\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>#{UserName}</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"Content\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>#{Person.name}</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"TaskName\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>Do something</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"Priority\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " </parameter>\n"; str += " <parameter name=\"Comment\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " </parameter>\n"; str += " <parameter name=\"Attachment\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"java.lang.Object\" />\n"; str += " </parameter>\n"; str += " </work>\n"; str += " <mapping type=\"in\" from=\"MyObject\" to=\"Attachment\" />"; str += " <mapping type=\"in\" from=\"Person.name\" to=\"Comment\" />"; str += " <mapping type=\"out\" from=\"Result\" to=\"MyObject\" />"; str += " <mapping type=\"out\" from=\"Result.length()\" to=\"Number\" />"; str += " </workItem>\n"; str += " <end id=\"3\" name=\"End\" />\n"; str += " </nodes>\n"; str += "\n"; str += " <connections>\n"; str += " <connection from=\"1\" to=\"2\" />\n"; str += " <connection from=\"2\" to=\"3\" />\n"; str += " </connections>\n"; str += "\n"; str += "</process>"; Reader source = new StringReader( str ); kbuilder.add( ResourceFactory.newReaderResource( source ), ResourceType.DRF ); Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kpkgs ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler( "Human Task", handler ); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put( "UserName", "John Doe" ); Person person = new Person(); person.setName( "John Doe" ); parameters.put( "Person", person ); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.startProcess( "org.drools.actions", parameters ); assertEquals( ProcessInstance.STATE_ACTIVE, processInstance.getState() ); WorkItem workItem = handler.getWorkItem(); assertNotNull( workItem ); assertEquals( "John Doe", workItem.getParameter( "ActorId" ) ); assertEquals( "John Doe", workItem.getParameter( "Content" ) ); assertEquals( "John Doe", workItem.getParameter( "Comment" ) ); assertEquals( WorkItem.PENDING, workItem.getState() ); String inXml = ""; inXml = "{\"complete-work-item\":{\"id\":" + workItem.getId() + "}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, new ResultHandlerImpl() ); assertEquals( WorkItem.COMPLETED, workItem.getState() ); assertEquals( ProcessInstance.STATE_COMPLETED, processInstance.getState() ); parameters = new HashMap<String, Object>(); parameters.put( "UserName", "Jane Doe" ); parameters.put( "MyObject", "SomeString" ); person = new Person(); person.setName( "Jane Doe" ); parameters.put( "Person", person ); processInstance = (WorkflowProcessInstance) ksession.startProcess( "org.drools.actions", parameters ); assertEquals( ProcessInstance.STATE_ACTIVE, processInstance.getState() ); workItem = handler.getWorkItem(); assertNotNull( workItem ); assertEquals( "Jane Doe", workItem.getParameter( "ActorId" ) ); assertEquals( "SomeString", workItem.getParameter( "Attachment" ) ); assertEquals( "Jane Doe", workItem.getParameter( "Content" ) ); assertEquals( "Jane Doe", workItem.getParameter( "Comment" ) ); assertEquals( WorkItem.PENDING, workItem.getState() ); inXml = "{\"complete-work-item\":{\"id\":" + workItem.getId() + ",\"results\":{\"identifier\":\"Result\",\"object\":{\"@class\":\"string\",\"$\":\"SomeOtherString\"}}}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, new ResultHandlerImpl() ); assertEquals( WorkItem.COMPLETED, workItem.getState() ); assertEquals( ProcessInstance.STATE_COMPLETED, processInstance.getState() ); assertEquals( "SomeOtherString", processInstance.getVariable( "MyObject" ) ); assertEquals( 15, processInstance.getVariable( "Number" ) ); } public void testAbortWorkItem() { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); String str = ""; str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; str += "<process xmlns=\"http://drools.org/drools-5.0/process\"\n"; str += " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; str += " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n"; str += " type=\"RuleFlow\" name=\"flow\" id=\"org.drools.actions\" package-name=\"org.drools\" version=\"1\" >\n"; str += "\n"; str += " <header>\n"; str += " <variables>\n"; str += " <variable name=\"UserName\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>John Doe</value>\n"; str += " </variable>\n"; str += " <variable name=\"Person\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"org.drools.Person\" />\n"; str += " </variable>\n"; str += " <variable name=\"MyObject\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"java.lang.Object\" />\n"; str += " </variable>\n"; str += " <variable name=\"Number\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.IntegerDataType\" />\n"; str += " </variable>\n"; str += " </variables>\n"; str += " </header>\n"; str += "\n"; str += " <nodes>\n"; str += " <start id=\"1\" name=\"Start\" />\n"; str += " <workItem id=\"2\" name=\"HumanTask\" >\n"; str += " <work name=\"Human Task\" >\n"; str += " <parameter name=\"ActorId\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>#{UserName}</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"Content\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>#{Person.name}</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"TaskName\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " <value>Do something</value>\n"; str += " </parameter>\n"; str += " <parameter name=\"Priority\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " </parameter>\n"; str += " <parameter name=\"Comment\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.StringDataType\" />\n"; str += " </parameter>\n"; str += " <parameter name=\"Attachment\" >\n"; str += " <type name=\"org.drools.process.core.datatype.impl.type.ObjectDataType\" className=\"java.lang.Object\" />\n"; str += " </parameter>\n"; str += " </work>\n"; str += " <mapping type=\"in\" from=\"MyObject\" to=\"Attachment\" />"; str += " <mapping type=\"in\" from=\"Person.name\" to=\"Comment\" />"; str += " <mapping type=\"out\" from=\"Result\" to=\"MyObject\" />"; str += " <mapping type=\"out\" from=\"Result.length()\" to=\"Number\" />"; str += " </workItem>\n"; str += " <end id=\"3\" name=\"End\" />\n"; str += " </nodes>\n"; str += "\n"; str += " <connections>\n"; str += " <connection from=\"1\" to=\"2\" />\n"; str += " <connection from=\"2\" to=\"3\" />\n"; str += " </connections>\n"; str += "\n"; str += "</process>"; Reader source = new StringReader( str ); kbuilder.add( ResourceFactory.newReaderResource( source ), ResourceType.DRF ); Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kpkgs ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler( "Human Task", handler ); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put( "UserName", "John Doe" ); Person person = new Person(); person.setName( "John Doe" ); parameters.put( "Person", person ); WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.startProcess( "org.drools.actions", parameters ); assertEquals( ProcessInstance.STATE_ACTIVE, processInstance.getState() ); WorkItem workItem = handler.getWorkItem(); assertNotNull( workItem ); assertEquals( WorkItem.PENDING, workItem.getState() ); String inXml = "{\"abort-work-item\":{\"id\":" + workItem.getId() + "}}"; inXml = roundTripFromXml( inXml ); getPipelineStateful( ksession ).insert( inXml, new ResultHandlerImpl() ); assertEquals( WorkItem.ABORTED, workItem.getState() ); } public static class TestWorkItemHandler implements WorkItemHandler { private WorkItem workItem; public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { this.workItem = workItem; } public void abortWorkItem(WorkItem workItem, WorkItemManager manager) { } public WorkItem getWorkItem() { return workItem; } } public void testInsertObjectWithDeclaredFact() throws Exception { String str = ""; str += "package org.foo \n"; str += "declare Whee \n\ttype: String\n\tprice: Integer\n\toldPrice: Integer\nend\n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Whee() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.foo.Whee\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; //inXml = roundTripFromXml( inXml ); // can't round trip, as dosn't have the correct class loader StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); ClassLoader cl = ((InternalRuleBase) ((StatefulKnowledgeSessionImpl) ksession).getRuleBase()).getRootClassLoader(); XStream xstream = BatchExecutionHelper.newJSonMarshaller(); xstream.setClassLoader( cl ); FactHandle factHandle = (FactHandle) ((ExecutionResults) xstream.fromXML( outXml )).getFactHandle( "outStilton" ); assertNotNull( factHandle ); Object object = ((ExecutionResults) xstream.fromXML( outXml )).getValue( "outStilton" ); assertEquals( "org.foo.Whee", object.getClass().getName() ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"outStilton\">\n"; // expectedXml += " <org.foo.Whee>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " </org.foo.Whee>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handle identifier=\"outStilton\" externalForm=\"" + factHandle.toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } public void testInsertObjectStateful() throws Exception { String str = ""; str += "package org.foo \n"; str += "declare Whee \n\ttype: String\n\tprice: Integer\n\toldPrice: Integer\nend\n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Whee(price < 30) \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n update($c);\n"; str += "end\n"; str += "query results\n"; str += " w: Whee(price > 0)"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.foo.Whee\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}} } }"; inXml += "]}}"; //inXml = roundTripFromXml( inXml ); // can't round trip, as dosn't have the correct class loader StatefulKnowledgeSession ksession = getSessionStateful( ResourceFactory.newByteArrayResource( str.getBytes() ) ); ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineStateful( ksession ).insert( inXml, resultHandler ); inXml = "{\"batch-execution\":{\"commands\":["; inXml += " {\"query\":{\"out-identifier\":\"matchingthings\",\"name\":\"results\"}}"; inXml += "]}}"; getPipelineStateful( ksession ).insert( inXml, resultHandler ); String outXml = (String) resultHandler.getObject(); //we have not fired the rules yet assertTrue( outXml.indexOf( "\"price\":25" ) >= 0 ); getPipelineStateful( ksession ).insert( "{\"fire-all-rules\":\"\"}", resultHandler ); //ok lets try that again... inXml = "{\"batch-execution\":{\"commands\":["; inXml += " {\"query\":{\"out-identifier\":\"matchingthings\",\"name\":\"results\"}}"; inXml += "]}}"; getPipelineStateful( ksession ).insert( inXml, resultHandler ); outXml = (String) resultHandler.getObject(); assertTrue( outXml.indexOf( "\"price\":30" ) >= 0 ); } public void testVsmPipeline() throws Exception { String str = ""; str += "package org.drools \n"; str += "import org.drools.Cheese \n"; str += "rule rule1 \n"; str += " when \n"; str += " $c : Cheese() \n"; str += " \n"; str += " then \n"; str += " $c.setPrice( $c.getPrice() + 5 ); \n"; str += "end\n"; String inXml = ""; inXml += "{\"batch-execution\":{\"lookup\":\"ksession1\", \"commands\":["; inXml += "{\"insert\":{\"object\":{\"org.drools.Cheese\":{\"type\":\"stilton\",\"price\":25,\"oldPrice\":0}}, \"out-identifier\":\"outStilton\" } }"; inXml += ", {\"fire-all-rules\":\"\"}"; inXml += "]}}"; inXml = roundTripFromXml( inXml ); GridImpl grid = new GridImpl( new HashMap() ); grid.addService( WhitePages.class, new WhitePagesImpl() ); GridNode node = grid.createGridNode( "local" ); StatefulKnowledgeSession ksession = getExecutionNodeSessionStateful(node, ResourceFactory.newByteArrayResource( str.getBytes() ) ); node.set( "ksession1", ksession ); XStreamResolverStrategy xstreamStrategy = new XStreamResolverStrategy() { public XStream lookup(String name) { return BatchExecutionHelper.newJSonMarshaller(); } }; ResultHandlerImpl resultHandler = new ResultHandlerImpl(); getPipelineSessionStateful(node, xstreamStrategy).insert(inXml, resultHandler); String outXml = (String) resultHandler.getObject(); ExecutionResults result = (ExecutionResults) BatchExecutionHelper.newJSonMarshaller().fromXML( outXml ); Cheese stilton = (Cheese) result.getValue( "outStilton" ); assertEquals( 30, stilton.getPrice() ); FactHandle factHandle = (FactHandle) result.getFactHandle( "outStilton" ); stilton = (Cheese) ksession.getObject( factHandle ); assertEquals( 30, stilton.getPrice() ); // String expectedXml = ""; // expectedXml += "<execution-results>\n"; // expectedXml += " <result identifier=\"outStilton\">\n"; // expectedXml += " <org.drools.Cheese>\n"; // expectedXml += " <type>stilton</type>\n"; // expectedXml += " <oldPrice>0</oldPrice>\n"; // expectedXml += " <price>30</price>\n"; // expectedXml += " </org.drools.Cheese>\n"; // expectedXml += " </result>\n"; // expectedXml += " <fact-handle identifier=\"outStilton\" externalForm=\"" + ((InternalFactHandle) result.getFactHandle( "outStilton" )).toExternalForm() + "\" /> \n"; // expectedXml += "</execution-results>\n"; // // assertXMLEqual( expectedXml, // outXml ); } private Pipeline getPipeline(StatelessKnowledgeSession ksession) { Action executeResultHandler = PipelineFactory.newExecuteResultHandler(); Action assignResult = PipelineFactory.newAssignObjectAsResult(); assignResult.setReceiver( executeResultHandler ); Transformer outTransformer = PipelineFactory.newXStreamToXmlTransformer( BatchExecutionHelper.newJSonMarshaller() ); outTransformer.setReceiver( assignResult ); KnowledgeRuntimeCommand batchExecution = PipelineFactory.newCommandExecutor(); batchExecution.setReceiver( outTransformer ); Transformer inTransformer = PipelineFactory.newXStreamFromXmlTransformer( BatchExecutionHelper.newJSonMarshaller() ); inTransformer.setReceiver( batchExecution ); Pipeline pipeline = PipelineFactory.newStatelessKnowledgeSessionPipeline( ksession ); pipeline.setReceiver( inTransformer ); return pipeline; } private Pipeline getPipelineStateful(StatefulKnowledgeSession ksession) { Action executeResultHandler = PipelineFactory.newExecuteResultHandler(); Action assignResult = PipelineFactory.newAssignObjectAsResult(); assignResult.setReceiver( executeResultHandler ); Transformer outTransformer = PipelineFactory.newXStreamToXmlTransformer( BatchExecutionHelper.newJSonMarshaller() ); outTransformer.setReceiver( assignResult ); KnowledgeRuntimeCommand batchExecution = PipelineFactory.newCommandExecutor(); batchExecution.setReceiver( outTransformer ); Transformer inTransformer = PipelineFactory.newXStreamFromXmlTransformer( BatchExecutionHelper.newJSonMarshaller() ); inTransformer.setReceiver( batchExecution ); Pipeline pipeline = PipelineFactory.newStatefulKnowledgeSessionPipeline( ksession ); pipeline.setReceiver( inTransformer ); return pipeline; } private Pipeline getPipelineSessionStateful(GridNode node, XStreamResolverStrategy xstreamResolverStrategy) { Action executeResultHandler = PipelineFactory.newExecuteResultHandler(); Action assignResult = PipelineFactory.newAssignObjectAsResult(); assignResult.setReceiver( executeResultHandler ); //Transformer outTransformer = PipelineFactory.newXStreamToXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() ); Transformer outTransformer = new XStreamToXmlGridTransformer(); outTransformer.setReceiver( assignResult ); KnowledgeRuntimeCommand batchExecution = PipelineFactory.newCommandExecutor(); batchExecution.setReceiver( outTransformer ); //Transformer inTransformer = PipelineFactory.newXStreamFromXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() ); Transformer inTransformer = new XStreamFromXmlGridTransformer( xstreamResolverStrategy ); inTransformer.setReceiver( batchExecution ); // Transformer domTransformer = new ToXmlNodeTransformer(); // domTransformer.setReceiver( inTransformer ); //Pipeline pipeline = PipelineFactory.newStatefulKnowledgeSessionPipeline( ksession ); Pipeline pipeline = new ExecutionNodePipelineImpl( node ); pipeline.setReceiver( inTransformer ); return pipeline; } public static class ResultHandlerImpl implements ResultHandler { Object object; public void handleResult(Object object) { this.object = object; } public Object getObject() { return this.object; } } private StatelessKnowledgeSession getSession2(Resource resource) throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( resource, ResourceType.DRL ); if ( kbuilder.hasErrors() ) { fail( kbuilder.getErrors().toString() ); } assertFalse( kbuilder.hasErrors() ); Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( pkgs ); StatelessKnowledgeSession session = kbase.newStatelessKnowledgeSession(); return session; } private StatefulKnowledgeSession getSessionStateful(Resource resource) throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( resource, ResourceType.DRL ); if ( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); } assertFalse( kbuilder.hasErrors() ); Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( pkgs ); StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession(); return session; } private StatefulKnowledgeSession getExecutionNodeSessionStateful(GridNode node, Resource resource) throws Exception { KnowledgeBuilder kbuilder = node.get(KnowledgeBuilderFactoryService.class).newKnowledgeBuilder(); kbuilder.add( resource, ResourceType.DRL ); if ( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); } assertFalse( kbuilder.hasErrors() ); Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); KnowledgeBase kbase = node.get(KnowledgeBaseFactoryService.class).newKnowledgeBase(); kbase.addKnowledgePackages( pkgs ); StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession(); return session; } public String roundTripFromXml(String inXml) { Object object = BatchExecutionHelper.newJSonMarshaller().fromXML( inXml ); inXml = BatchExecutionHelper.newJSonMarshaller().toXML( object ); object = BatchExecutionHelper.newJSonMarshaller().fromXML( inXml ); return BatchExecutionHelper.newJSonMarshaller().toXML( object ); } public Object roundTripFromObject(Object object) { String xml = BatchExecutionHelper.newJSonMarshaller().toXML( object ); object = BatchExecutionHelper.newJSonMarshaller().fromXML( xml ); xml = BatchExecutionHelper.newJSonMarshaller().toXML( object ); return BatchExecutionHelper.newJSonMarshaller().fromXML( xml ); } }