1 2 Previous Next 24 Replies Latest reply on Sep 10, 2009 4:20 PM by Ronald van Kuijk

    JBPM Nested Fork/Joins Doesn't seem to work

    Phil Segal Newbie

      I am using nested fork/joins, I have 1 within the other. The Fork works, and i get two open tasks visible. However, neither join seems to work and I cannot work out why. Is this a restriction within JBPM? Is there any way to have nested fork/joins?

      When I remove the internal fork/joins and just have a normal start -> fork -> 2 tasks in parallel -> join -> task -> end, it proceeds just fine. But with the inner f/j, it seems to wait on the join, rather than proceeding to the next task.

      Any ideas?

      Many thanks
      Phil

        • 2. Re: JBPM Nested Fork/Joins Doesn't seem to work
          Phil Segal Newbie

          Hi,

          Thanks for the feedback, I will build the junit and get back to you, tho i may have spotted something. Do the internal fork/joins have to be totally self contained? At the moment I have transitions from within the internal f/j that goes to the outer one. Would this cause the issue? Is there anywhere to find a definitive do's/dont's list?

          • 3. Re: JBPM Nested Fork/Joins Doesn't seem to work
            Ronald van Kuijk Master

            yes, that is what fully contained/nested means....

            Regarding do's/dont's, this is the most important one, together with 'do not loop for polling the existence of a file' kind of things.

            • 4. Re: JBPM Nested Fork/Joins Doesn't seem to work
              Phil Segal Newbie

              It seems that within my Junit test i can have non-fully contained fork/joins, and that provided i get the correct child token (and childs-child etc) to signal, then it works succesfully.

              Is there any documentation on how taskInstance signalling works? Since I think maybe the problem is more to do with the taskInstance signal, than the token signal.

              • 5. Re: JBPM Nested Fork/Joins Doesn't seem to work
                Ronald van Kuijk Master

                If you manually signal tokens, a non fully nested fork/join might work, but that behaviour is not guaranteed to stay/be the same over versions.

                What do you mean by 'how task signalling works'? You end a task and the token continues if the other attributes on the task node allow it to. By default, ending the task makes it take the specified transition. So nothing special to it.

                • 6. Re: JBPM Nested Fork/Joins Doesn't seem to work
                  Phil Segal Newbie

                  Im not sure whether the signalling of tasks ie task.signal has the save behaviour as the direct signalling on the token object. Also, is the token object uniquely identified by something other than its name? ie its path parent/child? I am trying to work out thru junits what the constraints are, but it doesnt seem to be limited to fully nested f/j's.

                  It is all rather bizarre. Since, I have managed to see that all child tokens of a parent token are at the join, yet the parent is still at the fork. I didnt think that this should happed.

                  Finally, I have seen instances where the child tokens go past the join, yet the parent token is still at the fork...

                  • 7. Re: JBPM Nested Fork/Joins Doesn't seem to work
                    Ronald van Kuijk Master

                    if you have the unittest, please post it. Then I can see what you do instead of guessing or reading text ;-)

                    • 8. Re: JBPM Nested Fork/Joins Doesn't seem to work
                      Phil Segal Newbie

                      Thanks, Junit and jbpm xml file are below.


                      package com.jpmorgan.orion.workflow.ny;

                      import org.jbpm.graph.def.ProcessDefinition;
                      import org.jbpm.graph.exe.ProcessInstance;
                      import org.junit.Test;

                      import com.jpmorgan.orion.workflow.service.BaseManagerTestCase;

                      /**
                      * Phil Segal
                      * @date @14 May 2009
                      */
                      public class JoinsTest extends BaseManagerTestCase {

                      @Test
                      public void testNoAdjustments() throws Exception {
                      ProcessDefinition def = ProcessDefinition.parseXmlResource("workflow/ny-workflow-2/processdefinition.xml");

                      assertNotNull("Definition should not be null", def);

                      ProcessInstance instance = new ProcessInstance(def);
                      assertEquals("Def should be at start",
                      "start-daily-pnl",
                      instance.getRootToken().getNode().getName());

                      instance.signal("default");

                      instance.getRootToken().getChild("signoff").signal("signoff pnl");
                      instance.getRootToken().getChild("propose").signal("cancel fork1");

                      assertEquals("Def should be at auto approve",
                      "auto-signoff-adj",
                      instance.getRootToken().getNode().getName()
                      );
                      instance.signal("leave-asa");

                      assertEquals("Def should be at ds feeds",
                      "downstream-feeds",
                      instance.getRootToken().getNode().getName());
                      instance.signal("leave-dsf");

                      assertEquals("Def should be at fork 3",
                      "fork3",
                      instance.getRootToken().getNode().getName());

                      instance.getRootToken().getChild("reviewed").signal("review");
                      instance.getRootToken().getChild("unsignoff").signal("cancel");

                      // instance.signal();

                      assertTrue("Instance has ended", instance.hasEnded());
                      }

                      @Test
                      public void testWithAdjustmentsProcessNoApprove() throws Exception
                      {
                      ProcessDefinition def = ProcessDefinition.parseXmlResource("workflow/ny-workflow-2/processdefinition.xml");

                      assertNotNull("Definition should not be null", def);

                      ProcessInstance instance = new ProcessInstance(def);
                      assertEquals("Def should be at start",
                      "start-daily-pnl",
                      instance.getRootToken().getNode().getName());

                      instance.signal("default");

                      instance.getRootToken().getChild("propose").signal("propose an adjustment");

                      assertEquals("Def should be at fork2",
                      "fork2",
                      instance.getRootToken().getChild("propose").getNode().getName());

                      instance.getRootToken().getChild("propose").getChild("propose").signal("cancel");
                      instance.getRootToken().getChild("propose").getChild("approve").signal("cancel");

                      assertEquals("child should be at join1",
                      "join1",
                      instance.getRootToken().getChild("propose").getNode().getName());
                      assertEquals("parent should be at fork1",
                      "fork1",
                      instance.getRootToken().getNode().getName());

                      instance.getRootToken().getChild("signoff").signal("signoff pnl");

                      assertEquals("Def should be at auto approve",
                      "auto-signoff-adj",
                      instance.getRootToken().getNode().getName()
                      );

                      }
                      @Test
                      public void testWithMultipleAdjustmentsProcessNoApprove() throws Exception
                      {
                      ProcessDefinition def = ProcessDefinition.parseXmlResource("workflow/ny-workflow-2/processdefinition.xml");

                      assertNotNull("Definition should not be null", def);

                      ProcessInstance instance = new ProcessInstance(def);
                      assertEquals("Def should be at start",
                      "start-daily-pnl",
                      instance.getRootToken().getNode().getName());

                      instance.signal("default");

                      instance.getRootToken().getChild("propose").signal("propose an adjustment");

                      assertEquals("Def should be at fork2",
                      "fork2",
                      instance.getRootToken().getChild("propose").getNode().getName());

                      instance.getRootToken().getChild("propose").getChild("propose").signal("propose an adjustment");

                      // Use either just cancel, or both approve and default signals for approve signalling...
                      // instance.getRootToken().getChild("propose").getChild("approve").signal("cancel");
                      instance.getRootToken().getChild("propose").getChild("approve").signal("approve");
                      instance.getRootToken().getChild("propose").getChild("approve").signal("default");


                      instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").signal("cancel");
                      instance.getRootToken().getChild("propose").getChild("propose").getChild("approve").signal("cancel");

                      assertEquals("propose/propose should be at join1",
                      "join1",
                      instance.getRootToken().getChild("propose").getChild("propose").getNode().getName());
                      assertEquals("propose/approve should be at join2",
                      "join2",
                      instance.getRootToken().getChild("propose").getChild("approve").getNode().getName());

                      assertEquals("parent should be at fork1",
                      "fork1",
                      instance.getRootToken().getNode().getName());

                      assertEquals("propose should be at join1",
                      "join1",
                      instance.getRootToken().getChild("propose").getNode().getName());


                      instance.getRootToken().getChild("signoff").signal("signoff pnl");
                      assertEquals("signoff should be at join1",
                      "join1",
                      instance.getRootToken().getChild("signoff").getNode().getName());

                      // instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").signal("cancel");
                      // instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").signal("propose an adjustment");
                      // instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").getChild("propose").signal("cancel fork1");
                      // instance.getRootToken().getChild("propose").getChild("propose").getChild("approve").signal("cancel fork1");
                      // instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").getChild("approve").signal("cancel fork1");

                      assertEquals("Def should be at auto approve",
                      "auto-signoff-adj",
                      instance.getRootToken().getNode().getName()
                      );

                      }

                      }


                      ____________________________________________________
                      processdefinition

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

                      <process-definition xmlns="" name="ny-workflow-2">

                      <start-state name="start-daily-pnl">

                      </start-state>

                      <task-node name="signoff-pnl">

                      <!-- timer name="signoff-timer" duedate="1 minute" repeat="true">
                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      signOffTimerAction
                      jbpmConfiguration

                      </timer-->
                      <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      pnlSignOffMOAssignmentHandler
                      jbpmConfiguration


                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      signOffMultiAction
                      jbpmConfiguration




                      <!-- cancel-timer name="signoff-timer"/-->

                      </task-node>

                      <task-node name="propose-adjustments">

                      <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      proposeAdjustmentAssignmentHandler
                      jbpmConfiguration


                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      proposeAdjustmentsAction
                      jbpmConfiguration






                      </task-node>

                      <task-node name="approve-reject-adj">

                      <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      approveRejectAdjustmentAssignmentHandler
                      jbpmConfiguration






                      </task-node>

                      <!-- Reject select adjustment(s) -->

                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      rejectAdjustmentsAction
                      jbpmConfiguration




                      <task-node name="review">

                      <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      reviewPnlAssignmentHandler
                      jbpmConfiguration


                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      reviewPnlAction
                      jbpmConfiguration




                      </task-node>


                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      autoApproveAdjustmentsAction
                      jbpmConfiguration















                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      approveAdjustmentsAction
                      jbpmConfiguration









                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      downstreamFeedsAction
                      jbpmConfiguration




                      <task-node name="unsignoff-pnl">

                      <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      pnlSignOffMOAssignmentHandler
                      jbpmConfiguration


                      <action config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                      unsignoffAction
                      jbpmConfiguration


                      <!-- timer name="unsignoff-timer" duedate="1 business second" repeat="true">
                      <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                      unsignOffTimerAction
                      jbpmConfiguration

                      </timer-->


                      <!--cancel-timer name="unsignoff-timer"/-->


                      <!--cancel-timer name="unsignoff-timer"/-->

                      </task-node>














                      <end-state name="end-daily-pnl"></end-state>

                      </process-definition>

                      • 9. Re: JBPM Nested Fork/Joins Doesn't seem to work
                        Phil Segal Newbie

                        2nd time lucky...

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

                        <process-definition xmlns="" name="ny-workflow-2">

                        <start-state name="start-daily-pnl">

                        </start-state>

                        <task-node name="signoff-pnl">

                        <!-- timer name="signoff-timer" duedate="1 minute" repeat="true">
                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        signOffTimerAction
                        jbpmConfiguration

                        </timer-->
                        <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        pnlSignOffMOAssignmentHandler
                        jbpmConfiguration


                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        signOffMultiAction
                        jbpmConfiguration




                        <!-- cancel-timer name="signoff-timer"/-->

                        </task-node>

                        <task-node name="propose-adjustments">

                        <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        proposeAdjustmentAssignmentHandler
                        jbpmConfiguration


                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        proposeAdjustmentsAction
                        jbpmConfiguration






                        </task-node>

                        <task-node name="approve-reject-adj">

                        <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        approveRejectAdjustmentAssignmentHandler
                        jbpmConfiguration






                        </task-node>

                        <!-- Reject select adjustment(s) -->

                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        rejectAdjustmentsAction
                        jbpmConfiguration




                        <task-node name="review">

                        <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        reviewPnlAssignmentHandler
                        jbpmConfiguration


                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        reviewPnlAction
                        jbpmConfiguration




                        </task-node>


                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        autoApproveAdjustmentsAction
                        jbpmConfiguration















                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        approveAdjustmentsAction
                        jbpmConfiguration









                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        downstreamFeedsAction
                        jbpmConfiguration




                        <task-node name="unsignoff-pnl">

                        <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        pnlSignOffMOAssignmentHandler
                        jbpmConfiguration


                        <action config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                        unsignoffAction
                        jbpmConfiguration


                        <!-- timer name="unsignoff-timer" duedate="1 business second" repeat="true">
                        <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                        unsignOffTimerAction
                        jbpmConfiguration

                        </timer-->


                        <!--cancel-timer name="unsignoff-timer"/-->


                        <!--cancel-timer name="unsignoff-timer"/-->

                        </task-node>














                        <end-state name="end-daily-pnl"></end-state>

                        </process-definition>

                        • 10. Re: JBPM Nested Fork/Joins Doesn't seem to work
                          Phil Segal Newbie

                          sorry, im new to all this :)

                          <?xml version="1.0" encoding="UTF-8"?>
                          
                          <process-definition xmlns="" name="ny-workflow-2">
                          
                           <start-state name="start-daily-pnl">
                           <transition to="fork1" name="default"></transition>
                           </start-state>
                          
                           <task-node name="signoff-pnl">
                           <task name="Sign Off Daily PNL" description="signoff">
                           <!-- timer name="signoff-timer" duedate="1 minute" repeat="true">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>signOffTimerAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </timer-->
                           <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>pnlSignOffMOAssignmentHandler</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </assignment>
                           <event type="task-end">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>signOffMultiAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </event>
                           </task>
                           <transition to="join1" name="signoff pnl">
                           <!-- cancel-timer name="signoff-timer"/-->
                           </transition>
                           </task-node>
                          
                           <task-node name="propose-adjustments">
                           <task name="Propose Adjustments" description="proposeAdjustment">
                           <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>proposeAdjustmentAssignmentHandler</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </assignment>
                           <event type="task-end">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>proposeAdjustmentsAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </event>
                           </task>
                           <transition name="propose an adjustment" to="fork2"></transition>
                           <transition name="cancel fork1" to="join1"></transition>
                           <transition name="cancel" to="join2"></transition>
                           </task-node>
                          
                           <task-node name="approve-reject-adj">
                           <task name="Approve Adjustments" description="adjustmentDecision">
                           <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>approveRejectAdjustmentAssignmentHandler</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </assignment>
                           </task>
                           <transition to="reject-adjustment" name="reject"></transition>
                           <transition to="approve-adjustment" name="approve"></transition>
                           <transition to="join1" name="cancel fork1"></transition>
                           <transition to="join2" name="cancel"></transition>
                           </task-node>
                          
                           <!-- Reject select adjustment(s) -->
                           <node name="reject-adjustment">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>rejectAdjustmentsAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           <transition name="default" to="join2"></transition>
                           </node>
                          
                           <task-node name="review">
                           <task name="Review Daily PnL" description="reviewPNL">
                           <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>reviewPnlAssignmentHandler</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </assignment>
                           <event type="task-end">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>reviewPnlAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </event>
                           </task>
                           <transition name="review" to="join3"></transition>
                           </task-node>
                          
                           <node name="auto-signoff-adj">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>autoApproveAdjustmentsAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           <transition name="leave-asa" to="downstream-feeds"></transition>
                           </node>
                          
                           <fork name="fork1">
                           <transition name="propose" to="propose-adjustments"></transition>
                           <transition name="signoff" to="signoff-pnl"></transition>
                           </fork>
                          
                           <fork name="fork2">
                           <transition name="propose" to="propose-adjustments"></transition>
                           <transition name="approve" to="approve-reject-adj"></transition>
                           </fork>
                          
                           <node name="approve-adjustment">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>approveAdjustmentsAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           <transition name="default" to="join2"></transition>
                           </node>
                          
                           <join name="join1">
                           <transition name="default" to="auto-signoff-adj"></transition>
                           </join>
                          
                           <node name="downstream-feeds">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>downstreamFeedsAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           <transition name="leave-dsf" to="fork3"></transition>
                           </node>
                          
                           <task-node name="unsignoff-pnl">
                           <task name="Unsignoff PNL" description="signoff">
                           <assignment config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>pnlSignOffMOAssignmentHandler</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </assignment>
                           <event type="task-end">
                           <action config-type="bean" class="org.springmodules.workflow.jbpm31.JbpmHandler">
                           <beanName>unsignoffAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </event>
                           <!-- timer name="unsignoff-timer" duedate="1 business second" repeat="true">
                           <action class="org.springmodules.workflow.jbpm31.JbpmHandler" config-type="bean">
                           <beanName>unsignOffTimerAction</beanName>
                           <factoryKey>jbpmConfiguration</factoryKey>
                           </action>
                           </timer-->
                           </task>
                           <transition to="join3" name="cancel">
                           <!--cancel-timer name="unsignoff-timer"/-->
                           </transition>
                           <transition to="fork1" name="unsignoff">
                           <!--cancel-timer name="unsignoff-timer"/-->
                           </transition>
                           </task-node>
                          
                           <fork name="fork3">
                           <transition to="unsignoff-pnl" name="unsignoff"></transition>
                           <transition to="review" name="reviewed"></transition>
                           </fork>
                          
                           <join name="join3">
                           <transition to="end-daily-pnl" name="default"></transition>
                           </join>
                          
                           <join name="join2">
                           <transition to="join1" name="default"></transition>
                           </join>
                          
                           <end-state name="end-daily-pnl"></end-state>
                          
                          </process-definition>


                          • 11. Re: JBPM Nested Fork/Joins Doesn't seem to work
                            Ronald van Kuijk Master

                            nope, not even the second time : -)

                            Use [ c o d e ] [ / c o d e ] tags around it, without the spaces.

                            Ont small thing though. If it is not to much trouble, the example I referred to had everyting in one file. The processdefinition as a string and the actionhandlers as inner classes. That way I only have to create one file, not multiple, with possible typos etc.

                            • 12. Re: JBPM Nested Fork/Joins Doesn't seem to work
                              Ronald van Kuijk Master

                              ah, sorry, I missed the thrid time :-)

                              • 13. Re: JBPM Nested Fork/Joins Doesn't seem to work
                                Ronald van Kuijk Master

                                oh, and one more thing, it would be nice if you could reduce the test to a minimal one. Just showing this one issue.

                                • 14. Re: JBPM Nested Fork/Joins Doesn't seem to work
                                  Phil Segal Newbie

                                  Here is the 1 failing test, the other 2 work.

                                   @Test
                                   public void testWithMultipleAdjustmentsProcessNoApprove() throws Exception
                                   {
                                   ProcessDefinition def = ProcessDefinition.parseXmlResource("workflow/ny-workflow-2/processdefinition.xml");
                                  
                                   assertNotNull("Definition should not be null", def);
                                  
                                   ProcessInstance instance = new ProcessInstance(def);
                                   assertEquals("Def should be at start",
                                   "start-daily-pnl",
                                   instance.getRootToken().getNode().getName());
                                  
                                   instance.signal("default");
                                  
                                   instance.getRootToken().getChild("propose").signal("propose an adjustment");
                                  
                                   assertEquals("Def should be at fork2",
                                   "fork2",
                                   instance.getRootToken().getChild("propose").getNode().getName());
                                  
                                   instance.getRootToken().getChild("propose").getChild("propose").signal("propose an adjustment");
                                   instance.getRootToken().getChild("propose").getChild("approve").signal("cancel");
                                  
                                   instance.getRootToken().getChild("propose").getChild("propose").getChild("propose").signal("cancel");
                                   instance.getRootToken().getChild("propose").getChild("propose").getChild("approve").signal("cancel");
                                  
                                   assertEquals("propose/propose should be at join1",
                                   "join1",
                                   instance.getRootToken().getChild("propose").getChild("propose").getNode().getName());
                                   assertEquals("propose/approve should be at join2",
                                   "join2",
                                   instance.getRootToken().getChild("propose").getChild("approve").getNode().getName());
                                  
                                   assertEquals("parent should be at fork1",
                                   "fork1",
                                   instance.getRootToken().getNode().getName());
                                  
                                   assertEquals("propose should be at join1",
                                   "join1",
                                   instance.getRootToken().getChild("propose").getNode().getName());
                                  
                                  
                                   instance.getRootToken().getChild("signoff").signal("signoff pnl");
                                   assertEquals("signoff should be at join1",
                                   "join1",
                                   instance.getRootToken().getChild("signoff").getNode().getName());
                                  
                                   assertEquals("Def should be at auto approve",
                                   "auto-signoff-adj",
                                   instance.getRootToken().getNode().getName()
                                   );
                                  
                                   }
                                  
                                  


                                  1 2 Previous Next