[jboss-user] [JBoss jBPM] - Re: Using end-complete-process attribute of end-state

nizzy do-not-reply at jboss.com
Fri Jun 6 09:11:30 EDT 2008


Hi,

Finally got back to this issue.

I'm using the end-complete-process="true" attribute of end-state.

My process definition has a fork, the fork has two paths of execution. At the end of each path, processing can either be successfull or fail. When execution fails I would expect to enter the relevant end-state and not to be able to signal the process again.

This is not the observed behaviour.

In fact the end-state is only entered if both paths of execution in the fork fail.

Is this a problem or have I misunderstood what should be happening

Below is a unit test containing the process definition

Test1 is +ve test to show nothing wrong with process definition
Test2 fails as expected, however only because both paths in fork have failed
Test3 verifies that behaviour not as expected.

  | package com.sample;
  | 
  | 
  | import java.util.Map;
  | 
  | import junit.framework.Assert;
  | 
  | import org.apache.log4j.Logger;
  | import org.apache.log4j.PropertyConfigurator;
  | import org.jbpm.JbpmConfiguration;
  | import org.jbpm.JbpmContext;
  | import org.jbpm.context.exe.ContextInstance;
  | import org.jbpm.graph.def.ProcessDefinition;
  | import org.jbpm.graph.exe.ProcessInstance;
  | import org.jbpm.graph.exe.Token;
  | import org.junit.Before;
  | import org.junit.Test;
  | 
  | /** 
  |  * TODO description
  |  *
  |  * @author Alan Nisbet 
  |  * @version $Revision$ 
  |  */
  | 
  | /* 
  |  History 
  |  ======= 
  |  $Log$ 
  |  */
  | public class EndStateTest {
  | 
  |     /**
  |      * Log4j Logger for this class
  |      */
  |     private static final Logger log = Logger.getLogger(EndStateTest.class);
  |     private ProcessDefinition processDefinition;
  |     
  |     @Before
  |     public void setUp() throws Exception {
  |         PropertyConfigurator.configure("log4j.properties");
  |         JbpmContext ctx = JbpmConfiguration.getInstance().createJbpmContext();
  |         
  |         log.info("Parsing ProcessDefinition");
  |         try {
  |             processDefinition = ProcessDefinition
  |                     .parseXmlString(
  |                         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
  |                 		"<process-definition  xmlns=\"\" name=\"forktest\">" +
  |             				"<start-state name=\"start\">" +
  |             				    "<transition to=\"doThis1\"></transition>" +
  |             				"</start-state>" +
  |             				
  |             				"<node name=\"doThis1\">" +
  |             				    "<transition to=\"fork1\"></transition>" +
  |             				"</node>" +
  |             				
  |         				    "<fork name=\"fork1\">" +
  |             				    "<transition to=\"wait for a\" name=\"a\"></transition>" +
  |             				    "<transition to=\"wait for b\" name=\"b\"></transition>" +
  |         				    "</fork>" +
  |                 				    
  |         				    "<node name=\"doThis2\">" +
  |         				        "<action class=\"com.ecebs.sample.action.DefaultActionHandler\"></action>" +
  |         				        "<transition to=\"join1\" name=\"success\"></transition>" +
  |         				        "<transition to=\"end - doThis2 failed\" name=\"failure\"></transition>" +
  |         				    "</node>" +
  |         				    
  |         				    "<node name=\"doThis3\">" +
  |         				        "<action class=\"com.ecebs.sample.action.DefaultActionHandler\"></action>" +
  |         				        "<transition to=\"join1\" name=\"success\"></transition>" +
  |         				        "<transition to=\"end - doThis3 failed\" name=\"failure\"></transition>" +
  |         				    "</node>" +
  |         				    
  |         				    "<join name=\"join1\">" +
  |         				        "<transition to=\"wait state\"></transition>" +
  |         				    "</join>" +
  |         				    
  |         				    "<state name=\"wait for a\">" +
  |         				        "<transition to=\"doThis2\"></transition>" +
  |         				    "</state>" +
  |         				    
  |         				    "<state name=\"wait for b\">" +
  |         				        "<transition to=\"doThis3\"></transition>" +
  |         				    "</state>" +
  |         				    
  |         				    "<state name=\"wait state\">" +
  |         				        "<transition to=\"end\"></transition>" +
  |         				    "</state>" +
  |         				    
  |         				    "<end-state name=\"end\" />" +
  |         				    "<end-state name=\"end - doThis2 failed\" end-complete-process=\"true\" />" +
  |         				    "<end-state name=\"end - doThis3 failed\" end-complete-process=\"true\" />" +
  |                 		"</process-definition>");
  |         } finally {
  |             ctx.close();
  |         }
  |     }
  |     
  |     @Test
  |     public void testEndStatePass() {
  |         if (log.isDebugEnabled()) {
  |             log.debug("inside testEndState()");
  |         }
  |         
  |         // Create an instance of the process definition.
  |         ProcessInstance instance = new ProcessInstance(processDefinition);
  |         log.debug("ProcessId is " + instance.getId());
  | 
  |         // Signal to Start Process
  |         log.info("Signaling: Start");
  |         signal(instance, null);
  |         
  |         ContextInstance ctxInst = instance.getContextInstance();
  |         ctxInst.setVariable("status", "success");
  |         
  |         // Signal: Waiting for a
  |         log.info("Signaling: Waiting for a");
  |         signal(instance, "a");
  |         
  |         // Signal: Waiting for b
  |         log.info("Signaling: Waiting for b");
  |         signal(instance, "b");
  |         
  |         
  |         // Signal: Exit Wait
  |         log.info("Signaling: Exit Wait");
  |         signal(instance, null);
  |         
  |         Assert.assertEquals(processDefinition.getNode("end"), instance.getRootToken().getNode());
  |     }
  |     
  |     @Test
  |     public void testEndStateFail_doThis2() {
  |         
  |         // Create an instance of the process definition.
  |         ProcessInstance instance = new ProcessInstance(processDefinition);
  |         log.debug("ProcessId is " + instance.getId());
  | 
  |         // Signal to Start Process
  |         log.info("Signaling: Start");
  |         signal(instance, null);
  |         
  |         ContextInstance ctxInst = instance.getContextInstance();
  |         ctxInst.setVariable("status", "failure");
  |         
  |         // Signal: Waiting for a
  |         log.info("Signaling: Waiting for a");
  |         signal(instance, "a");
  |         
  |         ctxInst.setVariable("status", "failure");
  |         
  |         // Signal: Waiting for b
  |         log.info("Signaling: Waiting for b");
  |         signal(instance, "b");
  |                
  |         // Signal: Exit Wait
  |         log.info("Signaling: Exit Wait");
  |         signal(instance, null);
  |         
  |         Assert.assertEquals(processDefinition.getNode("end - doThis2 failed"), instance.getRootToken().getNode());
  |     }
  |     
  |     @Test
  |     public void testEndStateFail_doThis3() {
  |         if (log.isDebugEnabled()) {
  |             log.debug("inside testEndStateFail_doThis3()");
  |         }
  |         
  |         // Create an instance of the process definition.
  |         ProcessInstance instance = new ProcessInstance(processDefinition);
  |         log.debug("ProcessId is " + instance.getId());
  | 
  |         // Signal to Start Process
  |         log.info("Signaling: Start");
  |         signal(instance, null);
  |         
  |         ContextInstance ctxInst = instance.getContextInstance();
  |         ctxInst.setVariable("status", "success");
  |         
  |         // Signal: Waiting for a
  |         log.info("Signaling: Waiting for a");
  |         signal(instance, "a");
  |         
  |         ctxInst.setVariable("status", "failure");
  |         
  |         // Signal: Waiting for b
  |         log.info("Signaling: Waiting for b");
  |         signal(instance, "b");
  |         
  |         
  |         // Signal: Exit Wait
  |         log.info("Signaling: Exit Wait");
  |         signal(instance, null);
  |         
  |         Assert.assertEquals(processDefinition.getNode("end - doThis3 failed"), instance.getRootToken().getNode());
  |     }
  |     
  |     private void signal(ProcessInstance instance, String childKey) {
  |         if (log.isDebugEnabled()) {
  |             log.debug("inside signal(instance, childKey = " + childKey + ")");
  |         }
  | 
  |         Token rootToken = instance.getRootToken();
  |         if (rootToken.hasActiveChildren()) {
  |             Map<?, ?> children = rootToken.getActiveChildren();
  |             if (children.containsKey(childKey)) {
  |                 Token childToken = (Token) children.get(childKey);
  |                 childToken.signal();
  |             } else {
  |                 // TODO handle this
  |                 String msg = "Root Token does not contain, " + childKey;
  |                 log.debug(msg);
  |                 throw new RuntimeException(msg);
  |             }
  |         } else {
  |             rootToken.signal();
  |         }
  |     }
  | }


Cheers Alan

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4156299#4156299

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4156299



More information about the jboss-user mailing list