11 Replies Latest reply on Apr 14, 2007 2:39 PM by kukeltje

    process versioning + swimlane with pooledActors

    morpheus_jboss

      processdefinition.xml:

      Swimlane S1 with pooledActors="A1, A2"
      Process Definition has 3 Tasks: T1, T2 and T3, all assigned to Swimlane S1

      Problem:

      step 1:
      A1 started a process instance, with T2 automatically in his pooledTasks list, which is the expected behaviour

      step 2:
      Process Definition changed (S1 changed to S1' with pooledActors="A2", i.e., A1 is not in S1 any more) and the process definition got new version (using JbpmContext.deployProcessDefinition()):

      step 3:
      A1 completes T2

      Expected: T3 in A1's pooledTasks. Because the running process instance started by A1 was based on the old process definition, which means that A1 should be able to take a part in all the three tasks T1, T2 and T3.

      But T3 is not in A1's pooledTask list. In fact, T2 was already labeled with the new process definition version after step 2.

      Question
      It seems that the change in TaskMgmt takes effect immediately and influences the process instances started on old process definitions. Is this a bug or an intention?

        • 1. Re: process versioning + swimlane with pooledActors
          kukeltje

          If it realy behaves that way it is a bug. Could you make a testcase (unit test like all the other jbpm tests) that demonstrates the 'failing' behaviour?

          • 2. Re: process versioning + swimlane with pooledActors
            morpheus_jboss

            Thanks for the reply. I can not access my project till the end of next week. By then I will try your suggestion and post my results.

            • 3. Re: process versioning + swimlane with pooledActors
              morpheus_jboss

               

              import java.util.Iterator;
              import java.util.List;
              
              import junit.framework.Test;
              import junit.framework.TestCase;
              import junit.framework.TestSuite;
              
              import org.jbpm.JbpmConfiguration;
              import org.jbpm.JbpmContext;
              import org.jbpm.graph.def.ProcessDefinition;
              import org.jbpm.graph.exe.ProcessInstance;
              import org.jbpm.taskmgmt.def.Swimlane;
              import org.jbpm.taskmgmt.exe.TaskInstance;
              
              public class JbpmTest extends TestCase {
              
               JbpmConfiguration jbpmCfg;
               JbpmContext jbpmContext;
              
               public JbpmDelegatorTest(String name) {
               super(name);
               }
              
               protected void setUp() {
               this.jbpmCfg = JbpmConfiguration.getInstance();
               this.jbpmContext = jbpmCfg.createJbpmContext();
               }
              
               protected void tearDown() {
               jbpmContext.close();
               }
              
               public void testDeployProcessXml() {
               String xmlResource = "returngoods.swimlane-pooled-actors/processdefinition.xml";
               ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(xmlResource);
               jbpmContext.deployProcessDefinition(processDefinition);
               }
              
               public void testCreateStartTaskInstance() {
               ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("returngoods.swimlane-pooled-actors");
              // long processDefinitionId = processDefinition.getId();
              
               ProcessInstance processInstance = processDefinition.createProcessInstance();
               TaskInstance startTaskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
               startTaskInstance.end();
               jbpmContext.save(processInstance);
              
               List pooledTaskInstances = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("yoyo");
               assertTrue(pooledTaskInstances.size() > 0); //the 'Receive Item' task should be there according to the process definition
               TaskInstance taskInstanceOld = (TaskInstance) pooledTaskInstances.get(0);
               assertEquals("Receive Item", taskInstanceOld.getName());
               int oldVersion = taskInstanceOld.getTaskMgmtInstance().getTaskMgmtDefinition().getProcessDefinition().getVersion();
               System.out.println("oldVersion " + oldVersion);
              
               }
              
               public void testChangeProcessDefinition() {
               ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("returngoods.swimlane-pooled-actors");
              
               //removing yoyo from all swimlanes
               Swimlane swimlane = processDefinition.getTaskMgmtDefinition().getSwimlane("Shipping");
               swimlane.setActorIdExpression(null);
               swimlane.setPooledActorsExpression("grover");
              
               swimlane = processDefinition.getTaskMgmtDefinition().getSwimlane("Sales");
               swimlane.setActorIdExpression(null);
               swimlane.setPooledActorsExpression("ernie");
              
               swimlane = processDefinition.getTaskMgmtDefinition().getSwimlane("Accounting");
               swimlane.setActorIdExpression(null);
               swimlane.setPooledActorsExpression("bert");
              
               jbpmContext.deployProcessDefinition(processDefinition);
               }
              
               public void testCompleteTask() {
               List pooledTaskInstances = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("yoyo");
               assertTrue(pooledTaskInstances.size() > 0); //the 'Receive Item' task should be there according to the process definition
               TaskInstance taskInstanceNew = (TaskInstance) pooledTaskInstances.get(0);
               assertEquals("Receive Item", taskInstanceNew.getName());
               int newVersion = taskInstanceNew.getTaskMgmtInstance().getTaskMgmtDefinition().getProcessDefinition().getVersion();
              
               //The taskInstance is still there, but with new process version!
               System.out.println("newVersion "+ newVersion);
              
               taskInstanceNew.end();
               }
              
               public void testPooledTaskInstances() {
               List pooledTaskInstances = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("yoyo");
              
               // the suite failed here!
               assertTrue(pooledTaskInstances.size() > 0);
              
               for (Iterator iter = pooledTaskInstances.iterator(); iter.hasNext();) {
               TaskInstance taskInstance = (TaskInstance) iter.next();
               System.out.println("taskInstanceName " + taskInstance.getName());
               System.out.println("version " + taskInstance.getTaskMgmtInstance().getTaskMgmtDefinition().getProcessDefinition().getVersion());
               }
               }
              
               //clean up all pooledTaskInstances for yoyo to make the result clear
               public void testCleanUp() {
               List pooledTaskInstances = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("yoyo");
               for (Iterator iter = pooledTaskInstances.iterator(); iter.hasNext();) {
               TaskInstance taskInstance = (TaskInstance) iter.next();
               taskInstance.end();
               ProcessInstance processInstance = taskInstance.getTaskMgmtInstance().getProcessInstance();
               processInstance.end();
               jbpmContext.save(processInstance);
               }
               pooledTaskInstances = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("yoyo");
              // assertNull(pooledTaskInstances);
               assertEquals(0, pooledTaskInstances.size());
               }
              
               public static Test suite() {
               TestSuite suite = new TestSuite("Test for jbpm");
               //$JUnit-BEGIN$
               suite.addTest(new JbpmDelegatorTest("testCleanUp"));
               suite.addTest(new JbpmDelegatorTest("testDeployProcessXml"));
              
               //start a process instance
               suite.addTest(new JbpmDelegatorTest("testCreateStartTaskInstance"));
              
               //do some changes in TaskMgmtDefinition
               suite.addTest(new JbpmDelegatorTest("testChangeProcessDefinition"));
              
               //complete the already assigned taskInstance
               suite.addTest(new JbpmDelegatorTest("testCompleteTask"));
              
               //test if the processInstance is still using the old process definition, but failed here
               suite.addTest(new JbpmDelegatorTest("testPooledTaskInstances"));
               //$JUnit-END$
               return suite;
               }
              


              • 4. Re: process versioning + swimlane with pooledActors
                morpheus_jboss

                 

                <?xml version="1.0" encoding="UTF-8"?>
                
                <process-definition
                 xmlns="urn:jbpm.org:jpdl-3.1" name="returngoods.swimlane-pooled-actors">
                
                 <swimlane name="Shipping">
                 <assignment pooled-actors="grover, yoyo"></assignment>
                 </swimlane>
                 <swimlane name="Sales">
                 <assignment pooled-actors="ernie, yoyo"></assignment>
                 </swimlane>
                 <swimlane name="Accounting">
                 <assignment pooled-actors="bert, yoyo"></assignment>
                 </swimlane>
                
                 <start-state name="Ship Order Return">
                 <task name="Send Item">
                 <controller>
                 <variable name="tracking number" access="read,write,required"></variable>
                 </controller>
                 </task>
                 <transition name="Shipping" to="Receive Return"></transition>
                 </start-state>
                
                 <task-node name="Receive Return">
                 <task name="Receive Item" swimlane="Shipping">
                 <controller>
                 <variable name="tracking number" access="read"></variable>
                 <variable name="received date" access="read,write,required"></variable>
                 </controller>
                 </task>
                 <transition name="Process Return" to="fork 1"></transition>
                 </task-node>
                
                 <fork name="fork 1">
                 <transition name="Ordering" to="Update Order"></transition>
                 <transition name="Accounting" to="Return Money"></transition>
                 </fork>
                
                 <task-node name="Update Order">
                 <task name="Send Updated Order" swimlane="Sales">
                 <controller>
                 <variable name="address" access="read,write,required"></variable>
                 </controller>
                 </task>
                 <transition name="" to="join1"></transition>
                 </task-node>
                
                 <task-node name="Return Money">
                 <task name="Update Books" swimlane="Accounting">
                 <controller>
                 <variable name="amount" access="read,write,required"></variable>
                 </controller>
                 </task>
                 <transition name="" to="join1"></transition>
                 </task-node>
                
                 <join name="join1">
                 <transition name="" to="Process End"></transition>
                 </join>
                
                 <end-state name="Process End"></end-state>
                
                </process-definition>
                


                • 5. Re: process versioning + swimlane with pooledActors
                  morpheus_jboss

                  After the process instance is started, actor "yoyo" was in all three swimlanes. We remove him from all swimlanes in the processdefinition (programatically) and deploy this new definition. This change in taskMgmt takes effect immediately on the running processInstance, which is not a expected behaviour.

                  Based on the test suite and processdefinition.xml posted above, i suspect the process versioning is not working, at least not working together with taskMgmt. However, taskMgmt is the part that needs to be changed most frequently IMHO.

                  • 6. Re: process versioning + swimlane with pooledActors
                    morpheus_jboss

                    Sorry there was a typo. But the claim remains. The code for the suite should be:

                     public static Test suite() {
                     TestSuite suite = new TestSuite("Test for jbpm");
                     //$JUnit-BEGIN$
                     suite.addTest(new JbpmTest("testCleanUp"));
                     suite.addTest(new JbpmTest("testDeployProcessXml"));
                    
                     //start a process instance
                     suite.addTest(new JbpmTest("testCreateStartTaskInstance"));
                    
                     //do some changes in TaskMgmtDefinition
                     suite.addTest(new JbpmTest("testChangeProcessDefinition"));
                    
                     //complete the already assigned taskInstance
                     suite.addTest(new JbpmTest("testCompleteTask"));
                    
                     //test if the processInstance is still using the old process definition, but failed here
                     suite.addTest(new JbpmTest("testPooledTaskInstances"));
                     //$JUnit-END$
                     return suite;
                     }
                    


                    • 7. Re: process versioning + swimlane with pooledActors
                      kukeltje

                      hmmm... afaik, because of the way hibernate works, you cannot read a pd, update it programatically and deploy it as a new version. The way you do it now, you not only deploy a new processdefinition, but also update the current one.... (or maybe only update the current one).

                      Try working with 2 xml based processdefinitions and see if the problem still occurs...

                      • 8. Re: process versioning + swimlane with pooledActors
                        morpheus_jboss

                        I think working with two xml based pd's the problem should not be there any more. I have not tested that yet. But that is not what we want. I also agree with you about the hibernate part.

                        To summarize the problem, we want to have process versioning working while changing process definition programmatically and without parsing the xml again. IMHO this method, jbpmContext.deployProcessDefinition(pd), should in any case support process versioning.

                        • 9. Re: process versioning + swimlane with pooledActors
                          kukeltje

                          I think the api does deploy a new process, but....

                          you modify a processdefinition and when the context is closed, it is saved, so the one you retrieve is modified in addition to deploying a new one. Maybe you should make a kind of deep copy before modifiing and saving that.

                          • 10. Re: process versioning + swimlane with pooledActors
                            morpheus_jboss

                             

                            "kukeltje" wrote:
                            I think the api does deploy a new process, but....

                            you modify a processdefinition and when the context is closed, it is saved, so the one you retrieve is modified in addition to deploying a new one.

                            I checked in the database, there is no new pd entry inserted by jbpmContext.deployProcessDefinition(). The old entry is still there, with only its version number increased, or the old entry is just overwritten by the new one.


                            Maybe you should make a kind of deep copy before modifiing and saving that.

                            How to do that? Please could you give more details on this?

                            • 11. Re: process versioning + swimlane with pooledActors
                              kukeltje

                              I would if I new how to... this is a hibernate thing, so you might want to search the hibernate docs