ALF-19858: Fixed instance cleanup and added more unit tests

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54602 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tijs Rademakers
2013-08-29 08:19:08 +00:00
parent 104dc484d5
commit 61e3565081
9 changed files with 1376 additions and 629 deletions

View File

@@ -830,7 +830,7 @@
<property name="dictionaryService" ref="DictionaryService" />
<property name="namespaceService" ref="NamespaceService" />
<property name="tenantService" ref="tenantService" />
<property name="nodeService" ref="nodeService"/>
</bean>
<bean id="deployments" class="org.alfresco.rest.workflow.api.impl.DeploymentsImpl" parent="baseWorkflowRest">
@@ -874,7 +874,6 @@
<property name="workflowPackageComponent" ref="workflowPackageImpl"/>
<property name="serviceRegistry" ref="ServiceRegistry" />
<property name="authorityDAO" ref="authorityDAO" />
<property name="nodeService" ref="nodeService"/>
<property name="personService" ref="PersonService" />
<property name="messageService" ref="messageService" />
<property name="engineId" value="activiti" />
@@ -899,7 +898,6 @@
<bean id="tasks" class="org.alfresco.rest.workflow.api.impl.TasksImpl" parent="baseWorkflowRest">
<property name="restVariableHelper" ref="restVariableHelper" />
<property name="messageService" ref="messageService" />
<property name="processes" ref="processes"/>
</bean>
<bean id="Tasks" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -61,7 +61,6 @@ import org.alfresco.repo.workflow.WorkflowPropertyHandlerRegistry;
import org.alfresco.repo.workflow.WorkflowQNameConverter;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.activiti.ActivitiNodeConverter;
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
import org.alfresco.repo.workflow.activiti.ActivitiTypeConverter;
import org.alfresco.repo.workflow.activiti.ActivitiUtil;
import org.alfresco.repo.workflow.activiti.properties.ActivitiPropertyConverter;
@@ -85,11 +84,7 @@ import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
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.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.InvalidQNameException;
@@ -101,8 +96,6 @@ import org.apache.commons.io.IOUtils;
public class ProcessesImpl extends WorkflowRestImpl implements Processes
{
protected static final String BPM_PACKAGE = "bpm_package";
protected static String PROCESS_STATUS_ANY = "any";
protected static String PROCESS_STATUS_ACTIVE = "active";
protected static String PROCESS_STATUS_COMPLETED = "completed";
@@ -130,7 +123,6 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
protected WorkflowPackageImpl workflowPackageComponent;
protected ServiceRegistry serviceRegistry;
protected AuthorityDAO authorityDAO;
protected NodeService nodeService;
protected PersonService personService;
protected MessageService messageService;
protected String engineId;
@@ -163,11 +155,6 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
this.workflowPackageComponent = workflowPackageComponent;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
@@ -754,42 +741,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
}
validateIfUserAllowedToWorkWithProcess(processId);
ActivitiScriptNode packageScriptNode = null;
try
{
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)
{
throw new EntityNotFoundException(processId);
}
List<Item> page = new ArrayList<Item>();
if (packageScriptNode != null)
{
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
Item item = createItemForNodeRef(childAssociationRef.getChildRef());
page.add(item);
}
}
return CollectionWithPagingInfo.asPaged(paging, page, false, page.size());
return getItemsFromProcess(processId, paging);
}
@Override
@@ -805,52 +757,8 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("itemId is required to get an attached item");
}
NodeRef nodeRef = getNodeRef(itemId);
validateIfUserAllowedToWorkWithProcess(processId);
ActivitiScriptNode packageScriptNode = null;
try
{
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)
{
throw new EntityNotFoundException(processId);
}
Item item = null;
if (packageScriptNode != null)
{
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
if (childAssociationRef.getChildRef().equals(nodeRef))
{
item = createItemForNodeRef(childAssociationRef.getChildRef());
break;
}
}
}
if (item == null) {
throw new EntityNotFoundException(itemId);
}
return item;
return getItemFromProcess(itemId, processId);
}
@Override
@@ -867,46 +775,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
}
validateIfUserAllowedToWorkWithProcess(processId);
NodeRef nodeRef = getNodeRef(item.getId());
ActivitiScriptNode packageScriptNode = null;
try
{
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
if (packageScriptNode == null)
{
throw new InvalidArgumentException("process doesn't contain a workflow package variable");
}
// check if noderef exists
try
{
nodeService.getProperties(nodeRef);
}
catch (Exception e)
{
throw new EntityNotFoundException("item with id " + nodeRef.toString() + " not found");
}
try
{
QName workflowPackageItemId = QName.createQName("wpi", nodeRef.toString());
nodeService.addChild(packageScriptNode.getNodeRef(), nodeRef,
WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId);
}
catch (Exception e)
{
throw new ApiException("could not add item to process " + e.getMessage(), e);
}
return item;
return createItemInProcess(item.getId(), processId);
}
@Override
@@ -922,49 +791,8 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("itemId is required to delete an attached item");
}
NodeRef nodeRef = getNodeRef(itemId);
validateIfUserAllowedToWorkWithProcess(processId);
ActivitiScriptNode packageScriptNode = null;
try
{
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
if (packageScriptNode == null)
{
throw new InvalidArgumentException("process doesn't contain a workflow package variable");
}
boolean itemIdFoundInPackage = false;
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
if (childAssociationRef.getChildRef().equals(nodeRef))
{
itemIdFoundInPackage = true;
break;
}
}
if (itemIdFoundInPackage == false)
{
throw new EntityNotFoundException("Item " + itemId + " not found in the process package variable");
}
try
{
nodeService.removeChild(packageScriptNode.getNodeRef(), nodeRef);
}
catch (InvalidNodeRefException e)
{
throw new EntityNotFoundException("Item " + itemId + " not found");
}
deleteItemFromProcess(itemId, processId);
}
@Override
@@ -1233,33 +1061,4 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
processInfo.setProcessDefinitionKey(getLocalProcessDefinitionKey(definitionEntity.getKey()));
return processInfo;
}
protected Item createItemForNodeRef(NodeRef nodeRef) {
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
Item item = new Item();
String name = (String) properties.get(ContentModel.PROP_NAME);
String title = (String) properties.get(ContentModel.PROP_TITLE);
String description = (String) properties.get(ContentModel.PROP_DESCRIPTION);
Date createdAt = (Date) properties.get(ContentModel.PROP_CREATED);
String createdBy = (String) properties.get(ContentModel.PROP_CREATOR);
Date modifiedAt = (Date) properties.get(ContentModel.PROP_MODIFIED);
String modifiedBy = (String) properties.get(ContentModel.PROP_MODIFIER);
ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
item.setId(nodeRef.getId());
item.setName(name);
item.setTitle(title);
item.setDescription(description);
item.setCreatedAt(createdAt);
item.setCreatedBy(createdBy);
item.setModifiedAt(modifiedAt);
item.setModifiedBy(modifiedBy);
if (contentData != null)
{
item.setMimeType(contentData.getMimetype());
item.setSize(contentData.getSize());
}
return item;
}
}

