-
1. Re: How to create a simple waiting workflow
salaboy21 Feb 3, 2012 9:37 AM (in response to espinosa_cz)1 of 1 people found this helpfulYou have an old plugin that's why you are seeing a Wait State there..
You need to add a <task> -> service task node and then write an implementation of the WorkItemHandler class and do not complete the workitem inside the implementation. That will cause your process to wait until you finally decide to complete it.
Cheers
-
2. Re: How to create a simple waiting workflow
swiderski.maciej Feb 4, 2012 1:52 PM (in response to espinosa_cz)1 of 1 people found this helpfulIn my opinion the most sutiable node in BPMN2 for state node from jBPM v4 would be catch intermediateSignalEvent which will wait for an external signal, that should be done either through process instance or session that contains the process instance.
Exanle of BPMN2 file you can find here and sample code that operates on this can be found in testIntermediateCatchEventSignal() method here
HTH
-
3. Re: How to create a simple waiting workflow
espinosa_cz Feb 15, 2012 7:40 PM (in response to salaboy21)Mauricio Salatino wrote:
..You need to add a <task> -> service task node and then write an implementation of the WorkItemHandler class and do not complete the workitem inside the implementation. That will cause your process to wait until you finally decide to complete it...
Good tip. Thank you.
Now I am stuck on how to signalize the custom task (MyWaitTask1WorkItemHandler aka MyWaitTask1) to complete and continue to the next task.
According to this forum post, it is not possible to signalize Tasks, only Events:
In general you cannot just signal any node directly ... however normally you have to model this as a signal event. (by Tihomir Surdilovic)Please, how should I here apply signal event?
Put an Event element after the MyWaitTask1? Or before? Neither give sense.
At the start of a new process "line"? I saw it in some examples. I puzzles me. See my post below.
-
4. Re: How to create a simple waiting workflow
espinosa_cz Feb 15, 2012 8:11 PM (in response to swiderski.maciej)Maciej Swiderski wrote:
Exanle of BPMN2 file you can find here and sample code that operates on this can be found in testIntermediateCatchEventSignal() method here
Thank you.
However it brings more questions then answers
Here is the diagram of that process model:
(/jbpm-examples/src/main/resources/junit/BPMN2-IntermediateCatchEventSignal.bpmn2)
Why there are two lanes? One process, but two lanes. How they are supposed to influence each other?
Note: The "User Task" is a custom task mapped to DoNothingWorkItemHandler, which does nothing, empty handler, but in the task properties is selected "Wait for Completion = true"
The "event" (beginning of the second "line") is the mentioned intermediateCatchEvent task.
I made a bit modified version of this example:
When I re-run test now:
When I start the process, "Print something 1" is printed as expected.
When I send signal to the process, the "Print something 3" is printed, as expected.
And there is end of process.
The "Print something 2" is never reached.
More interestingly, the test is evaluated as "completed" even, despite the process still did not finished the "first line".
Puzzling I have to say.
Yes, I have my wait state, but still no idea how to signalize it to move to the next task.
-
5. Re: How to create a simple waiting workflow
espinosa_cz Feb 23, 2012 1:34 PM (in response to espinosa_cz)OK, I hope I solved it. Any objections against this solution? Any hidden catches?
This works (6a):
This works too (6b):
BPMN2 Code 6a:
<definitions ...> <process processType="Private" isExecutable="true" id="SimpleProcess6a" name="SimpleProcess6a" tns:packageName="defaultPackage" > <!-- nodes --> <startEvent id="_1" name="StartProcess" /> <task id="_4" name="JavaTask6" tns:taskName="JavaTask6" > </task> <intermediateCatchEvent id="_5" name="WaitForSignal" > <signalEventDefinition signalRef="fooSignal"/> </intermediateCatchEvent> <endEvent id="_3" name="EndProcess" /> <!-- connections --> <sequenceFlow id="_5-_3" sourceRef="_5" targetRef="_3" /> <sequenceFlow id="_1-_4" sourceRef="_1" targetRef="_4" /> <sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5" /> </process> </definitions>
BPMN2 Code 6b:
<definitions ...> <process processType="Private" isExecutable="true" id="SimpleProcess6b" name="SimpleProcess6b" tns:packageName="defaultPackage" > <!-- nodes --> <startEvent id="_1" name="StartProcess" /> <task id="_4" name="JavaTask6" tns:taskName="JavaTask6" > </task> <intermediateCatchEvent id="_5" name="Event" > <signalEventDefinition signalRef="fooSignal"/> </intermediateCatchEvent> <parallelGateway id="_6" name="Join" gatewayDirection="Converging" /> <endEvent id="_3" name="EndProcess" /> <!-- connections --> <sequenceFlow id="_6-_3" sourceRef="_6" targetRef="_3" /> <sequenceFlow id="_1-_4" sourceRef="_1" targetRef="_4" /> <sequenceFlow id="_4-_6" sourceRef="_4" targetRef="_6" /> <sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6" /> </process> </definitions>
Code for class behind JavaTask task node:
public class JavaTask6WorkItemHandler implements WorkItemHandler { @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { System.out.println("Inside JavaTask : " + workItem.getName()); // notify manager that work item has been completed // Essential! Custom tasks are by default set "wait for completion = true", this makes them "false" manager.completeWorkItem(workItem.getId(), null); } @Override public void abortWorkItem(WorkItem workItem, WorkItemManager manager) { // do nothing } }
Test run code, start and signalize the process:
public class SimpleProcess6aRun { public static void main(String[] args) { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource("simple_process_6a.bpmn"), ResourceType.BPMN2); KnowledgeBase kbase = kbuilder.newKnowledgeBase(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.getWorkItemManager().registerWorkItemHandler("JavaTask6", new JavaTask6WorkItemHandler()); ProcessInstance processInstance = ksession.startProcess("SimpleProcess6a"); Assert.assertNotNull(processInstance); // print all running processes Collection<ProcessInstance> allProcesses = ksession.getProcessInstances(); for (ProcessInstance p : allProcesses) { System.out.println("Running - " + p); } // test wait state Assert.assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState()); // send signal // ksession.signalEvent("fooSignal", "fooSignal"); // global signal processInstance.signalEvent("fooSignal", null); // process specific signal // test successful finish (test state) Assert.assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); } } // the code for SimpleProcess6bRun (6b process) is analogous
This forum thread is related too. I found Esteban Aliverti comment very helpful and so his examples on github.
Is there any real difference between 6a and 6b? Otherwise I am going to use the simpler variant, without Gateway.
If I have, let's say, process with 20 wait nodes, I have to add 20 more Event nodes after every task?