[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