6 Replies Latest reply on Mar 1, 2011 2:16 PM by byungwoojun

    jBPM 5 Loop Type support?

    byungwoojun

      1) Subprocess Loop Type:

       

      According to the jBPM 5 user guide and some jBPM 5 blogs, the "looping back" seems to be supported from the subprocess (and multi instance). However, from the Eclipse BPMN2 Process editor (which came with the jBPM 5 installation), I couldn't find any subprocess property field for the subprocess looping. How do I set the subprocess loop type from the Eclipse BPMN2 Process editor?

       

      The Oryx-based designer integrated with Guvnor has the subprocess loop type, but this designer does NOT allow me to "save" any process defintion with the subprocess (does NOT support the subprocess enum yet),as I reported earlier.

       

      So, I cannot use either BPMN 2 designer to define the looping subprocess. Does anyone have a suggestion for this? Any help will be appreciated.

       

       

      2) Process Loop back:

       

      For putting the loop back in a process, one blog suggested using a converging parallel gateway and a diverging gateway as follows:

       

      loopback.bmp

       

      But, the "Hello Again" acitivity was never executed. It seems to me that the converging parellel gatway <+> is waiting for the "Hello Back" before it goes to the "Hello Again" activity. It is possible my configuration is incorrect. If the process loop back is possible, how do I do it?

       

      Thanks,

      bwj

        • 1. jBPM 5 Loop Type support?
          bpmn2user

          Yes! Looping is possible.

          You might be missing something. It might be possible to suggest the modifications to your test code if you could share it.

          Could you post the sample code used?

          • 2. jBPM 5 Loop Type support?
            byungwoojun

            First of all, thank you very much for your reply! After your reply (thanks for the inspiration), I modifed my bpmn file, replacing the first converging parallel gateway with the converging "exclusive" gateway. See the attached bpmn file. After the changing, the loop worked!  So, the process has the converging exclusive gateway followed by the diverging exclusive gateway. Now, I think it is obvious.

             

            BTW, do have a suggestion for my question #1 (Subprocess looptype attribute from the Eclipse BPMN 2 Process Editor)?

             

            Thanks,

            bwj

             

            loopback2.bmp

             

             

            =========================

            processTest2.java

             

            import java.util.HashMap;
            import java.util.Map;
            import java.util.Properties;

            import org.drools.KnowledgeBase;
            import org.drools.KnowledgeBaseFactory;
            import org.drools.builder.KnowledgeBuilder;
            import org.drools.builder.KnowledgeBuilderFactory;
            import org.drools.builder.ResourceType;
            import org.drools.compiler.BPMN2ProcessFactory;
            import org.drools.compiler.ProcessBuilderFactory;
            import org.drools.impl.EnvironmentFactory;
            import org.drools.io.ResourceFactory;
            import org.drools.logger.KnowledgeRuntimeLogger;
            import org.drools.logger.KnowledgeRuntimeLoggerFactory;
            import org.drools.marshalling.impl.ProcessMarshallerFactory;
            import org.drools.runtime.KnowledgeSessionConfiguration;
            import org.drools.runtime.StatefulKnowledgeSession;
            import org.drools.runtime.process.ProcessRuntimeFactory;
            import org.jbpm.bpmn2.BPMN2ProcessProviderImpl;
            import org.jbpm.marshalling.impl.ProcessMarshallerFactoryServiceImpl;
            import org.jbpm.process.builder.ProcessBuilderFactoryServiceImpl;
            import org.jbpm.process.instance.ProcessRuntimeFactoryServiceImpl;
            import org.jbpm.process.workitem.wsht.WSHumanTaskHandler;

            /**
            * This is a sample file to launch a process.
            */
            public class ProcessTest2 {

            public static final void main(String[] args) {
              try {
               // load up the knowledge base
               KnowledgeBase kbase = readKnowledgeBase();
               StatefulKnowledgeSession ksession = createSession(kbase);
               KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

               // start a new process instance
               Map<String, Object> params = new HashMap<String, Object>();
               params.put("count", 1);  
               ksession.startProcess("looptest777", params);
               logger.close();
              } catch (Throwable t) {
               t.printStackTrace();
              }
            }

            private static KnowledgeBase readKnowledgeBase() throws Exception {
              ProcessBuilderFactory.setProcessBuilderFactoryService(new ProcessBuilderFactoryServiceImpl());
              ProcessMarshallerFactory.setProcessMarshallerFactoryService(new ProcessMarshallerFactoryServiceImpl());
              ProcessRuntimeFactory.setProcessRuntimeFactoryService(new ProcessRuntimeFactoryServiceImpl());
              BPMN2ProcessFactory.setBPMN2ProcessProvider(new BPMN2ProcessProviderImpl());
              KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
              kbuilder.add(ResourceFactory.newClassPathResource("looptest777.bpmn"), ResourceType.BPMN2);
              return kbuilder.newKnowledgeBase();
            }

            private static StatefulKnowledgeSession createSession(KnowledgeBase kbase) {
              Properties properties = new Properties();
              properties.put("drools.processInstanceManagerFactory", "org.jbpm.process.instance.impl.DefaultProcessInstanceManagerFactory");
              properties.put("drools.processSignalManagerFactory", "org.jbpm.process.instance.event.DefaultSignalManagerFactory");
              KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(properties);
              return kbase.newStatefulKnowledgeSession(config, EnvironmentFactory.newEnvironment());
            }
            }

             

            looptest777.bpmn

            ================

             

            <?xml version="1.0" encoding="UTF-8"?>

            <definitions id="Definition"

            targetNamespace="http://www.jboss.org/drools"

            typeLanguage="http://www.java.com/javaTypes"

            expressionLanguage="http://www.mvel.org/2.0"

            xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"

            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"

            xmlns:g="http://www.jboss.org/drools/flow/gpd"

            xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"

            xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"

            xmlns:di="http://www.omg.org/spec/DD/20100524/DI"

            xmlns:tns="http://www.jboss.org/drools">

             

            <itemDefinition id="_countItem" structureRef="Integer" />

             

            <process processType="Private" isExecutable="true" id="looptest777" name="looptest777.b" >

             

            <!-- process variables -->

            <property id="count" itemSubjectRef="_countItem"/>

             

            <!-- nodes -->

            <startEvent id="_1" name="Start" />

            <scriptTask id="_2" name="Hello" >

            <script>System.out.println("Hello");

            </script>

            </scriptTask>

            <scriptTask id="_4" name="Hello Again" >

            <script>System.out.println("Hello Again");</script>

            </scriptTask>

            <exclusiveGateway id="_5" name="Gateway" gatewayDirection="Diverging" />

            <endEvent id="_6" name="End" >

            <terminateEventDefinition/>

            </endEvent>

            <scriptTask id="_7" name="Hello Back" >

            <script>System.out.println("Hello back");

            count += 1;

            System.out.println("count: " + count);

            kcontext.setVariable("count", count);

            </script>

            </scriptTask>

            <scriptTask id="_8" name="Hello Post" >

            <script>System.out.println("Hello Post");</script>

            </scriptTask>

            <exclusiveGateway id="_10" name="Gateway" gatewayDirection="Converging" />

             

            <!-- connections -->

            <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />

            <sequenceFlow id="_10-_4" sourceRef="_10" targetRef="_4" />

            <sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5" />

            <sequenceFlow id="_8-_6" sourceRef="_8" targetRef="_6" />

            <sequenceFlow id="_5-_7" sourceRef="_5" targetRef="_7" name="loop back" >

            <conditionExpression xsi:type="tFormalExpression" >return count &lt; 3;</conditionExpression>

            </sequenceFlow>

            <sequenceFlow id="_5-_8" sourceRef="_5" targetRef="_8" name="otherwise" >

            <conditionExpression xsi:type="tFormalExpression" language="http://www.jboss.org/drools/rule" >eval(true)</conditionExpression>

            </sequenceFlow>

            <sequenceFlow id="_2-_10" sourceRef="_2" targetRef="_10" />

            <sequenceFlow id="_7-_10" sourceRef="_7" targetRef="_10" />

             

            </process>

             

            <bpmndi:BPMNDiagram>

            <bpmndi:BPMNPlane bpmnElement="looptest777" >

            <bpmndi:BPMNShape bpmnElement="_1" >

            <dc:Bounds x="27" y="150" width="48" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_2" >

            <dc:Bounds x="95" y="152" width="80" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_4" >

            <dc:Bounds x="286" y="205" width="80" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_5" >

            <dc:Bounds x="411" y="156" width="48" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_6" >

            <dc:Bounds x="609" y="152" width="48" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_7" >

            <dc:Bounds x="287" y="94" width="80" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_8" >

            <dc:Bounds x="492" y="156" width="80" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNShape bpmnElement="_10" >

            <dc:Bounds x="202" y="149" width="48" height="48" />

            </bpmndi:BPMNShape>

            <bpmndi:BPMNEdge bpmnElement="_1-_2" >

            <di:waypoint x="51" y="174" />

            <di:waypoint x="135" y="176" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_10-_4" >

            <di:waypoint x="226" y="173" />

            <di:waypoint x="326" y="229" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_4-_5" >

            <di:waypoint x="326" y="229" />

            <di:waypoint x="435" y="180" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_8-_6" >

            <di:waypoint x="532" y="180" />

            <di:waypoint x="633" y="176" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_5-_7" >

            <di:waypoint x="435" y="180" />

            <di:waypoint x="327" y="118" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_5-_8" >

            <di:waypoint x="435" y="180" />

            <di:waypoint x="532" y="180" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_2-_10" >

            <di:waypoint x="135" y="176" />

            <di:waypoint x="226" y="173" />

            </bpmndi:BPMNEdge>

            <bpmndi:BPMNEdge bpmnElement="_7-_10" >

            <di:waypoint x="327" y="118" />

            <di:waypoint x="226" y="173" />

            </bpmndi:BPMNEdge>

            </bpmndi:BPMNPlane>

            </bpmndi:BPMNDiagram>

             

            </definitions>

            • 3. jBPM 5 Loop Type support?
              krisverlaenen

              If you want to specifiy multiple instances (execute a part of your process multiple times, once for each element in a collection), you should use the MultipleInstances node type from the palette, that allows you to specify the collection to load from etc.


              Kris

              • 4. jBPM 5 Loop Type support?
                byungwoojun

                Kris, thanks! I enjoyed the webinar last Thursday.

                 

                I know the MultipleInstances node can do looping, but to me, it depends on the input collection (size). I need a subprocess looping based on the "do until" or "while' condition. So, an acitivity inside of the subprocess returns a value, and based on the value, a gateway inside of the subprocess decides the looping.

                 

                Speaking of the MultipleInstances node, I think activities inside of the node can be executed parallely or sequentially. How do I set the behavior from the Eclipse BPMN 2 Editor? I saw the Guvnor Designer (Oryx-based) has a subprocess property field where I can change the behavior (but as you may know, I couldn't save any subprocess using the Guvnor designer for now - at the webinar, you told us your team is working on the designer with Intalio and I assueme the 5.1 release fixes the issue).

                 

                Thanks again for great work!!!

                bwj

                • 5. jBPM 5 Loop Type support?
                  bpmn2user

                  I need a subprocess looping based on the "do until" or "while' condition. So, an acitivity inside of the subprocess returns a value, and based on the value, a gateway inside of the subprocess decides the looping.

                   

                   

                  I modfied the code to include a sub-process here.

                  http://community.jboss.org/people/bpmn2user/blog/2011/03/01/jbpm5--subproces-loop-example

                   

                  The loop condition can be set inside the sub-process, though it is passed as a paramter from the parent process in this example.

                  • 6. jBPM 5 Loop Type support?
                    byungwoojun

                    Hi bpmn2user,

                     

                    Very nice! Thank you very much for your reply and blog! I just imported and tested your code. It worked. Using your method, I learned how to achieve the subprocess looping (do util, while) even though there seems to be no "built-in" (property-based) subprocess loop type from the Eclipse BPMN2 Editor. Until, the Eclipse BPMN2 designer conforms to the full BPMN 2, I can use your method.

                     

                    Thanks again, your suggestion is very useful!!!

                     

                    bwj