So we took a different approach as we wanted to use our own human task server. We thought that if we will be notified about changes occurring inside Activiti's engine concerning user tasks (e.g. create task event), we could propagate those notifications to our Human Task Service. Unfortunately, we found out that Activiti's engine does not have a notification mechanism as we hoped (at least in 5.8 - there are talking about an event bus in future releases), so we had to use another mechanism to achieve this task.
Apparently Activiti does have a notification mechanism while parsing a BPMN process definition XML. It allows one to plug in a listener which will be notified in several events. One of those events is when a user task is being parsed. This was exactly what we needed. We plugged our own listener implementation and every time a user task was parsed we added a TaskListenr to the user task in the process definition. This listener was invoked by the engine when this task was created. Obviously the listener impl is to simply send a notification as "Task Created" to our own Human Task Service. Note: you will also have to manage the task life-cycle and update Activiti's engine using its services.
Now for the technical details. As in our latest post, this requires:
- adding a Java class implementing BpmnParseListener. This is the interface you want to implement to plug in your own listener.
- injecting the Java class using the Spring xml config file.
BpmnParseListener Class
We implement a TaskListener for each of the events we are interested in:
- CompleteTaskListenerImpl
- AssigneTaskListenerImpl
- CreateTaskListenerImpl
We Override the parseUserTask method so that in each time a parse event occurs our TaskListeners will add some logic on our WS-HumanTask Service/Task Service. The rest of the parse events will be ignored.
1: package my.great.company.com.businessprocessengine.listeners;
2: import java.util.ArrayList;
3:
4:
5: public class MyBpmnParseListener implements BpmnParseListener
6: {
7:
8: private final class CompleteTaskListenerImpl implements TaskListener {
9: @Override
10: public void notify(DelegateTask delegateTask) {
11: //TODO: this is where your logic should be added
12: logger.info("TASK COMPLETE from Activiti " + delegateTask.toString());
13: }
14: }
15:
16: private final class AssigneTaskListenerImpl implements TaskListener {
17: @Override
18: public void notify(DelegateTask delegateTask) {
19: //TODO: this is where your logic should be added
20: logger.info("TASK ASSIGN from Activiti " + delegateTask.toString());
21: }
22: }
23:
24: private final class CreateTaskListenerImpl implements TaskListener {
25: @Override
26: public void notify(DelegateTask delegateTask) {
27: //TODO: this is where your logic should be added
28: logger.info("TASK CREATE from Activiti " + taskEntity.toString());
29: }
30: }
31:
32: private TaskListener createTaskListener = new CreateTaskListenerImpl();
33: private TaskListener assigneTaskListener = new AssigneTaskListenerImpl();
34: private TaskListener completeTaskListener = new CompleteTaskListenerImpl();
35: private static final Logger logger = Logger.getLogger(MyBpmnParseListener.class);
36:
37:
38: public MyBpmnParseListener(){}
39:
40: @Override
41: public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity)
42: {
43: ActivityBehavior activitybehaviour = activity.getActivityBehavior();
44: if (activitybehaviour instanceof UserTaskActivityBehavior)
45: {
46: UserTaskActivityBehavior userTaskActivity = (UserTaskActivityBehavior) activitybehaviour;
47: if (createTaskListener != null)
48: {
49: userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_CREATE, createTaskListener);
50: }
51: if (assigneTaskListener != null)
52: {
53: userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT,assigneTaskListener);
54: }
55: if (completeTaskListener != null)
56: {
57: userTaskActivity.sgetTaskDefinition().addTaskListener(TaskListener.EVENTNAME_COMPLETE,completeTaskListener);
58: }
59: }
60: }
61:
62: @Override
63: public void parseRootElement(Element arg0, List<ProcessDefinitionEntity> arg1)
64: {
65: // Nothing to do here
66: }
67:
68: @Override
69: public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition)
70: {
71: // Nothing to do here
72: }
73:
74: @Override
75: public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity)
76: {
77: // Nothing to do here
78: }
79:
80: @Override
81: public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity)
82: {
83: // Nothing to do here
84: }
85:
86: @Override
87: public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity)
88: {
89: // Nothing to do here
90: }
91:
92: @Override
93: public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity)
94: {
95: // Nothing to do here
96: }
97:
98: @Override
99: public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity)
100: {
101: // Nothing to do here
102: }
103:
104: @Override
105: public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity)
106: {
107: // Nothing to do here
108: }
109:
110: @Override
111: public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity)
112: {
113: // Nothing to do here
114: }
115:
116: @Override
117: public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity)
118: {
119: // Nothing to do here
120: }
121:
122: @Override
123: public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting,
124: ActivityImpl timerActivity)
125: {
126: // Nothing to do here
127: }
128:
129: @Override
130: public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity)
131: {
132: // Nothing to do here
133: }
134:
135: @Override
136: public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity)
137: {
138: // Nothing to do here
139: }
140:
141: @Override
142: public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity)
143: {
144: // Nothing to do here
145: }
146:
147: @Override
148: public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition)
149: {
150: // Nothing to do here
151: }
152:
153: @Override
154: public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity)
155: {
156: // Nothing to do here
157: }
158:
159: @Override
160: public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity)
161: {
162: // Nothing to do here
163: }
164:
165: @Override
166: public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting,
167: ActivityImpl activity, ActivityImpl nestedErrorEventActivity)
168: {
169: // Nothing to do here
170: }
171:
172: @Override
173: public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity)
174: {
175: // Nothing to do here
176: }
177:
178: @Override
179: public void parseMultiInstanceLoopCharacteristics(Element activityElement,
180: Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity)
181: {
182: // Nothing to do here
183: }
184:
185: @Override
186: public void parseInclusiveGateway(Element arg0, ScopeImpl arg1, ActivityImpl arg2) {
187: // Nothing to do here
188:
189: }
190: }
Spring configuration
The Spring file change will be done in our context XML file:
1: ...
2: <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
3: ...
4: <property name="preParseListeners">
5: <list>
6: <bean class="my.great.company.com.businessprocessengine.listeners.MyBpmnParseListener"></bean>
7: </list>
8: </property>
9: ...
10: </bean>...
That's it. You are good to go and handle tasks on your own. Good luck.
i search internet for one activiti samples
ReplyDeletecan you give me one
aa.azizkhani@gmail.com