diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java index caa4b0f877..be3312bf7f 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java @@ -52,9 +52,11 @@ import org.activiti.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior; import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.activiti.engine.impl.bpmn.deployer.BpmnDeployer; import org.activiti.engine.impl.bpmn.diagram.ProcessDiagramGenerator; +import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.form.DefaultTaskFormHandler; import org.activiti.engine.impl.form.TaskFormHandler; import org.activiti.engine.impl.identity.Authentication; +import org.activiti.engine.impl.interceptor.CommandContext; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.persistence.entity.TimerEntity; @@ -985,16 +987,35 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine } // Start the process-instance - ProcessInstance instance = runtimeService.startProcessInstanceById(processDefId, variables); - if(instance.isEnded()) + CommandContext context = Context.getCommandContext(); + boolean isContextSuspended = false; + if (context != null && context.getException() == null) { - return typeConverter.buildCompletedPath(instance.getId(), instance.getId()); - } - else + // MNT-11926: push null context to stack to avoid context reusage when new instance is not flushed + Context.setCommandContext(null); + isContextSuspended = true; + } + try { - WorkflowPath path = typeConverter.convert((Execution)instance); - endStartTaskAutomatically(path, instance); - return path; + ProcessInstance instance = runtimeService.startProcessInstanceById(processDefId, variables); + if (instance.isEnded()) + { + return typeConverter.buildCompletedPath(instance.getId(), instance.getId()); + } + else + { + WorkflowPath path = typeConverter.convert((Execution) instance); + endStartTaskAutomatically(path, instance); + return path; + } + } + finally + { + if (isContextSuspended) + { + // pop null context out of stack + Context.removeCommandContext(); + } } } catch (ActivitiException ae) diff --git a/source/test-java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java b/source/test-java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java index 4dafe83f86..5ea8231eb7 100644 --- a/source/test-java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java +++ b/source/test-java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java @@ -86,7 +86,7 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT protected TestPersonManager personManager; protected TestGroupManager groupManager; protected NodeService nodeService; - private NodeRef companyHome; + protected NodeRef companyHome; protected WorkflowTestHelper wfTestHelper; protected TransactionServiceImpl transactionService; diff --git a/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java b/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java index 29f5ffac00..f0c3dfee1b 100644 --- a/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java +++ b/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java @@ -28,11 +28,13 @@ import java.util.List; import java.util.Map; import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.workflow.AbstractWorkflowServiceIntegrationTest; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowPath; @@ -382,6 +384,39 @@ public class ActivitiWorkflowServiceIntegrationTest extends AbstractWorkflowServ checkNoTasksFoundUsingQuery(taskQuery); } + public void testStartWorkflowFromTaskListener() throws Exception + { + WorkflowDefinition testDefinition = deployDefinition("activiti/testStartWfFromListener.bpmn20.xml"); + + AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser(); + + Map props = new HashMap(); + props.put(ContentModel.PROP_NAME, "MNT-11926-testfile.txt"); + final ChildAssociationRef childAssoc = nodeService.createNode(companyHome, ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, "MNT-11926-test"), ContentModel.TYPE_CONTENT, props); + + try + { + // Create workflow parameters + Map params = new HashMap(); + Serializable wfPackage = workflowService.createPackage(null); + params.put(WorkflowModel.ASSOC_PACKAGE, wfPackage); + NodeRef assignee = personManager.get(USER1); + params.put(WorkflowModel.ASSOC_ASSIGNEE, assignee); // task instance field + + WorkflowPath path = workflowService.startWorkflow(testDefinition.getId(), params); + String instanceId = path.getInstance().getId(); + + WorkflowTask startTask = workflowService.getStartTask(instanceId); + workflowService.endTask(startTask.getId(), null); + } + finally + { + // tidy up + nodeService.deleteNode(childAssoc.getChildRef()); + } + } + @Override protected String getEngine() { diff --git a/source/test-resources/activiti/testStartWfFromListener.bpmn20.xml b/source/test-resources/activiti/testStartWfFromListener.bpmn20.xml new file mode 100644 index 0000000000..65da565105 --- /dev/null +++ b/source/test-resources/activiti/testStartWfFromListener.bpmn20.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + var wfdef = workflow.getDefinitionByName("activiti$activitiReview"); + var wfparams = new Object(); + wfparams["bpm:workflowDescription"] = "Start workflow JS - "; + wfparams["bpm:assignee"] = people.getPerson("admin"); + var wfpackage = workflow.createPackage(); + wfpackage.addNode(search.luceneSearch("+PATH:\"/app:company_home/*\" +@cm\\:name:\"MNT-11926-testfile.txt\"")[0]); + wfdef.startWorkflow(wfpackage,wfparams); + + + + + + + ${bpm_assignee.properties.userName} + + + + + + + + + Verify the task was completed. + + + + + + if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate + if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority; + + if (wf_notifyMe) + { + var mail = actions.create("mail"); + mail.parameters.to = initiator.properties.email; + mail.parameters.subject = "Adhoc Task " + bpm_workflowDescription; + mail.parameters.from = bpm_assignee.properties.email; + mail.parameters.text = "It's done"; + mail.execute(bpm_package); + } + + + + + + + ${initiator.exists() ? initiator.properties.userName : 'admin'} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file