[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