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
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user