View File

@@ -54,7 +54,6 @@ import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.workflow.api.Processes;
import org.alfresco.rest.workflow.api.Tasks;
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker.QueryVariableHolder;
import org.alfresco.rest.workflow.api.model.FormModelElement;
@@ -123,7 +122,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
private WorkflowObjectFactory workflowFactory;
private WorkflowQNameConverter qNameConverter;
private MessageService messageService;
private Processes processes;
public void setRestVariableHelper(RestVariableHelper restVariableHelper)
{
@@ -135,11 +133,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
this.messageService = messageService;
}
public void setProcesses(Processes processes)
{
this.processes = processes;
}
@Override
public CollectionWithPagingInfo<Task> getTasks(Parameters parameters)
{
@@ -634,7 +627,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
throw new InvalidArgumentException("Task id is required");
}
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId, true);
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId);
return new Task(taskInstance);
}
@@ -818,7 +811,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
public CollectionWithPagingInfo<FormModelElement> getTaskFormModel(String taskId, Paging paging)
{
// Check if task can be accessed by the current user
HistoricTaskInstance task = getValidHistoricTask(taskId, true);
HistoricTaskInstance task = getValidHistoricTask(taskId);
String formKey = task.getFormKey();
// Lookup type definition for the task
@@ -830,7 +823,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
public CollectionWithPagingInfo<TaskVariable> getTaskVariables(String taskId, Paging paging, VariableScope scope)
{
// Ensure the user is allowed to get variables for the task involved.
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId, true);
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId);
String formKey = taskInstance.getFormKey();
// Based on the scope, right variables are queried
@@ -878,13 +871,13 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override
public TaskVariable updateTaskVariable(String taskId, TaskVariable taskVariable)
{
org.activiti.engine.task.Task taskInstance = getValidTask(taskId, true);
org.activiti.engine.task.Task taskInstance = getValidTask(taskId);
return updateVariableInTask(taskId, taskInstance, taskVariable);
}
public List<TaskVariable> updateTaskVariables(String taskId, List<TaskVariable> variables)
{
org.activiti.engine.task.Task taskInstance = getValidTask(taskId, true);
org.activiti.engine.task.Task taskInstance = getValidTask(taskId);
List<TaskVariable> updatedVariables = new ArrayList<TaskVariable>();
if (variables != null)
{
@@ -1003,7 +996,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
}
// Fetch task to check if user is authorized to perform the delete
getValidTask(taskId, true);
getValidTask(taskId);
// Check if variable is present on the scope
if (activitiProcessEngine.getTaskService().hasVariableLocal(taskId, variableName) == false)
@@ -1017,7 +1010,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
public CollectionWithPagingInfo<TaskCandidate> getTaskCandidates(String taskId, Paging paging)
{
// Fetch task to check if user is authorized to perform the delete
getValidTask(taskId, true);
getValidTask(taskId);
List<IdentityLink> links = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId);
List<TaskCandidate> page = new ArrayList<TaskCandidate>();
@@ -1038,49 +1031,49 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override
public Item createItem(String taskId, Item item)
{
org.activiti.engine.task.Task task = getValidTask(taskId, false);
org.activiti.engine.task.Task task = getValidTask(taskId);
if (task.getProcessInstanceId() == null)
{
throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
}
return processes.createItem(task.getProcessInstanceId(), item);
return createItemInProcess(item.getId(), task.getProcessInstanceId());
}
@Override
public void deleteItem(String taskId, String itemId)
{
org.activiti.engine.task.Task task = getValidTask(taskId, false);
org.activiti.engine.task.Task task = getValidTask(taskId);
if (task.getProcessInstanceId() == null)
{
throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
}
processes.deleteItem(task.getProcessInstanceId(), itemId);
deleteItemFromProcess(itemId, task.getProcessInstanceId());
}
@Override
public Item getItem(String taskId, String itemId)
{
HistoricTaskInstance task = getValidHistoricTask(taskId, true);
HistoricTaskInstance task = getValidHistoricTask(taskId);
if (task.getProcessInstanceId() == null)
{
throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
}
return processes.getItem(task.getProcessInstanceId(), itemId);
return getItemFromProcess(itemId, task.getProcessInstanceId());
}
@Override
public CollectionWithPagingInfo<Item> getItems(String taskId, Paging paging)
{
HistoricTaskInstance task = getValidHistoricTask(taskId, true);
HistoricTaskInstance task = getValidHistoricTask(taskId);
if (task.getProcessInstanceId() == null)
{
throw new UnsupportedResourceOperationException("Task is not part of process, no items available.");
}
return processes.getItems(task.getProcessInstanceId(), paging);
return getItemsFromProcess(task.getProcessInstanceId(), paging);
}
protected String getFormResourceKey(final org.activiti.engine.task.Task task)
@@ -1175,7 +1168,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
* @throws EntityNotFoundException when the task was not found
* @throws PermissionDeniedException when the current logged in user isn't allowed to access task.
*/
protected HistoricTaskInstance getValidHistoricTask(String taskId, boolean validIfClaimable)
protected HistoricTaskInstance getValidHistoricTask(String taskId)
{
HistoricTaskInstanceQuery query = activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
@@ -1214,9 +1207,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
else
{
boolean isTaskClaimable = false;
if (validIfClaimable)
{
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
@@ -1227,7 +1217,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.taskId(taskId)
.count() == 1;
}
}
if (isTaskClaimable == false)
{
@@ -1246,7 +1235,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
* @throws EntityNotFoundException when the task was not found
* @throws PermissionDeniedException when the current logged in user isn't allowed to access task.
*/
protected org.activiti.engine.task.Task getValidTask(String taskId, boolean validIfClaimable)
protected org.activiti.engine.task.Task getValidTask(String taskId)
{
if (taskId == null)
{
@@ -1288,19 +1277,14 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
throw new EntityNotFoundException(taskId);
}
else
{
boolean isTaskClaimable = false;
if (validIfClaimable)
{
// 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
isTaskClaimable = activitiProcessEngine.getTaskService()
boolean isTaskClaimable = activitiProcessEngine.getTaskService()
.createTaskQuery()
.taskCandidateGroupIn(new ArrayList<String>(authorityService.getAuthoritiesForUser(AuthenticationUtil.getRunAsUser())))
.taskId(taskId)
.count() == 1;
}
if (isTaskClaimable == false)
{

View File

@@ -1,5 +1,6 @@
package org.alfresco.rest.workflow.api.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -11,6 +12,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
@@ -28,8 +30,10 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.workflow.WorkflowConstants;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
import org.alfresco.rest.framework.core.exceptions.ApiException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
@@ -37,6 +41,7 @@ import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.workflow.api.model.FormModelElement;
import org.alfresco.rest.workflow.api.model.Item;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.Constraint;
@@ -44,7 +49,11 @@ import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
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.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.NamespaceService;
@@ -60,10 +69,13 @@ import org.apache.commons.beanutils.ConvertUtils;
*/
public class WorkflowRestImpl
{
protected static final String BPM_PACKAGE = "bpm_package";
protected TenantService tenantService;
protected AuthorityService authorityService;
protected NamespaceService namespaceService;
protected DictionaryService dictionaryService;
protected NodeService nodeService;
protected ProcessEngine activitiProcessEngine;
protected boolean deployWorkflowsInTenant;
protected List<String> excludeModelTypes = new ArrayList<String>(Arrays.asList("bpm_priority", "bpm_description", "bpm_dueDate"));
@@ -96,6 +108,11 @@ public class WorkflowRestImpl
this.dictionaryService = dictionaryService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setActivitiProcessEngine(ProcessEngine activitiProcessEngine)
{
this.activitiProcessEngine = activitiProcessEngine;
@@ -123,6 +140,192 @@ public class WorkflowRestImpl
return nodeRef;
}
/**
* Get all items from the process package variable
*/
public CollectionWithPagingInfo<Item> getItemsFromProcess(String processId, Paging paging)
{
ActivitiScriptNode packageScriptNode = null;
try
{
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)
{
throw new EntityNotFoundException(processId);
}
List<Item> page = new ArrayList<Item>();
if (packageScriptNode != null)
{
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
Item item = createItemForNodeRef(childAssociationRef.getChildRef());
page.add(item);
}
}
return CollectionWithPagingInfo.asPaged(paging, page, false, page.size());
}
/**
* Get an item from the process package variable
*/
public Item getItemFromProcess(String itemId, String processId)
{
NodeRef nodeRef = getNodeRef(itemId);
ActivitiScriptNode packageScriptNode = null;
try
{
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)
{
throw new EntityNotFoundException(processId);
}
Item item = null;
if (packageScriptNode != null)
{
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
if (childAssociationRef.getChildRef().equals(nodeRef))
{
item = createItemForNodeRef(childAssociationRef.getChildRef());
break;
}
}
}
if (item == null) {
throw new EntityNotFoundException(itemId);
}
return item;
}
/**
* Create a new item in the process package variable
*/
public Item createItemInProcess(String itemId, String processId)
{
NodeRef nodeRef = getNodeRef(itemId);
ActivitiScriptNode packageScriptNode = null;
try
{
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
if (packageScriptNode == null)
{
throw new InvalidArgumentException("process doesn't contain a workflow package variable");
}
// check if noderef exists
try
{
nodeService.getProperties(nodeRef);
}
catch (Exception e)
{
throw new EntityNotFoundException("item with id " + nodeRef.toString() + " not found");
}
try
{
QName workflowPackageItemId = QName.createQName("wpi", nodeRef.toString());
nodeService.addChild(packageScriptNode.getNodeRef(), nodeRef,
WorkflowModel.ASSOC_PACKAGE_CONTAINS, workflowPackageItemId);
}
catch (Exception e)
{
throw new ApiException("could not add item to process " + e.getMessage(), e);
}
Item responseItem = createItemForNodeRef(nodeRef);
return responseItem;
}
/**
* Delete an item from the process package variable
*/
public void deleteItemFromProcess(String itemId, String processId)
{
NodeRef nodeRef = getNodeRef(itemId);
ActivitiScriptNode packageScriptNode = null;
try
{
packageScriptNode = (ActivitiScriptNode) activitiProcessEngine.getRuntimeService().getVariable(processId, BPM_PACKAGE);
}
catch (ActivitiObjectNotFoundException e)
{
throw new EntityNotFoundException(processId);
}
if (packageScriptNode == null)
{
throw new InvalidArgumentException("process doesn't contain a workflow package variable");
}
boolean itemIdFoundInPackage = false;
List<ChildAssociationRef> documentList = nodeService.getChildAssocs(packageScriptNode.getNodeRef());
for (ChildAssociationRef childAssociationRef : documentList)
{
if (childAssociationRef.getChildRef().equals(nodeRef))
{
itemIdFoundInPackage = true;
break;
}
}
if (itemIdFoundInPackage == false)
{
throw new EntityNotFoundException("Item " + itemId + " not found in the process package variable");
}
try
{
nodeService.removeChild(packageScriptNode.getNodeRef(), nodeRef);
}
catch (InvalidNodeRefException e)
{
throw new EntityNotFoundException("Item " + itemId + " not found");
}
}
/**
* Get the process definition from the cache if available
*
@@ -342,4 +545,33 @@ public class WorkflowRestImpl
return variableInstances;
}
protected Item createItemForNodeRef(NodeRef nodeRef) {
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
Item item = new Item();
String name = (String) properties.get(ContentModel.PROP_NAME);
String title = (String) properties.get(ContentModel.PROP_TITLE);
String description = (String) properties.get(ContentModel.PROP_DESCRIPTION);
Date createdAt = (Date) properties.get(ContentModel.PROP_CREATED);
String createdBy = (String) properties.get(ContentModel.PROP_CREATOR);
Date modifiedAt = (Date) properties.get(ContentModel.PROP_MODIFIED);
String modifiedBy = (String) properties.get(ContentModel.PROP_MODIFIER);
ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
item.setId(nodeRef.getId());
item.setName(name);
item.setTitle(title);
item.setDescription(description);
item.setCreatedAt(createdAt);
item.setCreatedBy(createdBy);
item.setModifiedAt(modifiedAt);
item.setModifiedBy(modifiedBy);
if (contentData != null)
{
item.setMimeType(contentData.getMimetype());
item.setSize(contentData.getSize());
}
return item;
}
}

View File

@@ -25,10 +25,14 @@ import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.rest.api.tests.AbstractTestFixture;
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext;
@@ -118,40 +122,53 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
}
// @Test
// public void testGetDeploymentsEmpty() throws Exception
// {
// // Create a new test-network, not added to the test-fixture to prevent being used
// // in other tests
// String networkName = AbstractTestFixture.TEST_DOMAIN_PREFIX + UUID.randomUUID();
// TestNetwork testNetwork = repoService.createNetworkWithAlias(networkName, true);
// testNetwork.create();
//
// // Delete all deployments in the network
// List<org.activiti.engine.repository.Deployment> deployments = activitiProcessEngine.getRepositoryService()
// .createDeploymentQuery()
// .processDefinitionKeyLike("@" + networkName + "@")
// .list();
//
// for(org.activiti.engine.repository.Deployment deployment : deployments) {
// activitiProcessEngine.getRepositoryService().deleteDeployment(deployment.getId(), true);
// }
//
// // Fetch deployments using tenant-admin
// String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + networkName;
// publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin));
//
// DeploymentsClient deploymentsClient = publicApiClient.deploymentsClient();
//
// ListResponse<Deployment> deploymentResponse = deploymentsClient.getDeployments();
// assertEquals(0, deploymentResponse.getList().size());
// }
@Test
public void testGetDeploymentsEmpty() throws Exception
{
// Create a new test-network, not added to the test-fixture to prevent being used
// in other tests
String networkName = AbstractTestFixture.TEST_DOMAIN_PREFIX + "999";
final TestNetwork testNetwork = repoService.createNetworkWithAlias(networkName, true);
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
@SuppressWarnings("synthetic-access")
public Void execute() throws Throwable
{
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
testNetwork.create();
return null;
}
}, false, true);
// Delete all deployments in the network
List<org.activiti.engine.repository.Deployment> deployments = activitiProcessEngine.getRepositoryService()
.createDeploymentQuery()
.processDefinitionKeyLike("@" + testNetwork.getId() + "@%")
.list();
for(org.activiti.engine.repository.Deployment deployment : deployments)
{
activitiProcessEngine.getRepositoryService().deleteDeployment(deployment.getId(), true);
}
// Fetch deployments using tenant-admin
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + testNetwork.getId();
publicApiClient.setRequestContext(new RequestContext(testNetwork.getId(), tenantAdmin));
DeploymentsClient deploymentsClient = publicApiClient.deploymentsClient();
ListResponse<Deployment> deploymentResponse = deploymentsClient.getDeployments();
assertEquals(0, deploymentResponse.getList().size());
}
@Test
public void testGetDeploymentById() throws Exception
{
// Use admin-user for tenant
RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin));
@@ -174,6 +191,28 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDeployment.getCategory(), deployment.getCategory());
assertEquals(activitiDeployment.getName(), deployment.getName());
assertEquals(activitiDeployment.getDeploymentTime(), deployment.getDeployedAt());
try
{
deploymentsClient.findDeploymentById("fakeid");
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// get deployment with default user
try
{
publicApiClient.setRequestContext(requestContext);
deploymentsClient.findDeploymentById(activitiDeployment.getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(403, e.getHttpResponse().getStatusCode());
}
}
protected String createProcessDefinitionKey(String key, RequestContext requestContext) {

View File

@@ -175,6 +175,21 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(processDefinitionMap.containsKey("activitiAdhoc"));
assertEquals(1, processDefinitionMap.size());
// Use AND operator
processDefinitionMap = getProcessDefinitions(processDefinitionsClient, "(category = 'http://alfresco.org' AND name = 'Adhoc Activiti Process')");
assertTrue(processDefinitionMap.containsKey("activitiAdhoc"));
assertEquals(1, processDefinitionMap.size());
// Use OR operator
try
{
processDefinitionMap = getProcessDefinitions(processDefinitionsClient, "(category = 'http://alfresco.org' OR name = 'Adhoc Activiti Process')");
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(400, e.getHttpResponse().getStatusCode());
}
}
@Test
@@ -182,6 +197,9 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
{
RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext);
org.activiti.engine.repository.ProcessDefinition activitiDefinition = activitiProcessEngine.getRepositoryService()
.createProcessDefinitionQuery()
@@ -204,6 +222,15 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDefinition.getVersion(), adhocDefinition.getVersion());
assertEquals(((ProcessDefinitionEntity) activitiDefinition).isGraphicalNotationDefined(), adhocDefinition.isGraphicNotationDefined());
assertEquals("wf:submitAdhocTask", adhocDefinition.getStartFormResourceKey());
// get process definition with admin
publicApiClient.setRequestContext(adminContext);
adhocDefinition = processDefinitionsClient.findProcessDefinitionById(activitiDefinition.getId());
assertNotNull(adhocDefinition);
// Check fields of a resulting process-definition
assertEquals(activitiDefinition.getId(), adhocDefinition.getId());
assertEquals("activitiAdhoc", adhocDefinition.getKey());
}
@Test
@@ -227,6 +254,10 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
public void testGetProcessDefinitionStartModel() throws Exception
{
RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
ProcessDefinitionsClient processDefinitionsClient = publicApiClient.processDefinitionsClient();
String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext);
@@ -322,6 +353,43 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(allowedValues.contains("On Hold"));
assertTrue(allowedValues.contains("Cancelled"));
assertTrue(allowedValues.contains("Completed"));
// get start form model with admin
publicApiClient.setRequestContext(adminContext);
model = processDefinitionsClient.findStartFormModel(activitiDefinition.getId());
assertNotNull(model);
entries = (JSONArray) model.get("entries");
assertNotNull(entries);
// Add all entries to a map, to make lookup easier
modelFieldsByName = new HashMap<String, JSONObject>();
for(int i=0; i<entries.size(); i++)
{
entry = (JSONObject) entries.get(i);
assertNotNull(entry);
entry = (JSONObject) entry.get("entry");
assertNotNull(entry);
modelFieldsByName.put((String) entry.get("name"), entry);
}
// Check well-known properties and their types
// Validate bpm:description
modelEntry = modelFieldsByName.get("bpm_workflowDescription");
assertNotNull(modelEntry);
assertEquals("Description", modelEntry.get("title"));
assertEquals("{http://www.alfresco.org/model/bpm/1.0}workflowDescription", modelEntry.get("qualifiedName"));
assertEquals("d:text", modelEntry.get("dataType"));
assertFalse((Boolean)modelEntry.get("required"));
// Validate bpm:description
modelEntry = modelFieldsByName.get("bpm_completionDate");
assertNotNull(modelEntry);
assertEquals("Completion Date", modelEntry.get("title"));
assertEquals("{http://www.alfresco.org/model/bpm/1.0}completionDate", modelEntry.get("qualifiedName"));
assertEquals("d:date", modelEntry.get("dataType"));
assertFalse((Boolean)modelEntry.get("required"));
}
@Test

View File

@@ -37,6 +37,7 @@ import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
import org.alfresco.rest.api.tests.client.HttpResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext;
@@ -218,6 +219,69 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
}
}
@Test
public void testCreateProcessInstanceWithNoParams() throws Exception
{
initApiClientWithTestUser();
ProcessesClient processesClient = publicApiClient.processesClient();
JSONObject createProcessObject = new JSONObject();
try
{
processesClient.createProcess(createProcessObject.toJSONString());
fail("Exception excpected");
}
catch (PublicApiException e)
{
assertEquals(400, e.getHttpResponse().getStatusCode());
}
}
@Test
public void testMethodNotAllowedURIs() throws Exception
{
RequestContext requestContext = initApiClientWithTestUser();
HttpResponse response = publicApiClient.get("public", "processes", null, null, null, null);
assertEquals(200, response.getStatusCode());
response = publicApiClient.put("public", "processes", null, null, null, null, null);
assertEquals(405, response.getStatusCode());
final ProcessInfo processInfo = startAdhocProcess(requestContext, null);
try
{
response = publicApiClient.get("public", "processes", processInfo.getId(), null, null, null);
assertEquals(200, response.getStatusCode());
response = publicApiClient.post("public", "processes", processInfo.getId(), null, null, null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.put("public", "processes", processInfo.getId(), null, null, null, null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.get("public", "processes", processInfo.getId(), "activities", null, null);
assertEquals(200, response.getStatusCode());
response = publicApiClient.post("public", "processes", processInfo.getId(), "activities", null, null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.delete("public", "processes", processInfo.getId(), "activities", null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.put("public", "processes", processInfo.getId(), "activities", null, null, null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.get("public", "processes", processInfo.getId(), "tasks", null, null);
assertEquals(200, response.getStatusCode());
response = publicApiClient.post("public", "processes", processInfo.getId(), "tasks", null, null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.delete("public", "processes", processInfo.getId(), "tasks", null);
assertEquals(405, response.getStatusCode());
response = publicApiClient.put("public", "processes", processInfo.getId(), "tasks", null, null, null);
assertEquals(405, response.getStatusCode());
}
finally
{
cleanupProcessInstance(processInfo.getId());
}
}
@Test
public void testCreateProcessInstanceForPooledReview() throws Exception
{
@@ -225,6 +289,7 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final ProcessInfo processInfo = startReviewPooledProcess(requestContext);
assertNotNull(processInfo);
assertNotNull(processInfo.getId());
cleanupProcessInstance(processInfo.getId());
}
@Test
@@ -234,11 +299,12 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final ProcessInfo processInfo = startParallelReviewProcess(requestContext);
assertNotNull(processInfo);
assertNotNull(processInfo.getId());
cleanupProcessInstance(processInfo.getId());
}
@Test
@SuppressWarnings("unchecked")
public void testCreateProcessInstanceFormOtherNetwork() throws Exception
public void testCreateProcessInstanceFromOtherNetwork() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
@@ -432,10 +498,13 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
initApiClientWithTestUser();
ProcessesClient processesClient = publicApiClient.processesClient();
try {
try
{
processesClient.findProcessById("unexisting");
fail("Exception expected");
} catch(PublicApiException expected) {
}
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: unexisting was not found", expected.getHttpResponse());
}
@@ -922,6 +991,25 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
}
}
@Test
public void getProcessImage() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
final ProcessInfo processRest = startAdhocProcess(requestContext, null);
HttpResponse response = publicApiClient.processesClient().getImage(processRest.getId());
assertEquals(200, response.getStatusCode());
cleanupProcessInstance(processRest.getId());
try
{
response = publicApiClient.processesClient().getImage("fakeId");
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
}
@Test
public void testGetProcessItems() throws Exception
{
@@ -974,6 +1062,16 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(doc2Found);
cleanupProcessInstance(processRest.getId());
try
{
processesClient.findProcessItems("fakeid");
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
}
@Test
@@ -987,7 +1085,6 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final String newProcessInstanceId = processRest.getId();
ProcessesClient processesClient = publicApiClient.processesClient();
System.out.println("node ref " + docNodeRefs[0].toString());
JSONObject itemJSON = processesClient.findProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
assertNotNull(itemJSON);
@@ -1107,6 +1204,80 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
}
}
@Test
public void testDeleteProcessItemWithAdmin() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
final RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
publicApiClient.setRequestContext(adminContext);
// start process with admin user
NodeRef[] docNodeRefs = createTestDocuments(adminContext);
final ProcessInfo processRest = startAdhocProcess(adminContext, docNodeRefs);
try
{
assertNotNull(processRest);
final String newProcessInstanceId = processRest.getId();
ProcessesClient processesClient = publicApiClient.processesClient();
// Delete the item
processesClient.deleteProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
// Fetching the item should result in 404
try
{
publicApiClient.processesClient().findProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
fail("Exception expected");
}
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: " + docNodeRefs[0].getId() + " was not found", expected.getHttpResponse());
}
}
finally
{
cleanupProcessInstance(processRest.getId());
}
// start process with default user and delete item with admin
publicApiClient.setRequestContext(requestContext);
docNodeRefs = createTestDocuments(requestContext);
final ProcessInfo processRestDefaultUser = startAdhocProcess(requestContext, docNodeRefs);
try
{
assertNotNull(processRestDefaultUser);
publicApiClient.setRequestContext(adminContext);
final String newProcessInstanceId = processRestDefaultUser.getId();
ProcessesClient processesClient = publicApiClient.processesClient();
// Delete the item
processesClient.deleteProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
// Fetching the item should result in 404
try
{
publicApiClient.processesClient().findProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
fail("Exception expected");
}
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: " + docNodeRefs[0].getId() + " was not found", expected.getHttpResponse());
}
}
finally
{
cleanupProcessInstance(processRestDefaultUser.getId());
}
}
@Test
public void testGetProcessVariables() throws Exception
{
@@ -1458,16 +1629,20 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
{
initApiClientWithTestUser();
try {
try
{
publicApiClient.processesClient().deleteVariable("unexisting", "deleteMe");
fail("Exception expected");
} catch(PublicApiException expected) {
}
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: unexisting was not found", expected.getHttpResponse());
}
}
protected void completeAdhocTasks(String instanceId, RequestContext requestContext) {
protected void completeAdhocTasks(String instanceId, RequestContext requestContext)
{
final Task task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(instanceId).singleResult();
assertEquals(requestContext.getRunAsUser(), task.getAssignee());

View File

@@ -53,7 +53,6 @@ import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext;
import org.alfresco.rest.api.tests.client.data.MemberOfSite;
import org.alfresco.rest.workflow.api.model.ProcessInfo;
import org.alfresco.rest.workflow.api.tests.WorkflowApiClient.ProcessesClient;
import org.alfresco.rest.workflow.api.tests.WorkflowApiClient.TasksClient;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ISO8601DateFormat;
@@ -968,6 +967,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
String businessKey = UUID.randomUUID().toString();
ProcessInstance processInstance = startAdhocProcess(requestContext.getRunAsUser(), requestContext.getNetworkId(), businessKey);
try
{
// Complete the adhoc task
final Task completedTask = activitiProcessEngine.getTaskService().createTaskQuery()
.processInstanceId(processInstance.getId()).singleResult();
@@ -1294,6 +1295,11 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
params.put("where", "(variables/numberVar < 'd:int 10')");
assertEquals(0, getResultSizeForTaskQuery(params, tasksClient));
}
finally
{
cleanupProcessInstance(processInstance);
}
}
@Test
public void testGetTasksWithPaging() throws Exception
@@ -2463,20 +2469,26 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
{
final RequestContext requestContext = initApiClientWithTestUser();
String otherPerson = getOtherPersonInNetwork(requestContext.getRunAsUser(), requestContext.getNetworkId()).getId();
RequestContext otherContext = new RequestContext(requestContext.getNetworkId(), otherPerson);
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
// Create test-document and add to package
NodeRef[] docNodeRefs = createTestDocuments(requestContext);
ProcessInfo processInfo = startAdhocProcess(requestContext, docNodeRefs);
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery()
Task task = activitiProcessEngine.getTaskService().createTaskQuery()
.processInstanceId(processInfo.getId()).singleResult();
assertNotNull(processInstance);
assertNotNull(task);
activitiProcessEngine.getTaskService().setAssignee(task.getId(), null);
try
{
final String newProcessInstanceId = processInstance.getId();
ProcessesClient processesClient = publicApiClient.processesClient();
JSONObject itemsJSON = processesClient.findProcessItems(newProcessInstanceId);
TasksClient tasksClient = publicApiClient.tasksClient();
JSONObject itemsJSON = tasksClient.findTaskItems(task.getId());
assertNotNull(itemsJSON);
JSONArray entriesJSON = (JSONArray) itemsJSON.get("entries");
assertNotNull(entriesJSON);
@@ -2515,10 +2527,398 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
}
assertTrue(doc1Found);
assertTrue(doc2Found);
// get with admin
publicApiClient.setRequestContext(adminContext);
itemsJSON = tasksClient.findTaskItems(task.getId());
assertNotNull(itemsJSON);
entriesJSON = (JSONArray) itemsJSON.get("entries");
assertNotNull(entriesJSON);
assertTrue(entriesJSON.size() == 2);
// get with non involved user
publicApiClient.setRequestContext(otherContext);
try
{
tasksClient.findTaskItems(task.getId());
}
catch (PublicApiException e)
{
assertEquals(403, e.getHttpResponse().getStatusCode());
}
// get with candidate user
activitiProcessEngine.getTaskService().addCandidateUser(task.getId(), otherContext.getRunAsUser());
publicApiClient.setRequestContext(otherContext);
itemsJSON = tasksClient.findTaskItems(task.getId());
assertNotNull(itemsJSON);
entriesJSON = (JSONArray) itemsJSON.get("entries");
assertNotNull(entriesJSON);
assertTrue(entriesJSON.size() == 2);
// get with user from candidate group
List<MemberOfSite> memberships = getTestFixture().getNetwork(otherContext.getNetworkId()).getSiteMemberships(otherContext.getRunAsUser());
assertTrue(memberships.size() > 0);
MemberOfSite memberOfSite = memberships.get(0);
String group = "GROUP_site_" + memberOfSite.getSiteId() + "_" + memberOfSite.getRole().name();
activitiProcessEngine.getTaskService().deleteCandidateUser(task.getId(), otherContext.getRunAsUser());
activitiProcessEngine.getTaskService().addCandidateGroup(task.getId(), group);
publicApiClient.setRequestContext(otherContext);
itemsJSON = tasksClient.findTaskItems(task.getId());
assertNotNull(itemsJSON);
entriesJSON = (JSONArray) itemsJSON.get("entries");
assertNotNull(entriesJSON);
assertTrue(entriesJSON.size() == 2);
// invalid task id
publicApiClient.setRequestContext(requestContext);
try
{
tasksClient.findTaskItems("fakeid");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
}
finally
{
cleanupProcessInstance(processInstance);
cleanupProcessInstance(processInfo.getId());
}
}
@Test
@SuppressWarnings("unchecked")
public void testAddTaskItem() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
String otherPerson = getOtherPersonInNetwork(requestContext.getRunAsUser(), requestContext.getNetworkId()).getId();
RequestContext otherContext = new RequestContext(requestContext.getNetworkId(), otherPerson);
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
// Create test-document and add to package
NodeRef[] docNodeRefs = createTestDocuments(requestContext);
ProcessInfo processInfo = startAdhocProcess(requestContext, null);
final Task task = activitiProcessEngine.getTaskService()
.createTaskQuery()
.processInstanceId(processInfo.getId())
.singleResult();
assertNotNull(task);
try
{
TasksClient tasksClient = publicApiClient.tasksClient();
JSONObject createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
JSONObject result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
assertEquals("Test Doc1", result.get("name"));
assertEquals("Test Doc1 Title", result.get("title"));
assertEquals("Test Doc1 Description", result.get("description"));
assertNotNull(result.get("createdAt"));
assertEquals(requestContext.getRunAsUser(), result.get("createdBy"));
assertNotNull(result.get("modifiedAt"));
assertEquals(requestContext.getRunAsUser(), result.get("modifiedBy"));
assertNotNull(result.get("size"));
assertNotNull(result.get("mimeType"));
JSONObject itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// add item as admin
publicApiClient.setRequestContext(adminContext);
result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
assertEquals("Test Doc1", result.get("name"));
itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// add item with candidate user
activitiProcessEngine.getTaskService().addCandidateUser(task.getId(), otherPerson);
publicApiClient.setRequestContext(otherContext);
result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
assertEquals("Test Doc1", result.get("name"));
itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// add item with not involved user
activitiProcessEngine.getTaskService().deleteCandidateUser(task.getId(), otherPerson);
publicApiClient.setRequestContext(otherContext);
try
{
tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(403, e.getHttpResponse().getStatusCode());
}
// invalid task id
publicApiClient.setRequestContext(requestContext);
try
{
tasksClient.addTaskItem("fakeid", createItemObject.toJSONString());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// invalid item id
createItemObject = new JSONObject();
createItemObject.put("id", "fakeid");
try
{
tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// add item to completed task
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
activitiProcessEngine.getTaskService().complete(task.getId());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
try
{
tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
}
finally
{
cleanupProcessInstance(processInfo.getId());
}
}
@Test
@SuppressWarnings("unchecked")
public void testDeleteTaskItem() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
String otherPerson = getOtherPersonInNetwork(requestContext.getRunAsUser(), requestContext.getNetworkId()).getId();
RequestContext otherContext = new RequestContext(requestContext.getNetworkId(), otherPerson);
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
// Create test-document and add to package
NodeRef[] docNodeRefs = createTestDocuments(requestContext);
ProcessInfo processInfo = startAdhocProcess(requestContext, docNodeRefs);
final Task task = activitiProcessEngine.getTaskService()
.createTaskQuery()
.processInstanceId(processInfo.getId())
.singleResult();
assertNotNull(task);
try
{
TasksClient tasksClient = publicApiClient.tasksClient();
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// delete item as admin
JSONObject createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
JSONObject result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
JSONObject itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
publicApiClient.setRequestContext(adminContext);
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// delete item with candidate user
createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
activitiProcessEngine.getTaskService().addCandidateUser(task.getId(), otherPerson);
publicApiClient.setRequestContext(otherContext);
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
try
{
tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// delete item with not involved user
createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
activitiProcessEngine.getTaskService().deleteCandidateUser(task.getId(), otherPerson);
publicApiClient.setRequestContext(otherContext);
try
{
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(403, e.getHttpResponse().getStatusCode());
}
// invalid task id
publicApiClient.setRequestContext(requestContext);
try
{
tasksClient.deleteTaskItem("fakeid", docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// invalid item id
try
{
tasksClient.deleteTaskItem(task.getId(), "fakeid");
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
// delete item from completed task
createItemObject = new JSONObject();
createItemObject.put("id", docNodeRefs[0].getId());
result = tasksClient.addTaskItem(task.getId(), createItemObject.toJSONString());
assertNotNull(result);
assertEquals(docNodeRefs[0].getId(), result.get("id"));
itemJSON = tasksClient.findTaskItem(task.getId(), docNodeRefs[0].getId());
assertEquals(docNodeRefs[0].getId(), itemJSON.get("id"));
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
activitiProcessEngine.getTaskService().complete(task.getId());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
try
{
tasksClient.deleteTaskItem(task.getId(), docNodeRefs[0].getId());
fail("Expected exception");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
}
finally
{
cleanupProcessInstance(processInfo.getId());
}
}
@@ -2597,4 +2997,22 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
log("Error while cleaning up process instance");
}
}
protected void cleanupProcessInstance(String... processInstances)
{
// Clean up process-instance regardless of test success/failure
try
{
for (String instanceId : processInstances)
{
activitiProcessEngine.getRuntimeService().deleteProcessInstance(instanceId, null);
activitiProcessEngine.getHistoryService().deleteHistoricProcessInstance(instanceId);
}
}
catch(Throwable t)
{
// Ignore error during cleanup to prevent swallowing potential assetion-exception
log("Error while cleaning up process instance");
}
}
}

View File

@@ -158,6 +158,12 @@ public class WorkflowApiClient extends PublicApiClient
return list;
}
public HttpResponse getImage(String processInstanceId) throws PublicApiException
{
HttpResponse response = getSingle("processes", processInstanceId, "image", null, "Failed to get image of processInstanceId " + processInstanceId);
return response;
}
public JSONObject findProcessItems(String processInstanceId) throws PublicApiException
{
HttpResponse response = getAll("processes", processInstanceId, "items", null, null,
@@ -283,6 +289,34 @@ public class WorkflowApiClient extends PublicApiClient
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
return list;
}
public JSONObject findTaskItems(String taskId) throws PublicApiException
{
HttpResponse response = getAll("tasks", taskId, "items", null, null,
"Failed to get the items of the task");
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
return list;
}
public JSONObject addTaskItem(String taskId, String body) throws PublicApiException
{
HttpResponse response = create("tasks", taskId, "items", null, body, "Failed to add item");
JSONObject entry = (JSONObject) response.getJsonResponse().get("entry");
return entry;
}
public void deleteTaskItem(String taskId, String itemId) throws PublicApiException
{
remove("tasks", taskId, "items", itemId, "Failed to delete item");
}
public JSONObject findTaskItem(String taskId, String itemId) throws PublicApiException
{
HttpResponse response = getAll("tasks", taskId, "items", itemId, null,
"Failed to get the item of the task");
JSONObject entry = (JSONObject) response.getJsonResponse().get("entry");
return entry;
}
}
public static Date parseDate(JSONObject entry, String fieldName) {