02-01-2017 12:11 PM
I have a process that involves a series of sensor data incidents which take the form of user tasks to lead to various service tasks being launched. Trouble is the service tasks need to know which incidents caused them to be launched. Simply looking at the history won't work because different incidents may be triggering different service tasks, even simultaneously (or close to). Is there a way for the service task to be passed information related to the previous state(s) that led to it's invocation, or the execution ID's/task ID's that caused it's invocation. Alternatively is there a way for the service task to be able to look back at the previous state(s) somehow to identify which paths led to the invocation so that those tasks could be queried?
02-06-2017 07:37 AM
For anyone else doing something similar, here is the solution I've found. I get the sense that this isn't how the API's were intended to be used, but it seems to achieve what I'm looking for. I really wanted a way to get previous tasks without adding bloat to the BPMN diagram itself.
@Service
public class CorrelationService implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
List<Task> previousTasks = getPreviousTransitionTasks(execution);
}private List<Task> getPreviousTransitionTasks(DelegateExecution execution) {
// Get incoming transitions
List<PvmTransition> incomingTransitions = ((ExecutionEntity)execution)
.getActivity().getIncomingTransitions();
List<Task> tasks = new ArrayList<Task>();
for (PvmTransition transition : incomingTransitions) {
tasks.add(getTaskFromTransition(execution, transition));
}
return tasks;
}private Task getTaskFromTransition(DelegateExecution execution, PvmTransition transition) {
return execution
.getEngineServices().getTaskService()
.createTaskQuery()
.taskId(
getTaskIdFromTransition(execution, transition)
).singleResult();
}private String getTaskIdFromTransition(DelegateExecution execution, PvmTransition transition) {
return execution
.getEngineServices().getHistoryService()
.createHistoricActivityInstanceQuery()
.activityId(
((TransitionImpl) transition).getSource().getId()
)
.singleResult()
.getTaskId();
}
02-02-2017 12:45 AM
HI Brenden R ,
There are various approaches to do this.
- Option 1 - Exclusive Gateway: Have a look at the docs here Activiti User Guide . Exclusive gateway allows you to 'choose' what service task to be executed based on the conditions provided by the user task. However, exclusive gateway will allow only and only 1 flow to be executed. If you need more than 1 service task to be executed at a time, we can go to the next option.
- Option 2 - Inclusive Gateway: Activiti User Guide . Inclusive gateways allow more service tasks to be executed if the condition-to-execute evaluates to true.
- Option 3 - Event Based Gateway: Activiti User Guide . Or you can use event gateway to execute service tasks by intermediate catching event.
- Option 4 - Signals: Have a look at the docs Activiti User Guide . Signal Events allow you implement event subscription/publishing model within the Activiti process. So in your use case, once the user task has completed, it would throw signals e.g. servicetask1-signal, servicetask3-signal. Then you can use the intermediate signal catch event or the signal start event Activiti User Guide to catch them and execute the service tasks as you model. You can place each service task in its own process definition.
I'm sure one of these approaches should help you. Let me know it does not.
Thanks,
Thong Huynh
02-02-2017 09:31 AM
Brandon,
Interesting scenario you have.
For situations like this I like to add "milestones" to the process model (using none send events and associated listener).
I use these to either update a status or in your case I would add the "status" to an array. As each service task fires, you can feed the array in as a parameter and it will know the key state transitions of the process.
Hope this helps,
Greg
02-06-2017 07:37 AM
For anyone else doing something similar, here is the solution I've found. I get the sense that this isn't how the API's were intended to be used, but it seems to achieve what I'm looking for. I really wanted a way to get previous tasks without adding bloat to the BPMN diagram itself.
@Service
public class CorrelationService implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
List<Task> previousTasks = getPreviousTransitionTasks(execution);
}private List<Task> getPreviousTransitionTasks(DelegateExecution execution) {
// Get incoming transitions
List<PvmTransition> incomingTransitions = ((ExecutionEntity)execution)
.getActivity().getIncomingTransitions();
List<Task> tasks = new ArrayList<Task>();
for (PvmTransition transition : incomingTransitions) {
tasks.add(getTaskFromTransition(execution, transition));
}
return tasks;
}private Task getTaskFromTransition(DelegateExecution execution, PvmTransition transition) {
return execution
.getEngineServices().getTaskService()
.createTaskQuery()
.taskId(
getTaskIdFromTransition(execution, transition)
).singleResult();
}private String getTaskIdFromTransition(DelegateExecution execution, PvmTransition transition) {
return execution
.getEngineServices().getHistoryService()
.createHistoricActivityInstanceQuery()
.activityId(
((TransitionImpl) transition).getSource().getId()
)
.singleResult()
.getTaskId();
}
Explore our Alfresco products with the links below. Use labels to filter content by product module.