[rules-users] iterating over objects in a StatelessKnowledgeSession
Michal Bali
michalbali at gmail.com
Thu Mar 19 19:49:33 EDT 2009
Thank you Mark! That helps.
I was just trying to provide some feedback before the final release :)
Best Regards,
Michal
2009/3/19 Mark Proctor <mproctor at codehaus.org>
> Based on your feedbck I have added support for a GetObjects command and a
> FireAllRules command. So now you can call GetObjects and have it's results
> assigned to an identifier. FireAllrules can now be manually called, even for
> a stateless session. If you manually call fireAllRules in a stateless
> session it will no longer be called automatically at the end.
>
> Here are two unit tests showing the behaviour. I was going to leave this
> till 5.1, but it seems you really need this and the code is safe enough that
> it shouldn't break anything else.
>
> 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>";
> inXml += " <insert-elements>";
> inXml += " <org.drools.Cheese>";
> inXml += " <type>stilton</type>";
> inXml += " <price>25</price>";
> inXml += " <oldPrice>0</oldPrice>";
> inXml += " </org.drools.Cheese>";
> inXml += " <org.drools.Cheese>";
> inXml += " <type>stilton</type>";
> inXml += " <price>30</price>";
> inXml += " <oldPrice>0</oldPrice>";
> inXml += " </org.drools.Cheese>";
> inXml += " </insert-elements>";
> inXml += " <get-objects out-identifier='list' />";
> inXml += "</batch-execution>";
>
> StatelessKnowledgeSession ksession = getSession2(
> ResourceFactory.newByteArrayResource( str.getBytes() ) );
> ResultHandlerImpl resultHandler = new ResultHandlerImpl();
> getPipeline(ksession).insert( inXml, resultHandler );
> String outXml = ( String ) resultHandler.getObject();
>
> String expectedXml = "";
> expectedXml += "<batch-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 += "</batch-execution-results>\n";
>
> assertXMLEqual( expectedXml, outXml );
>
> BatchExecutionResults result = ( BatchExecutionResults )
> BatchExecutionHelper.newXStreamMarshaller().fromXML( outXml );
> List list = ( List ) result.getValue( "list" );
> 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 testManualFireAllRules() throws Exception {
> String str = "";
> str += "package org.drools \n";
> str += "import org.drools.Cheese \n";
> str += "global java.util.List list \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 += " list.add( $c );";
> str += "end\n";
>
> String inXml = "";
> inXml += "<batch-execution>";
> inXml += " <set-global identifier='list' out='true'>";
> inXml += " <list/>";
> inXml += " </set-global>";
> inXml += " <insert-elements>";
> inXml += " <org.drools.Cheese>";
> inXml += " <type>stilton</type>";
> inXml += " <price>25</price>";
> inXml += " <oldPrice>0</oldPrice>";
> inXml += " </org.drools.Cheese>";
> inXml += " <org.drools.Cheese>";
> inXml += " <type>stilton</type>";
> inXml += " <price>30</price>";
> inXml += " <oldPrice>0</oldPrice>";
> inXml += " </org.drools.Cheese>";
> inXml += " </insert-elements>";
> inXml += " <fire-all-rules />";
> inXml += " <insert out-identifier='outBrie'>";
> inXml += " <org.drools.Cheese>";
> inXml += " <type>brie</type>";
> inXml += " <price>10</price>";
> inXml += " <oldPrice>5</oldPrice>";
> inXml += " </org.drools.Cheese>";
> inXml += " </insert>";
> inXml += "</batch-execution>";
>
> StatelessKnowledgeSession ksession = getSession2(
> ResourceFactory.newByteArrayResource( str.getBytes() ) );
> ResultHandlerImpl resultHandler = new ResultHandlerImpl();
> getPipeline(ksession).insert( inXml, resultHandler );
> String outXml = ( String ) resultHandler.getObject();
>
> String expectedXml = "";
> expectedXml += "<batch-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 += "</batch-execution-results>\n";
> assertXMLEqual( expectedXml, outXml );
>
> BatchExecutionResults result = ( BatchExecutionResults )
> BatchExecutionHelper.newXStreamMarshaller().fromXML( outXml );
>
> // brie should not have been added to the list
> List list = ( List ) result.getValue( "list" );
> 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" ) );
> }
>
>
>
>
>
> Michal Bali wrote:
>
> Hi Mark,
>
> I want this for a unit test. It will verify that the stateless session
> contains only expected objects after execution. I don't want to write a new
> query that will be used only in the unit test.
>
> Currently it is possible to iterate over all objects in a
> StatefulKnowledgeSession through its getObjects method. However it is not
> supported by default on the StatelessKnowledgeSession.
>
> I've created a custom command for getting the objects. Its execute method
> looks like this:
> public Iterator< ? > execute(ReteooWorkingMemory session) {
> Iterator<?> objects = session.iterateObjects( filter );
> session.getBatchExecutionResult().getResults().put(identifier,
> objects);
> return objects;
> }
>
> Another thing to note is that StatelessKnowledgeSession.execute(Command
> command) method first executes all given commands and then calls
> session.fireAllRules. So if you want to insert some objects and run a query
> you'll pass some insert commands and a query command. However the query will
> be executed before the fireAllRules call and so it won't return anything. Alternatively
> you could pass in a fireAllRules command as well, which will work fine. The
> fireAllRules will be executed twice but that is not a big deal.
> Another issue is that the query command makes it difficult to pass in query
> arguments that are known only after the rules execution. Because you have to
> specify the query before the fireAllRules execution. I guess you could
> create your own command and do all logic there but this is not very nice.
> Just my 2c.
>
> Best Regards,
> Michal
>
>
> 2009/3/17 Mark Proctor <mproctor at codehaus.org>
>
>> Michal Bali wrote:
>>
>> Hi,
>>
>> I am trying this on trunk. There is currently no way how to iterate
>> objects in a StatelessKnowledgeSession.
>>
>> I've tried to use the GetObjectsCommand, however when it is executes the
>> result is lost in the ether :). The collection of objects is not handed back
>> to the user.
>>
>> I guess it should probably be added to the BatchExecutionResults? It will
>> then be possible to access this collection of objects.
>>
>> You have ot specify what it is you want as an out, either as an 'out' on
>> an inserted fact or global or a query.
>>
>>
>> Please let me know if there is a different way how to iterate over objects
>> in a StatelessKnowledgeSession. I'd like to use an ObjectFilter as well.
>>
>> Extend the Query interface and use that to filter the iterator on a
>> returned query.
>>
>>
>> Best Regards,
>> Michal
>>
>> ------------------------------
>> _______________________________________________
>> rules-users mailing listrules-users at lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users
>>
>>
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
>>
> ------------------------------
> _______________________________________________
> rules-users mailing listrules-users at lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090319/3e1c6e62/attachment.html
More information about the rules-users
mailing list