Alfresco Summit 2013 · Synchronizing Alfresco Activiti User Tasks with External Systems

Alfresco Summit Barcelona Agenda includes “Synchronizing Alfresco Activiti User Tasks with External Systems” at Lightning Talks #2 session.

This presentation shows how user tasks status, managed by Activiti inside Alfresco, can be synchronized with any other system. By using Activiti parser extension, customized listeners can be assigned for every workflow launched in Alfresco. Once each of the events associated to this listeners has been triggered, synchronization operations can be performed.

You can find a source code template, as an Alfresco AMP module, at https://github.com/keensoft/alfresco-user-task-listener. Feel free to provide an ExternalTaskSystem implementation and let me know your comments.

#SummitNow

Anuncios

Alfresco · Listener genérico para tareas de Activiti (II)

En el artículo anterior sobre este tema, se crearon listener para capturar la creación y la terminación de tareas de usuario en Alfresco. No obstante, con este mecanismo no es posible capturar las tareas canceladas. Una tarea es cancelada cuando el usuario que ha iniciado el flujo, decide cancelarlo.

Para capturar este evento, es necesario interceptar el método parseRootElement de listener de BPMN.

public class CustomUserTaskListener implements BpmnParseListener {
	
	public void parseUserTask(Element element, ScopeImpl scope, ActivityImpl activity) {
		
        ActivityBehavior activitybehaviour = activity.getActivityBehavior();
        
        if (activitybehaviour instanceof UserTaskActivityBehavior) {
        	
        	UserTaskActivityBehavior userTaskActivity = (UserTaskActivityBehavior) activitybehaviour;
            userTaskActivity.getTaskDefinition().
                addTaskListener(TaskListener.EVENTNAME_CREATE, new CustomTaskCreateListener());
            userTaskActivity.getTaskDefinition().
                addTaskListener(TaskListener.EVENTNAME_COMPLETE, new CustomTaskCompleteListener()); 
            
        }
        
	}
	
	@Override
	public void parseRootElement(Element element, List<ProcessDefinitionEntity> processes) {
		
        for (ProcessDefinitionEntity processDefinition : processes) {
            processDefinition.
                addExecutionListener(ExecutionListener.EVENTNAME_END, new ProcessEndExecutionListener());
        }
		
	}
}

En la implementación del listener, las tareas pendientes tras la cancelación de un flujo pueden ser recuperadas para informar a un sistema externo.

/**
 * Delete task WS invocation on workflow cancel event.
 * No CANCEL EVENT available on TaskListener.
 */
public class ProcessEndExecutionListener extends ActivitiScriptBase implements ExecutionListener {
	
	private static final Log logger = LogFactory.getLog(ProcessEndExecutionListener.class);

	// Activiti flows are prefixed with an special ID
	private static final String ACTIVITI_PREFIX = "activiti$";

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		
		ExecutionListenerExecution listenerExecution = (ExecutionListenerExecution) execution;
		
		WorkflowTaskQuery workflowTaskQuery = new WorkflowTaskQuery();
    	workflowTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
    	workflowTaskQuery.setProcessId(ACTIVITI_PREFIX + listenerExecution.getProcessInstanceId());
        List<WorkflowTask> tasks = 
            getServiceRegistry().getWorkflowService().queryTasks(workflowTaskQuery, true);

        for (WorkflowTask task : tasks) {
        	ExecutorService executorService = Executors.newSingleThreadExecutor();
        	executorService.execute(new WSInvocatorTask(task));
        	executorService.shutdown();
        }
		
	}

	private class WSInvocatorTask implements Runnable {
		
		private WorkflowTask task;
		
		public WSInvocatorTask(WorkflowTask task) {
			this.task = task;
		}

		@Override
		public void run() {
			
			String taskId = task.getId();
			if (task.getId().startsWith(ACTIVITI_PREFIX)) {
				taskId = taskId.substring(ACTIVITI_PREFIX.length(), taskId.length());
			}

			// Perform any action with task
			// ...
		}
		
	}

}