Fixes for history processes and tasks, support for bpm_assignees, and fix for task update response

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54547 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tijs Rademakers
2013-08-28 10:05:33 +00:00
parent 354010d090
commit 2881f31d3f
8 changed files with 481 additions and 224 deletions

View File

@@ -90,7 +90,6 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.InvalidQNameException; import org.alfresco.service.namespace.InvalidQNameException;
@@ -102,50 +101,53 @@ import org.apache.commons.io.IOUtils;
public class ProcessesImpl extends WorkflowRestImpl implements Processes public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
private WorkflowPackageImpl workflowPackageComponent; protected static final String BPM_PACKAGE = "bpm_package";
private ServiceRegistry serviceRegistry;
private AuthorityDAO authorityDAO;
private NodeService nodeService;
private PersonService personService;
private MessageService messageService;
private String engineId;
private Repository repositoryHelper;
private RestVariableHelper restVariableHelper;
private ActivitiNodeConverter nodeConverter;
private ActivitiUtil activitiUtil;
private DefaultWorkflowPropertyHandler defaultPropertyHandler;
private WorkflowQNameConverter qNameConverter;
private QName defaultStartTaskType = WorkflowModel.TYPE_ACTIVTI_START_TASK;
private WorkflowObjectFactory workflowFactory;
private WorkflowPropertyHandlerRegistry handlerRegistry;
private WorkflowAuthorityManager authorityManager;
private ActivitiPropertyConverter propertyConverter;
private ActivitiTypeConverter typeConverter;
protected static String PROCESS_STATUS_ANY = "any"; protected static String PROCESS_STATUS_ANY = "any";
protected static String PROCESS_STATUS_ACTIVE = "active"; protected static String PROCESS_STATUS_ACTIVE = "active";
protected static String PROCESS_STATUS_COMPLETED = "completed"; protected static String PROCESS_STATUS_COMPLETED = "completed";
private static final Set<String> PROCESS_STATUS_LIST = new HashSet<String>(Arrays.asList(
protected static final Set<String> PROCESS_STATUS_LIST = new HashSet<String>(Arrays.asList(
PROCESS_STATUS_ANY, PROCESS_STATUS_ACTIVE, PROCESS_STATUS_COMPLETED PROCESS_STATUS_ANY, PROCESS_STATUS_ACTIVE, PROCESS_STATUS_COMPLETED
)); ));
private static final Set<String> PROCESS_COLLECTION_EQUALS_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList( protected static final Set<String> PROCESS_COLLECTION_EQUALS_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList(
"processDefinitionId", "businessKey", "processDefinitionKey", "startUserId", "status" "processDefinitionId", "businessKey", "processDefinitionKey", "startUserId", "status"
)); ));
private static final Set<String> PROCESS_COLLECTION_GREATERTHAN_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList( protected static final Set<String> PROCESS_COLLECTION_GREATERTHAN_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList(
"startedAt", "endedAt" "startedAt", "endedAt"
)); ));
private static final Set<String> PROCESS_COLLECTION_LESSTHAN_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList( protected static final Set<String> PROCESS_COLLECTION_LESSTHAN_QUERY_PROPERTIES = new HashSet<String>(Arrays.asList(
"startedAt", "endedAt" "startedAt", "endedAt"
)); ));
private static final Set<String> PROCESS_COLLECTION_SORT_PROPERTIES = new HashSet<String>(Arrays.asList( protected static final Set<String> PROCESS_COLLECTION_SORT_PROPERTIES = new HashSet<String>(Arrays.asList(
"processDefinitionId", "businessKey", "id", "startedAt", "endedAt", "durationInMillis" "processDefinitionId", "businessKey", "id", "startedAt", "endedAt", "durationInMillis"
)); ));
protected WorkflowPackageImpl workflowPackageComponent;
protected ServiceRegistry serviceRegistry;
protected AuthorityDAO authorityDAO;
protected NodeService nodeService;
protected PersonService personService;
protected MessageService messageService;
protected String engineId;
protected Repository repositoryHelper;
protected RestVariableHelper restVariableHelper;
protected ActivitiNodeConverter nodeConverter;
protected ActivitiUtil activitiUtil;
protected DefaultWorkflowPropertyHandler defaultPropertyHandler;
protected WorkflowQNameConverter qNameConverter;
protected QName defaultStartTaskType = WorkflowModel.TYPE_ACTIVTI_START_TASK;
protected WorkflowObjectFactory workflowFactory;
protected WorkflowPropertyHandlerRegistry handlerRegistry;
protected WorkflowAuthorityManager authorityManager;
protected ActivitiPropertyConverter propertyConverter;
protected ActivitiTypeConverter typeConverter;
public void setAuthorityDAO(AuthorityDAO authorityDAO) public void setAuthorityDAO(AuthorityDAO authorityDAO)
{ {
this.authorityDAO = authorityDAO; this.authorityDAO = authorityDAO;
@@ -532,7 +534,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("Either processDefinitionId or processDefinitionKey is required"); throw new InvalidArgumentException("Either processDefinitionId or processDefinitionKey is required");
} }
if(!definitionExistingChecked) if (definitionExistingChecked == false)
{ {
// Check if the required definition actually exists // Check if the required definition actually exists
ProcessDefinitionQuery query = activitiProcessEngine ProcessDefinitionQuery query = activitiProcessEngine
@@ -584,11 +586,71 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
AssociationDefinition associationDef = taskAssociations.get(propNameMap.get(variableName)); AssociationDefinition associationDef = taskAssociations.get(propNameMap.get(variableName));
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName())) if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
{ {
variableValue = getPersonNodeRef(variableValue.toString()); if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> personList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef personRef = getPersonNodeRef(value.toString());
if (personRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
}
personList.add(personRef);
}
variableValue = personList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef personRef = getPersonNodeRef(variableValue.toString());
if (personRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
}
variableValue = personRef;
}
} }
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName())) else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
{ {
variableValue = authorityService.getAuthorityNodeRef(variableValue.toString()); if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> authorityList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
}
authorityList.add(authorityRef);
}
variableValue = authorityList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
}
variableValue = authorityRef;
}
} }
} }
@@ -621,7 +683,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
for (String item: process.getItems()) for (String item: process.getItems())
{ {
NodeRef itemNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, item); NodeRef itemNodeRef = getNodeRef(item);
QName workflowPackageItemId = QName.createQName("wpi", itemNodeRef.toString()); QName workflowPackageItemId = QName.createQName("wpi", itemNodeRef.toString());
nodeService.addChild(workflowPackageNodeRef, itemNodeRef, WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId); nodeService.addChild(workflowPackageNodeRef, itemNodeRef, WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId);
} }
@@ -680,7 +742,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
public void deleteProcess(String id) public void deleteProcess(String id)
{ {
validateIfUserAllowedToWorkWithProcess(id); validateIfUserAllowedToWorkWithProcess(id);
activitiProcessEngine.getRuntimeService().deleteProcessInstance(id, null); activitiProcessEngine.getRuntimeService().deleteProcessInstance(id, "deleted through REST API call");
} }
@Override @Override
@@ -696,9 +758,22 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
ActivitiScriptNode packageScriptNode = null; ActivitiScriptNode packageScriptNode = null;
try try
{ {
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, "bpm_package"); HistoricVariableInstance variableInstance = activitiProcessEngine.getHistoryService()
.createHistoricVariableInstanceQuery()
.processInstanceId(processId)
.variableName(BPM_PACKAGE)
.singleResult();
if (variableInstance != null)
{
packageScriptNode = (ActivitiScriptNode) variableInstance.getValue();
}
else
{
throw new EntityNotFoundException(processId);
}
} }
catch(ActivitiObjectNotFoundException e) catch (ActivitiObjectNotFoundException e)
{ {
throw new EntityNotFoundException(processId); throw new EntityNotFoundException(processId);
} }
@@ -730,14 +805,29 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("itemId is required to get an attached item"); throw new InvalidArgumentException("itemId is required to get an attached item");
} }
NodeRef nodeRef = getNodeRef(itemId);
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
ActivitiScriptNode packageScriptNode = null; ActivitiScriptNode packageScriptNode = null;
try try
{ {
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, "bpm_package"); HistoricVariableInstance variableInstance = activitiProcessEngine.getHistoryService()
.createHistoricVariableInstanceQuery()
.processInstanceId(processId)
.variableName(BPM_PACKAGE)
.singleResult();
if (variableInstance != null)
{
packageScriptNode = (ActivitiScriptNode) variableInstance.getValue();
}
else
{
throw new EntityNotFoundException(processId);
}
} }
catch(ActivitiObjectNotFoundException e) catch (ActivitiObjectNotFoundException e)
{ {
throw new EntityNotFoundException(processId); throw new EntityNotFoundException(processId);
} }
@@ -748,7 +838,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef()); List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList) for (ChildAssociationRef childAssociationRef : documentList)
{ {
if (childAssociationRef.getChildRef().getId().equals(itemId)) if (childAssociationRef.getChildRef().equals(nodeRef))
{ {
item = createItemForNodeRef(childAssociationRef.getChildRef()); item = createItemForNodeRef(childAssociationRef.getChildRef());
break; break;
@@ -778,10 +868,12 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
NodeRef nodeRef = getNodeRef(item.getId());
ActivitiScriptNode packageScriptNode = null; ActivitiScriptNode packageScriptNode = null;
try try
{ {
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, "bpm_package"); packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
} }
catch (ActivitiObjectNotFoundException e) catch (ActivitiObjectNotFoundException e)
{ {
@@ -796,18 +888,17 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
// check if noderef exists // check if noderef exists
try try
{ {
nodeService.getProperties(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, item.getId())); nodeService.getProperties(nodeRef);
} }
catch (Exception e) catch (Exception e)
{ {
throw new EntityNotFoundException("item with id " + item.getId() + " not found"); throw new EntityNotFoundException("item with id " + nodeRef.toString() + " not found");
} }
try try
{ {
NodeRef itemNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, item.getId()); QName workflowPackageItemId = QName.createQName("wpi", nodeRef.toString());
QName workflowPackageItemId = QName.createQName("wpi", itemNodeRef.toString()); nodeService.addChild(packageScriptNode.getNodeRef(), nodeRef,
nodeService.addChild(packageScriptNode.getNodeRef(), itemNodeRef,
WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId); WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId);
} }
catch (Exception e) catch (Exception e)
@@ -831,12 +922,14 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("itemId is required to delete an attached item"); throw new InvalidArgumentException("itemId is required to delete an attached item");
} }
NodeRef nodeRef = getNodeRef(itemId);
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
ActivitiScriptNode packageScriptNode = null; ActivitiScriptNode packageScriptNode = null;
try try
{ {
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, "bpm_package"); packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
} }
catch (ActivitiObjectNotFoundException e) catch (ActivitiObjectNotFoundException e)
{ {
@@ -852,7 +945,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef()); List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList) for (ChildAssociationRef childAssociationRef : documentList)
{ {
if (childAssociationRef.getChildRef().getId().equals(itemId)) if (childAssociationRef.getChildRef().equals(nodeRef))
{ {
itemIdFoundInPackage = true; itemIdFoundInPackage = true;
break; break;
@@ -866,7 +959,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
try try
{ {
nodeService.removeChild(packageScriptNode.getNodeRef(), new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, itemId)); nodeService.removeChild(packageScriptNode.getNodeRef(), nodeRef);
} }
catch (InvalidNodeRefException e) catch (InvalidNodeRefException e)
{ {
@@ -879,49 +972,43 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
CollectionWithPagingInfo<Variable> result = null; CollectionWithPagingInfo<Variable> result = null;
// Check if user is allowed to gte variabled // Check if user is allowed to get variables
validateIfUserAllowedToWorkWithProcess(processId); List<HistoricVariableInstance> variableInstances = validateIfUserAllowedToWorkWithProcess(processId);
Map<String, Object> variables = new HashMap<String, Object>();
for (HistoricVariableInstance variable : variableInstances)
{
variables.put(variable.getVariableName(), variable.getValue());
}
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery() ProcessInstance processInstance = activitiProcessEngine.getRuntimeService()
.processInstanceId(processId).singleResult(); .createProcessInstanceQuery()
.processInstanceId(processId)
.singleResult();
String processDefinitionId = null; String processDefinitionId = null;
Map<String, Object> variables = null;
if(processInstance != null) if (processInstance != null)
{ {
// Fetch actual variables from activiti
variables = activitiProcessEngine.getRuntimeService().getVariables(processId);
processDefinitionId = processInstance.getProcessDefinitionId(); processDefinitionId = processInstance.getProcessDefinitionId();
} }
else else
{ {
// Completed task // Completed process instance
HistoricProcessInstance historicInstance = activitiProcessEngine.getHistoryService().createHistoricProcessInstanceQuery() HistoricProcessInstance historicInstance = activitiProcessEngine.getHistoryService().createHistoricProcessInstanceQuery()
.processInstanceId(processId).singleResult(); .processInstanceId(processId).singleResult();
if(historicInstance == null) if (historicInstance == null)
{ {
throw new EntityNotFoundException(processId); throw new EntityNotFoundException(processId);
} }
processDefinitionId = historicInstance.getProcessDefinitionId(); processDefinitionId = historicInstance.getProcessDefinitionId();
// Fetch actual variables from activiti
List<HistoricVariableInstance> varInstances = activitiProcessEngine.getHistoryService()
.createHistoricVariableInstanceQuery().processInstanceId(processId).list();
variables = new HashMap<String, Object>();
for(HistoricVariableInstance var : varInstances)
{
variables.put(var.getVariableName(), var.getValue());
}
} }
// Get start-task definition for explicit typing of variables submitted at the start // Get start-task definition for explicit typing of variables submitted at the start
String formKey = null; String formKey = null;
StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(processDefinitionId); StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(processDefinitionId);
if(startFormData != null) if (startFormData != null)
{ {
formKey = startFormData.getFormKey(); formKey = startFormData.getFormKey();
} }
@@ -939,8 +1026,10 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery() ProcessInstance processInstance = activitiProcessEngine.getRuntimeService()
.processInstanceId(processId).singleResult(); .createProcessInstanceQuery()
.processInstanceId(processId)
.singleResult();
if (processInstance == null) if (processInstance == null)
{ {
@@ -955,8 +1044,10 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery() ProcessInstance processInstance = activitiProcessEngine.getRuntimeService()
.processInstanceId(processId).singleResult(); .createProcessInstanceQuery()
.processInstanceId(processId)
.singleResult();
if (processInstance == null) if (processInstance == null)
{ {
@@ -1036,7 +1127,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
try try
{ {
if(!activitiProcessEngine.getRuntimeService().hasVariable(processId, variableName)) if (activitiProcessEngine.getRuntimeService().hasVariable(processId, variableName) == false)
{ {
throw new EntityNotFoundException(variableName); throw new EntityNotFoundException(variableName);
} }
@@ -1053,10 +1144,12 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{ {
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery() ProcessInstance processInstance = activitiProcessEngine.getRuntimeService()
.processInstanceId(processId).singleResult(); .createProcessInstanceQuery()
.processInstanceId(processId)
.singleResult();
if(processInstance == null) if (processInstance == null)
{ {
throw new EntityNotFoundException(processId); throw new EntityNotFoundException(processId);
} }
@@ -1162,7 +1255,8 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
item.setCreatedBy(createdBy); item.setCreatedBy(createdBy);
item.setModifiedAt(modifiedAt); item.setModifiedAt(modifiedAt);
item.setModifiedBy(modifiedBy); item.setModifiedBy(modifiedBy);
if (contentData != null) { if (contentData != null)
{
item.setMimeType(contentData.getMimetype()); item.setMimeType(contentData.getMimetype());
item.setSize(contentData.getSize()); item.setSize(contentData.getSize());
} }

View File

@@ -85,12 +85,12 @@ public class RestVariableHelper
List<TaskVariable> result = new ArrayList<TaskVariable>(); List<TaskVariable> result = new ArrayList<TaskVariable>();
TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition); TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition);
if(localVariables != null) if (localVariables != null)
{ {
addTaskVariables(result, localVariables, context, VariableScope.LOCAL); addTaskVariables(result, localVariables, context, VariableScope.LOCAL);
} }
if(globalVariables != null) if (globalVariables != null)
{ {
addTaskVariables(result, globalVariables, context, VariableScope.GLOBAL); addTaskVariables(result, globalVariables, context, VariableScope.GLOBAL);
} }

View File

@@ -21,17 +21,19 @@ package org.alfresco.rest.workflow.api.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.activiti.engine.ActivitiTaskAlreadyClaimedException; import org.activiti.engine.ActivitiTaskAlreadyClaimedException;
import org.activiti.engine.form.FormData;
import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery; import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.task.TaskDefinition; import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.IdentityLink; import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType; import org.activiti.engine.task.IdentityLinkType;
import org.activiti.engine.task.TaskQuery; import org.activiti.engine.task.TaskQuery;
@@ -643,7 +645,8 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
TaskStateTransition taskAction = null; TaskStateTransition taskAction = null;
List<String> selectedProperties = parameters.getSelectedProperties(); List<String> selectedProperties = parameters.getSelectedProperties();
if(selectedProperties.contains("state")) { if (selectedProperties.contains("state"))
{
taskAction = TaskStateTransition.getTaskActionFromString(task.getState()); taskAction = TaskStateTransition.getTaskActionFromString(task.getState());
} }
@@ -651,7 +654,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
TaskQuery query = activitiProcessEngine.getTaskService().createTaskQuery().taskId(taskId); TaskQuery query = activitiProcessEngine.getTaskService().createTaskQuery().taskId(taskId);
org.activiti.engine.task.Task taskInstance = query.singleResult(); org.activiti.engine.task.Task taskInstance = query.singleResult();
if(taskInstance == null) if (taskInstance == null)
{ {
// Check if task exists in history, to be able to return appropriate error when trying to update an // Check if task exists in history, to be able to return appropriate error when trying to update an
// existing completed task vs. an unexisting task vs. unauthorized // existing completed task vs. an unexisting task vs. unauthorized
@@ -659,7 +662,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.taskId(taskId) .taskId(taskId)
.count() > 0; .count() > 0;
if(taskHasExisted) if (taskHasExisted)
{ {
throw new UnsupportedResourceOperationException("Task with id: " + taskId + " cannot be updated, it's completed"); throw new UnsupportedResourceOperationException("Task with id: " + taskId + " cannot be updated, it's completed");
} }
@@ -679,7 +682,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
Set<String> candidateGroups = new HashSet<String>(); Set<String> candidateGroups = new HashSet<String>();
if(!authorized) if (!authorized)
{ {
// Check if user is initiator of the process this task is involved with // Check if user is initiator of the process this task is involved with
List<IdentityLink> linksForTask = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId); List<IdentityLink> linksForTask = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId);
@@ -707,7 +710,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
} }
// When claiming, a limited update (set assignee through claim) is allowed // When claiming, a limited update (set assignee through claim) is allowed
if(!authorized && taskAction == TaskStateTransition.CLAIMED) if (!authorized && taskAction == TaskStateTransition.CLAIMED)
{ {
Set<String> userGroups = authorityService.getAuthoritiesForUser(user); Set<String> userGroups = authorityService.getAuthoritiesForUser(user);
for(String group : candidateGroups) for(String group : candidateGroups)
@@ -720,7 +723,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
} }
} }
if(!authorized) if (!authorized)
{ {
// None of the above conditions are met, not authorized to update task // None of the above conditions are met, not authorized to update task
throw new PermissionDeniedException(); throw new PermissionDeniedException();
@@ -728,10 +731,10 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
} }
// Update fields if no action is required // Update fields if no action is required
if(taskAction == null) if (taskAction == null)
{ {
// Only update task in Activiti API if actual properties are changed // Only update task in Activiti API if actual properties are changed
if(updateTaskProperties(selectedProperties, task, taskInstance)) if (updateTaskProperties(selectedProperties, task, taskInstance))
{ {
activitiProcessEngine.getTaskService().saveTask(taskInstance); activitiProcessEngine.getTaskService().saveTask(taskInstance);
} }
@@ -739,8 +742,8 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
else else
{ {
// Perform actions associated to state transition // Perform actions associated to state transition
if(taskAction != null) { if (taskAction != null) {
switch(taskAction) { switch (taskAction) {
case CLAIMED: case CLAIMED:
try try
{ {
@@ -780,34 +783,46 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
} }
} }
if(taskAction == TaskStateTransition.COMPLETED) Task responseTask = new Task(activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.taskId(taskId).singleResult());
// if the task is not ended the task state might be pending or resolved
if (responseTask.getEndedAt() == null)
{ {
// Task completed, fetch from history instead of returning runtime instance try
return new Task(activitiProcessEngine.getHistoryService() {
.createHistoricTaskInstanceQuery() org.activiti.engine.task.Task runningTask = activitiProcessEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
.taskId(taskId).singleResult()); if (runningTask != null)
} {
else if (runningTask.getDelegationState() == DelegationState.PENDING)
{ {
// Task object updated, can return the object without fetching it agian responseTask.setState(TaskStateTransition.DELEGATED.name().toLowerCase());
return new Task(taskInstance); }
else if (runningTask.getDelegationState() == DelegationState.RESOLVED)
{
responseTask.setState(TaskStateTransition.RESOLVED.name().toLowerCase());
}
}
}
catch (Exception e)
{
// ignore the exception
}
} }
return responseTask;
} }
@Override @Override
public CollectionWithPagingInfo<FormModelElement> getTaskFormModel(String taskId, Paging paging) public CollectionWithPagingInfo<FormModelElement> getTaskFormModel(String taskId, Paging paging)
{ {
// Check if task can be accessed by the current user // Check if task can be accessed by the current user
getValidTask(taskId, false); HistoricTaskInstance task = getValidHistoricTask(taskId, true);
String formKey = task.getFormKey();
FormData formData = activitiProcessEngine.getFormService().getTaskFormData(taskId);
if(formData == null)
{
throw new EntityNotFoundException(taskId);
}
// Lookup type definition for the task // Lookup type definition for the task
TypeDefinition taskType = getWorkflowFactory().getTaskFullTypeDefinition(formData.getFormKey(), true); TypeDefinition taskType = getWorkflowFactory().getTaskFullTypeDefinition(formKey, true);
return getFormModelElements(taskType, paging); return getFormModelElements(taskType, paging);
} }
@@ -815,21 +830,44 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
public CollectionWithPagingInfo<TaskVariable> getTaskVariables(String taskId, Paging paging, VariableScope scope) public CollectionWithPagingInfo<TaskVariable> getTaskVariables(String taskId, Paging paging, VariableScope scope)
{ {
// Ensure the user is allowed to get variables for the task involved. // Ensure the user is allowed to get variables for the task involved.
org.activiti.engine.task.Task taskInstance = getValidTask(taskId, true); HistoricTaskInstance taskInstance = getValidHistoricTask(taskId, true);
String formKey = activitiProcessEngine.getFormService().getTaskFormKey(taskInstance.getProcessDefinitionId(), taskInstance.getTaskDefinitionKey()); String formKey = taskInstance.getFormKey();
// Based on the scope, right variables are queried // Based on the scope, right variables are queried
Map<String, Object> taskvariables = null; Map<String, Object> taskvariables = new HashMap<String, Object>();
Map<String, Object> processVariables = null; Map<String, Object> processVariables = new HashMap<String, Object>();
if(scope == VariableScope.ANY || scope == VariableScope.LOCAL) if (scope == VariableScope.ANY || scope == VariableScope.LOCAL)
{ {
taskvariables = activitiProcessEngine.getTaskService().getVariablesLocal(taskId); List<HistoricVariableInstance> variables = activitiProcessEngine.getHistoryService()
.createHistoricVariableInstanceQuery()
.taskId(taskId)
.list();
if (variables != null)
{
for (HistoricVariableInstance variable : variables)
{
taskvariables.put(variable.getVariableName(), variable.getValue());
}
}
} }
if((scope == VariableScope.ANY || scope == VariableScope.GLOBAL) && taskInstance.getExecutionId() != null) if ((scope == VariableScope.ANY || scope == VariableScope.GLOBAL) && taskInstance.getProcessInstanceId() != null)
{ {
processVariables = activitiProcessEngine.getRuntimeService().getVariables(taskInstance.getExecutionId()); List<HistoricVariableInstance> variables = activitiProcessEngine.getHistoryService()
.createHistoricVariableInstanceQuery()
.processInstanceId(taskInstance.getProcessInstanceId())
.excludeTaskVariables()
.list();
if (variables != null)
{
for (HistoricVariableInstance variable : variables)
{
processVariables.put(variable.getVariableName(), variable.getValue());
}
}
} }
// Convert raw variables to TaskVariables // Convert raw variables to TaskVariables
@@ -860,25 +898,25 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
protected TaskVariable updateVariableInTask(String taskId, org.activiti.engine.task.Task taskInstance, TaskVariable taskVariable) protected TaskVariable updateVariableInTask(String taskId, org.activiti.engine.task.Task taskInstance, TaskVariable taskVariable)
{ {
if(taskVariable.getName() == null) if (taskVariable.getName() == null)
{ {
throw new InvalidArgumentException("Variable name is required."); throw new InvalidArgumentException("Variable name is required.");
} }
if(taskVariable.getVariableScope() == null || taskVariable.getVariableScope() == VariableScope.ANY) if (taskVariable.getVariableScope() == null || taskVariable.getVariableScope() == VariableScope.ANY)
{ {
throw new InvalidArgumentException("Variable scope is required and can only be 'local' or 'global'."); throw new InvalidArgumentException("Variable scope is required and can only be 'local' or 'global'.");
} }
DataTypeDefinition dataTypeDefinition = null; DataTypeDefinition dataTypeDefinition = null;
if(taskVariable.getType() != null) if (taskVariable.getType() != null)
{ {
try try
{ {
QName dataType = QName.createQName(taskVariable.getType(), namespaceService); QName dataType = QName.createQName(taskVariable.getType(), namespaceService);
dataTypeDefinition = dictionaryService.getDataType(dataType); dataTypeDefinition = dictionaryService.getDataType(dataType);
} }
catch(InvalidQNameException iqne) catch (InvalidQNameException iqne)
{ {
throw new InvalidArgumentException("Unsupported type of variable: '" + taskVariable.getType() +"'."); throw new InvalidArgumentException("Unsupported type of variable: '" + taskVariable.getType() +"'.");
} }
@@ -893,7 +931,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
QName propQName = WorkflowQNameConverter.convertNameToQName(taskVariable.getName(), namespaceService); QName propQName = WorkflowQNameConverter.convertNameToQName(taskVariable.getName(), namespaceService);
PropertyDefinition propDef = typeDefinition.getProperties().get(propQName); PropertyDefinition propDef = typeDefinition.getProperties().get(propQName);
if(propDef != null) if (propDef != null)
{ {
dataTypeDefinition = propDef.getDataType(); dataTypeDefinition = propDef.getDataType();
} }
@@ -906,15 +944,15 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
} }
} }
} }
catch(InvalidQNameException ignore) catch (InvalidQNameException ignore)
{ {
// In case the property is not part of the model, it's possible that the property-name is not a valid. // In case the property is not part of the model, it's possible that the property-name is not a valid.
// This can be ignored safeley as it falls back to the raw type // This can be ignored safeley as it falls back to the raw type
} }
if(dataTypeDefinition == null) if (dataTypeDefinition == null)
{ {
// Finall fallback to raw value when no type has been passed and not present in model // Final fallback to raw value when no type has been passed and not present in model
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue())); dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue()));
} }
} }
@@ -968,7 +1006,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
getValidTask(taskId, true); getValidTask(taskId, true);
// Check if variable is present on the scope // Check if variable is present on the scope
if(!activitiProcessEngine.getTaskService().hasVariableLocal(taskId, variableName)) if (activitiProcessEngine.getTaskService().hasVariableLocal(taskId, variableName) == false)
{ {
throw new EntityNotFoundException(variableName); throw new EntityNotFoundException(variableName);
} }
@@ -978,6 +1016,9 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override @Override
public CollectionWithPagingInfo<TaskCandidate> getTaskCandidates(String taskId, Paging paging) public CollectionWithPagingInfo<TaskCandidate> getTaskCandidates(String taskId, Paging paging)
{ {
// Fetch task to check if user is authorized to perform the delete
getValidTask(taskId, true);
List<IdentityLink> links = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId); List<IdentityLink> links = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId);
List<TaskCandidate> page = new ArrayList<TaskCandidate>(); List<TaskCandidate> page = new ArrayList<TaskCandidate>();
if (links != null) if (links != null)
@@ -999,7 +1040,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
{ {
org.activiti.engine.task.Task task = getValidTask(taskId, false); org.activiti.engine.task.Task task = getValidTask(taskId, false);
if(task.getProcessInstanceId() == null) if (task.getProcessInstanceId() == null)
{ {
throw new UnsupportedResourceOperationException("Task is not part of process, no items available."); throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
} }
@@ -1021,9 +1062,9 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override @Override
public Item getItem(String taskId, String itemId) public Item getItem(String taskId, String itemId)
{ {
org.activiti.engine.task.Task task = getValidTask(taskId, false); HistoricTaskInstance task = getValidHistoricTask(taskId, true);
if(task.getProcessInstanceId() == null) if (task.getProcessInstanceId() == null)
{ {
throw new UnsupportedResourceOperationException("Task is not part of process, no items available."); throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
} }
@@ -1033,7 +1074,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override @Override
public CollectionWithPagingInfo<Item> getItems(String taskId, Paging paging) public CollectionWithPagingInfo<Item> getItems(String taskId, Paging paging)
{ {
org.activiti.engine.task.Task task = getValidTask(taskId, false); HistoricTaskInstance task = getValidHistoricTask(taskId, true);
if(task.getProcessInstanceId() == null) if(task.getProcessInstanceId() == null)
{ {
@@ -1140,10 +1181,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.createHistoricTaskInstanceQuery() .createHistoricTaskInstanceQuery()
.taskId(taskId); .taskId(taskId);
if(authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser())) if (authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser()))
{ {
// Admin is allowed to read all tasks in the current tenant // Admin is allowed to read all tasks in the current tenant
if(tenantService.isEnabled()) { if (tenantService.isEnabled())
{
query.processVariableValueEquals(ActivitiConstants.VAR_TENANT_DOMAIN, TenantUtil.getCurrentDomain()); query.processVariableValueEquals(ActivitiConstants.VAR_TENANT_DOMAIN, TenantUtil.getCurrentDomain());
} }
} }
@@ -1153,18 +1195,18 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
query.taskInvolvedUser(AuthenticationUtil.getRunAsUser()); query.taskInvolvedUser(AuthenticationUtil.getRunAsUser());
} }
HistoricTaskInstance taskInstance = query.singleResult(); HistoricTaskInstance taskInstance = query.singleResult();
if(taskInstance == null) if (taskInstance == null)
{ {
// Either the task doesn't exist or the user is not involved direcltly. We can differentiate by // Either the task doesn't exist or the user is not involved directly. We can differentiate by
// checking if the task exists without applying the additional filtering // checking if the task exists without applying the additional filtering
taskInstance = activitiProcessEngine.getHistoryService() taskInstance = activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery() .createHistoricTaskInstanceQuery()
.taskId(taskId) .taskId(taskId)
.singleResult(); .singleResult();
if(taskInstance == null) if (taskInstance == null)
{ {
// Full error message will be "Task with id: 'id' was not found" // Full error message will be "Task with id: 'id' was not found"
throw new EntityNotFoundException(taskId); throw new EntityNotFoundException(taskId);
@@ -1173,21 +1215,21 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
{ {
boolean isTaskClaimable = false; boolean isTaskClaimable = false;
if(validIfClaimable) if (validIfClaimable)
{ {
if(taskInstance.getEndTime() == null) if (taskInstance.getEndTime() == null)
{ {
// Task is not yet finished, so potentially claimable. If user is part of a "candidateGroup", the task is accessible to the // Task is not yet finished, so potentially claimable. If user is part of a "candidateGroup", the task is accessible to the
// user regardless of not being involved/owner/assignee // user regardless of not being involved/owner/assignee
isTaskClaimable = activitiProcessEngine.getTaskService() isTaskClaimable = activitiProcessEngine.getTaskService()
.createTaskQuery() .createTaskQuery()
.taskCandidateGroupIn(new ArrayList<String>(authorityService.getAuthoritiesForUser(AuthenticationUtil.getRunAsUser()))) .taskCandidateGroupIn(new ArrayList<String>(authorityService.getAuthoritiesForUser(AuthenticationUtil.getRunAsUser())))
.taskId(taskId) .taskId(taskId)
.count() == 1; .count() == 1;
} }
} }
if(!isTaskClaimable) if (isTaskClaimable == false)
{ {
throw new PermissionDeniedException(); throw new PermissionDeniedException();
} }
@@ -1206,7 +1248,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
*/ */
protected org.activiti.engine.task.Task getValidTask(String taskId, boolean validIfClaimable) protected org.activiti.engine.task.Task getValidTask(String taskId, boolean validIfClaimable)
{ {
if(taskId == null) if (taskId == null)
{ {
throw new InvalidArgumentException("Task id is required."); throw new InvalidArgumentException("Task id is required.");
} }
@@ -1215,10 +1257,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.createTaskQuery() .createTaskQuery()
.taskId(taskId); .taskId(taskId);
if(authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser())) if (authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser()))
{ {
// Admin is allowed to read all tasks in the current tenant // Admin is allowed to read all tasks in the current tenant
if(tenantService.isEnabled()) { if (tenantService.isEnabled())
{
query.processVariableValueEquals(ActivitiConstants.VAR_TENANT_DOMAIN, TenantUtil.getCurrentDomain()); query.processVariableValueEquals(ActivitiConstants.VAR_TENANT_DOMAIN, TenantUtil.getCurrentDomain());
} }
} }
@@ -1230,16 +1273,16 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
org.activiti.engine.task.Task taskInstance = query.singleResult(); org.activiti.engine.task.Task taskInstance = query.singleResult();
if(taskInstance == null) if (taskInstance == null)
{ {
// Either the task doesn't exist or the user is not involved direcltly. We can differentiate by // Either the task doesn't exist or the user is not involved directly. We can differentiate by
// checking if the task exists without applying the additional filtering // checking if the task exists without applying the additional filtering
taskInstance = activitiProcessEngine.getTaskService() taskInstance = activitiProcessEngine.getTaskService()
.createTaskQuery() .createTaskQuery()
.taskId(taskId) .taskId(taskId)
.singleResult(); .singleResult();
if(taskInstance == null) if (taskInstance == null)
{ {
// Full error message will be "Task with id: 'id' was not found" // Full error message will be "Task with id: 'id' was not found"
throw new EntityNotFoundException(taskId); throw new EntityNotFoundException(taskId);
@@ -1248,7 +1291,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
{ {
boolean isTaskClaimable = false; boolean isTaskClaimable = false;
if(validIfClaimable) if (validIfClaimable)
{ {
// Task is not yet finished, so potentially claimable. If user is part of a "candidateGroup", the task is accessible to the // Task is not yet finished, so potentially claimable. If user is part of a "candidateGroup", the task is accessible to the
// user regardless of not being involved/owner/assignee // user regardless of not being involved/owner/assignee
@@ -1259,7 +1302,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.count() == 1; .count() == 1;
} }
if(!isTaskClaimable) if (isTaskClaimable == false)
{ {
throw new PermissionDeniedException(); throw new PermissionDeniedException();
} }

View File

@@ -4,16 +4,17 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery; import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.ProcessEngineImpl; import org.activiti.engine.impl.ProcessEngineImpl;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.context.Context;
@@ -43,6 +44,8 @@ import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -103,6 +106,23 @@ public class WorkflowRestImpl
this.deployWorkflowsInTenant = deployWorkflowsInTenant; this.deployWorkflowsInTenant = deployWorkflowsInTenant;
} }
/**
* Create NodeRef from item id String
*/
public NodeRef getNodeRef(String itemId)
{
NodeRef nodeRef = null;
if (NodeRef.isNodeRef(itemId) == false)
{
nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, itemId);
}
else
{
nodeRef = new NodeRef(itemId);
}
return nodeRef;
}
/** /**
* Get the process definition from the cache if available * Get the process definition from the cache if available
* *
@@ -263,65 +283,63 @@ public class WorkflowRestImpl
* *
* @param processId identifier of the process instance * @param processId identifier of the process instance
*/ */
protected void validateIfUserAllowedToWorkWithProcess(String processId) protected List<HistoricVariableInstance> validateIfUserAllowedToWorkWithProcess(String processId)
{ {
if (tenantService.isEnabled()) List<HistoricVariableInstance> variableInstances = activitiProcessEngine.getHistoryService()
{ .createHistoricVariableInstanceQuery()
try .processInstanceId(processId)
{ .list();
String tenantDomain = (String) activitiProcessEngine.getRuntimeService().getVariable(processId, ActivitiConstants.VAR_TENANT_DOMAIN);
if (TenantUtil.getCurrentDomain().equals(tenantDomain) == false)
{
throw new PermissionDeniedException("Process is running in another tenant");
}
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
}
try Map<String, Object> variableMap = new HashMap<String, Object>();
if (variableInstances != null && variableInstances.size() > 0)
{ {
ActivitiScriptNode initiator = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, WorkflowConstants.PROP_INITIATOR); for (HistoricVariableInstance variableInstance : variableInstances)
if (AuthenticationUtil.getRunAsUser().equals(initiator.getNodeRef().getId()))
{ {
// user is allowed variableMap.put(variableInstance.getVariableName(), variableInstance.getValue());
return;
}
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
HistoricTaskInstanceQuery query = activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.processInstanceId(processId);
if (authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser()))
{
// Admin is allowed to read all processes in the current tenant
if (tenantService.isEnabled())
{
query.processVariableValueEquals(ActivitiConstants.VAR_TENANT_DOMAIN, TenantUtil.getCurrentDomain());
}
else
{
return;
} }
} }
else else
{ {
// If non-admin user, involvement in the task is required (either owner, assignee or externally involved). throw new EntityNotFoundException(processId);
query.taskInvolvedUser(AuthenticationUtil.getRunAsUser());
} }
List<HistoricTaskInstance> taskList = query.list(); if (tenantService.isEnabled())
if(org.apache.commons.collections.CollectionUtils.isEmpty(taskList))
{ {
throw new PermissionDeniedException("user is not allowed to access information about process " + processId); String tenantDomain = (String) variableMap.get(ActivitiConstants.VAR_TENANT_DOMAIN);
if (TenantUtil.getCurrentDomain().equals(tenantDomain) == false)
{
throw new PermissionDeniedException("Process is running in another tenant");
}
} }
ActivitiScriptNode initiator = (ActivitiScriptNode) variableMap.get(WorkflowConstants.PROP_INITIATOR);
if (initiator != null && AuthenticationUtil.getRunAsUser().equals(initiator.getNodeRef().getId()))
{
// user is allowed
return variableInstances;
}
if (authorityService.isAdminAuthority(AuthenticationUtil.getRunAsUser()))
{
// Admin is allowed to read all processes in the current tenant
return variableInstances;
}
else
{
// If non-admin user, involvement in the task is required (either owner, assignee or externally involved).
HistoricTaskInstanceQuery query = activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.processInstanceId(processId)
.taskInvolvedUser(AuthenticationUtil.getRunAsUser());
List<HistoricTaskInstance> taskList = query.list();
if (org.apache.commons.collections.CollectionUtils.isEmpty(taskList))
{
throw new PermissionDeniedException("user is not allowed to access information about process " + processId);
}
}
return variableInstances;
} }
} }

View File

@@ -90,9 +90,13 @@ public class Task
this.assignee = taskInstance.getAssignee(); this.assignee = taskInstance.getAssignee();
if (taskInstance.getDelegationState() == DelegationState.PENDING) if (taskInstance.getDelegationState() == DelegationState.PENDING)
{ {
this.state = TaskStateTransition.DELEGATED.name().toLowerCase();
} }
if (taskInstance.getAssignee() != null) else if (taskInstance.getDelegationState() == DelegationState.RESOLVED)
{
this.state = TaskStateTransition.RESOLVED.name().toLowerCase();
}
else if (taskInstance.getAssignee() != null)
{ {
this.state = TaskStateTransition.CLAIMED.name().toLowerCase(); this.state = TaskStateTransition.CLAIMED.name().toLowerCase();
} }

View File

@@ -306,4 +306,43 @@ public class EnterpriseWorkflowTestApi extends EnterpriseTestApi
return processesClient.createProcess(createProcessObject.toJSONString()); return processesClient.createProcess(createProcessObject.toJSONString());
} }
/**
* Start a review pooled process through the public REST-API.
*/
@SuppressWarnings("unchecked")
protected ProcessInfo startParallelReviewProcess(final RequestContext requestContext) throws PublicApiException {
org.activiti.engine.repository.ProcessDefinition processDefinition = activitiProcessEngine
.getRepositoryService()
.createProcessDefinitionQuery()
.processDefinitionKey("@" + requestContext.getNetworkId() + "@activitiParallelReview")
.singleResult();
ProcessesClient processesClient = publicApiClient.processesClient();
final JSONObject createProcessObject = new JSONObject();
createProcessObject.put("processDefinitionId", processDefinition.getId());
final JSONObject variablesObject = new JSONObject();
variablesObject.put("bpm_priority", 1);
variablesObject.put("wf_notifyMe", Boolean.FALSE);
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
JSONArray assigneeArray = new JSONArray();
assigneeArray.add(requestContext.getRunAsUser());
TestPerson otherPerson = getOtherPersonInNetwork(requestContext.getRunAsUser(), requestContext.getNetworkId());
assigneeArray.add(otherPerson.getId());
variablesObject.put("bpm_assignees", assigneeArray);
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
createProcessObject.put("variables", variablesObject);
return processesClient.createProcess(createProcessObject.toJSONString());
}
} }

View File

@@ -223,6 +223,17 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
{ {
final RequestContext requestContext = initApiClientWithTestUser(); final RequestContext requestContext = initApiClientWithTestUser();
final ProcessInfo processInfo = startReviewPooledProcess(requestContext); final ProcessInfo processInfo = startReviewPooledProcess(requestContext);
assertNotNull(processInfo);
assertNotNull(processInfo.getId());
}
@Test
public void testCreateProcessInstanceForParallelReview() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
final ProcessInfo processInfo = startParallelReviewProcess(requestContext);
assertNotNull(processInfo);
assertNotNull(processInfo.getId());
} }
@Test @Test
@@ -458,7 +469,7 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
.createHistoricProcessInstanceQuery().processInstanceId(process.getId()).singleResult(); .createHistoricProcessInstanceQuery().processInstanceId(process.getId()).singleResult();
assertNotNull(deletedInstance); assertNotNull(deletedInstance);
assertNotNull(deletedInstance.getEndTime()); assertNotNull(deletedInstance.getEndTime());
assertNull(deletedInstance.getDeleteReason()); assertEquals("deleted through REST API call", deletedInstance.getDeleteReason());
} }
finally finally
{ {
@@ -480,7 +491,7 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
.createHistoricProcessInstanceQuery().processInstanceId(process.getId()).singleResult(); .createHistoricProcessInstanceQuery().processInstanceId(process.getId()).singleResult();
assertNotNull(deletedInstance); assertNotNull(deletedInstance);
assertNotNull(deletedInstance.getEndTime()); assertNotNull(deletedInstance.getEndTime());
assertNull(deletedInstance.getDeleteReason()); assertEquals("deleted through REST API call", deletedInstance.getDeleteReason());
} }
finally finally
{ {

View File

@@ -227,7 +227,13 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
List<String> selectedFields = new ArrayList<String>(); List<String> selectedFields = new ArrayList<String>();
selectedFields.addAll(Arrays.asList(new String[] { "name", "description", "dueAt", "priority", "assignee", "owner"})); selectedFields.addAll(Arrays.asList(new String[] { "name", "description", "dueAt", "priority", "assignee", "owner"}));
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("Updated name", result.get("name"));
assertEquals("Updated description", result.get("description"));
assertEquals(1234, Integer.valueOf(result.get("priority").toString()).intValue());
assertEquals("john", result.get("assignee"));
assertEquals("james", result.get("owner"));
assertEquals(dueDate, parseDate(result, "dueAt"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task); assertNotNull(task);
@@ -277,7 +283,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().setAssignee(task.getId(), requestContext.getRunAsUser()); activitiProcessEngine.getTaskService().setAssignee(task.getId(), requestContext.getRunAsUser());
taskBody.put("name", "Updated name by assignee"); taskBody.put("name", "Updated name by assignee");
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("Updated name by assignee", result.get("name"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task); assertNotNull(task);
assertEquals("Updated name by assignee", task.getName()); assertEquals("Updated name by assignee", task.getName());
@@ -287,7 +294,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().setOwner(task.getId(), requestContext.getRunAsUser()); activitiProcessEngine.getTaskService().setOwner(task.getId(), requestContext.getRunAsUser());
taskBody.put("name", "Updated name by owner"); taskBody.put("name", "Updated name by owner");
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("Updated name by owner", result.get("name"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task); assertNotNull(task);
assertEquals("Updated name by owner", task.getName()); assertEquals("Updated name by owner", task.getName());
@@ -295,7 +303,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
// Update as process initiator // Update as process initiator
taskBody.put("name", "Updated name by initiator"); taskBody.put("name", "Updated name by initiator");
requestContext.setRunAsUser(initiator); requestContext.setRunAsUser(initiator);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("Updated name by initiator", result.get("name"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task); assertNotNull(task);
assertEquals("Updated name by initiator", task.getName()); assertEquals("Updated name by initiator", task.getName());
@@ -305,7 +314,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin)); publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin));
taskBody.put("name", "Updated name by admin"); taskBody.put("name", "Updated name by admin");
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("Updated name by admin", result.get("name"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertNotNull(task); assertNotNull(task);
assertEquals("Updated name by admin", task.getName()); assertEquals("Updated name by admin", task.getName());
@@ -441,11 +451,13 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
taskBody.put("state", "claimed"); taskBody.put("state", "claimed");
JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result); assertNotNull(result);
assertEquals(requestContext.getRunAsUser(), result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Re-claiming the same task with the current assignee shouldn't be a problem // Re-claiming the same task with the current assignee shouldn't be a problem
result = tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result); assertNotNull(result);
assertEquals(requestContext.getRunAsUser(), result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Claiming as a candidateUser should also work // Claiming as a candidateUser should also work
@@ -454,6 +466,7 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().addCandidateUser(task.getId(), requestContext.getRunAsUser()); activitiProcessEngine.getTaskService().addCandidateUser(task.getId(), requestContext.getRunAsUser());
result = tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result); assertNotNull(result);
assertEquals(requestContext.getRunAsUser(), result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Claiming as a task owner should also work // Claiming as a task owner should also work
@@ -462,6 +475,7 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE); activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE);
result = tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result); assertNotNull(result);
assertEquals(requestContext.getRunAsUser(), result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertEquals(requestContext.getRunAsUser(), activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Claiming as admin should work // Claiming as admin should work
@@ -472,6 +486,7 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE); activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE);
result = tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result); assertNotNull(result);
assertEquals(tenantAdmin, result.get("assignee"));
assertEquals(tenantAdmin, activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertEquals(tenantAdmin, activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
} }
@@ -514,21 +529,24 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
// Unclaiming as process initiator // Unclaiming as process initiator
requestContext.setRunAsUser(initiator); requestContext.setRunAsUser(initiator);
activitiProcessEngine.getTaskService().setAssignee(task.getId(), null); activitiProcessEngine.getTaskService().setAssignee(task.getId(), null);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNull(result.get("assignee"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Unclaiming as assignee // Unclaiming as assignee
activitiProcessEngine.getTaskService().setAssignee(task.getId(), user); activitiProcessEngine.getTaskService().setAssignee(task.getId(), user);
requestContext.setRunAsUser(user); requestContext.setRunAsUser(user);
assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNull(result.get("assignee"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Unclaim as owner // Unclaim as owner
activitiProcessEngine.getTaskService().setOwner(task.getId(), user); activitiProcessEngine.getTaskService().setOwner(task.getId(), user);
activitiProcessEngine.getTaskService().setAssignee(task.getId(), initiator); activitiProcessEngine.getTaskService().setAssignee(task.getId(), initiator);
assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNull(result.get("assignee"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
// Unclaim as admin // Unclaim as admin
@@ -538,7 +556,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().setAssignee(task.getId(), initiator); activitiProcessEngine.getTaskService().setAssignee(task.getId(), initiator);
activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE); activitiProcessEngine.getTaskService().deleteUserIdentityLink(task.getId(), requestContext.getRunAsUser(), IdentityLinkType.CANDIDATE);
assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNotNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNull(result.get("assignee"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(task.getId()).singleResult().getAssignee());
} }
finally finally
@@ -585,20 +604,26 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
// Completing as assignee initiator // Completing as assignee initiator
activitiProcessEngine.getTaskService().setAssignee(asAssigneeTask.getId(), user); activitiProcessEngine.getTaskService().setAssignee(asAssigneeTask.getId(), user);
tasksClient.updateTask(asAssigneeTask.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(asAssigneeTask.getId(), taskBody, selectedFields);
assertEquals("completed", result.get("state"));
assertNotNull(result.get("endedAt"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asAssigneeTask.getId()).singleResult()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asAssigneeTask.getId()).singleResult());
// Completing as process initiator // Completing as process initiator
requestContext.setRunAsUser(initiator); requestContext.setRunAsUser(initiator);
activitiProcessEngine.getTaskService().setAssignee(asInitiatorTask.getId(), null); activitiProcessEngine.getTaskService().setAssignee(asInitiatorTask.getId(), null);
tasksClient.updateTask(asInitiatorTask.getId(), taskBody, selectedFields); result = tasksClient.updateTask(asInitiatorTask.getId(), taskBody, selectedFields);
assertEquals("completed", result.get("state"));
assertNotNull(result.get("endedAt"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asInitiatorTask.getId()).singleResult()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asInitiatorTask.getId()).singleResult());
// Completing as owner // Completing as owner
requestContext.setRunAsUser(user); requestContext.setRunAsUser(user);
asOwnerTask.setOwner(user); asOwnerTask.setOwner(user);
activitiProcessEngine.getTaskService().saveTask(asOwnerTask); activitiProcessEngine.getTaskService().saveTask(asOwnerTask);
tasksClient.updateTask(asOwnerTask.getId(), taskBody, selectedFields); result = tasksClient.updateTask(asOwnerTask.getId(), taskBody, selectedFields);
assertEquals("completed", result.get("state"));
assertNotNull(result.get("endedAt"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asOwnerTask.getId()).singleResult()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asOwnerTask.getId()).singleResult());
// Complete as admin // Complete as admin
@@ -606,7 +631,9 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin)); publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin));
asAdminTask.setOwner(null); asAdminTask.setOwner(null);
activitiProcessEngine.getTaskService().saveTask(asAdminTask); activitiProcessEngine.getTaskService().saveTask(asAdminTask);
tasksClient.updateTask(asAdminTask.getId(), taskBody, selectedFields); result = tasksClient.updateTask(asAdminTask.getId(), taskBody, selectedFields);
assertEquals("completed", result.get("state"));
assertNotNull(result.get("endedAt"));
assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asAdminTask.getId()).singleResult()); assertNull(activitiProcessEngine.getTaskService().createTaskQuery().taskId(asAdminTask.getId()).singleResult());
} }
finally finally
@@ -669,7 +696,10 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
selectedFields = new ArrayList<String>(); selectedFields = new ArrayList<String>();
selectedFields.addAll(Arrays.asList(new String[] { "state", "assignee" })); selectedFields.addAll(Arrays.asList(new String[] { "state", "assignee" }));
assertNull(task.getDelegationState()); assertNull(task.getDelegationState());
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("delegated", result.get("state"));
assertEquals(initiator, result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), result.get("owner"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.PENDING, task.getDelegationState()); assertEquals(DelegationState.PENDING, task.getDelegationState());
assertEquals(initiator, task.getAssignee()); assertEquals(initiator, task.getAssignee());
@@ -680,7 +710,10 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
task.setOwner(requestContext.getRunAsUser()); task.setOwner(requestContext.getRunAsUser());
task.setAssignee(null); task.setAssignee(null);
activitiProcessEngine.getTaskService().saveTask(task); activitiProcessEngine.getTaskService().saveTask(task);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("delegated", result.get("state"));
assertEquals(initiator, result.get("assignee"));
assertEquals(requestContext.getRunAsUser(), result.get("owner"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.PENDING, task.getDelegationState()); assertEquals(DelegationState.PENDING, task.getDelegationState());
assertEquals(initiator, task.getAssignee()); assertEquals(initiator, task.getAssignee());
@@ -693,7 +726,10 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().saveTask(task); activitiProcessEngine.getTaskService().saveTask(task);
requestContext.setRunAsUser(initiator); requestContext.setRunAsUser(initiator);
taskBody.put("assignee", user); taskBody.put("assignee", user);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("delegated", result.get("state"));
assertEquals(user, result.get("assignee"));
assertEquals(initiator, result.get("owner"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.PENDING, task.getDelegationState()); assertEquals(DelegationState.PENDING, task.getDelegationState());
assertEquals(user, task.getAssignee()); assertEquals(user, task.getAssignee());
@@ -708,7 +744,10 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
requestContext.setRunAsUser(tenantAdmin); requestContext.setRunAsUser(tenantAdmin);
taskBody.put("assignee", user); taskBody.put("assignee", user);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("delegated", result.get("state"));
assertEquals(user, result.get("assignee"));
assertEquals(tenantAdmin, result.get("owner"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.PENDING, task.getDelegationState()); assertEquals(DelegationState.PENDING, task.getDelegationState());
assertEquals(user, task.getAssignee()); assertEquals(user, task.getAssignee());
@@ -758,7 +797,9 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
taskBody.put("assignee", initiator); taskBody.put("assignee", initiator);
selectedFields = new ArrayList<String>(); selectedFields = new ArrayList<String>();
selectedFields.addAll(Arrays.asList(new String[] { "state", "assignee" })); selectedFields.addAll(Arrays.asList(new String[] { "state", "assignee" }));
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("resolved", result.get("state"));
assertEquals(initiator, result.get("assignee"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.RESOLVED, task.getDelegationState()); assertEquals(DelegationState.RESOLVED, task.getDelegationState());
assertEquals(initiator, task.getAssignee()); assertEquals(initiator, task.getAssignee());
@@ -768,7 +809,9 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
task.setOwner(requestContext.getRunAsUser()); task.setOwner(requestContext.getRunAsUser());
task.setAssignee(null); task.setAssignee(null);
activitiProcessEngine.getTaskService().saveTask(task); activitiProcessEngine.getTaskService().saveTask(task);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("resolved", result.get("state"));
assertEquals(user, result.get("assignee"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.RESOLVED, task.getDelegationState()); assertEquals(DelegationState.RESOLVED, task.getDelegationState());
assertEquals(user, task.getAssignee()); assertEquals(user, task.getAssignee());
@@ -780,7 +823,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
activitiProcessEngine.getTaskService().saveTask(task); activitiProcessEngine.getTaskService().saveTask(task);
requestContext.setRunAsUser(initiator); requestContext.setRunAsUser(initiator);
taskBody.put("assignee", user); taskBody.put("assignee", user);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("resolved", result.get("state"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.RESOLVED, task.getDelegationState()); assertEquals(DelegationState.RESOLVED, task.getDelegationState());
@@ -793,7 +837,9 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
requestContext.setRunAsUser(tenantAdmin); requestContext.setRunAsUser(tenantAdmin);
taskBody.put("assignee", user); taskBody.put("assignee", user);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertEquals("resolved", result.get("state"));
assertEquals(initiator, result.get("assignee"));
task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
assertEquals(DelegationState.RESOLVED, task.getDelegationState()); assertEquals(DelegationState.RESOLVED, task.getDelegationState());
assertEquals(initiator, task.getAssignee()); assertEquals(initiator, task.getAssignee());
@@ -825,14 +871,16 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
JSONObject taskBody = new JSONObject(); JSONObject taskBody = new JSONObject();
String dueAt = formatDate(new Date()); String dueAt = formatDate(new Date());
taskBody.put("dueAt", dueAt); taskBody.put("dueAt", dueAt);
tasksClient.updateTask(task.getId(), taskBody, selectedFields); JSONObject result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result.get("dueAt"));
taskObject = tasksClient.findTaskById(task.getId()); taskObject = tasksClient.findTaskById(task.getId());
assertNotNull(taskObject.get("dueAt")); assertNotNull(taskObject.get("dueAt"));
taskBody = new JSONObject(); taskBody = new JSONObject();
taskBody.put("dueAt", taskObject.get("dueAt")); taskBody.put("dueAt", taskObject.get("dueAt"));
tasksClient.updateTask(task.getId(), taskBody, selectedFields); result = tasksClient.updateTask(task.getId(), taskBody, selectedFields);
assertNotNull(result.get("dueAt"));
taskObject = tasksClient.findTaskById(task.getId()); taskObject = tasksClient.findTaskById(task.getId());
assertNotNull(taskObject.get("dueAt")); assertNotNull(taskObject.get("dueAt"));