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="dictionaryService" ref="DictionaryService" />
<property name="namespaceService" ref="NamespaceService" /> <property name="namespaceService" ref="NamespaceService" />
<property name="tenantService" ref="tenantService" /> <property name="tenantService" ref="tenantService" />
<property name="nodeService" ref="nodeService"/>
</bean> </bean>
<bean id="deployments" class="org.alfresco.rest.workflow.api.impl.DeploymentsImpl" parent="baseWorkflowRest"> <bean id="deployments" class="org.alfresco.rest.workflow.api.impl.DeploymentsImpl" parent="baseWorkflowRest">
@@ -874,7 +874,6 @@
<property name="workflowPackageComponent" ref="workflowPackageImpl"/> <property name="workflowPackageComponent" ref="workflowPackageImpl"/>
<property name="serviceRegistry" ref="ServiceRegistry" /> <property name="serviceRegistry" ref="ServiceRegistry" />
<property name="authorityDAO" ref="authorityDAO" /> <property name="authorityDAO" ref="authorityDAO" />
<property name="nodeService" ref="nodeService"/>
<property name="personService" ref="PersonService" /> <property name="personService" ref="PersonService" />
<property name="messageService" ref="messageService" /> <property name="messageService" ref="messageService" />
<property name="engineId" value="activiti" /> <property name="engineId" value="activiti" />
@@ -899,7 +898,6 @@
<bean id="tasks" class="org.alfresco.rest.workflow.api.impl.TasksImpl" parent="baseWorkflowRest"> <bean id="tasks" class="org.alfresco.rest.workflow.api.impl.TasksImpl" parent="baseWorkflowRest">
<property name="restVariableHelper" ref="restVariableHelper" /> <property name="restVariableHelper" ref="restVariableHelper" />
<property name="messageService" ref="messageService" /> <property name="messageService" ref="messageService" />
<property name="processes" ref="processes"/>
</bean> </bean>
<bean id="Tasks" class="org.springframework.aop.framework.ProxyFactoryBean"> <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.WorkflowQNameConverter;
import org.alfresco.repo.workflow.activiti.ActivitiConstants; import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.activiti.ActivitiNodeConverter; 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.ActivitiTypeConverter;
import org.alfresco.repo.workflow.activiti.ActivitiUtil; import org.alfresco.repo.workflow.activiti.ActivitiUtil;
import org.alfresco.repo.workflow.activiti.properties.ActivitiPropertyConverter; 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.DataTypeDefinition;
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.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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
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;
@@ -101,8 +96,6 @@ import org.apache.commons.io.IOUtils;
public class ProcessesImpl extends WorkflowRestImpl implements Processes 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_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";
@@ -130,7 +123,6 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
protected WorkflowPackageImpl workflowPackageComponent; protected WorkflowPackageImpl workflowPackageComponent;
protected ServiceRegistry serviceRegistry; protected ServiceRegistry serviceRegistry;
protected AuthorityDAO authorityDAO; protected AuthorityDAO authorityDAO;
protected NodeService nodeService;
protected PersonService personService; protected PersonService personService;
protected MessageService messageService; protected MessageService messageService;
protected String engineId; protected String engineId;
@@ -163,11 +155,6 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
this.workflowPackageComponent = workflowPackageComponent; this.workflowPackageComponent = workflowPackageComponent;
} }
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService) public void setPersonService(PersonService personService)
{ {
this.personService = personService; this.personService = personService;
@@ -754,42 +741,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
} }
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
return getItemsFromProcess(processId, 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());
} }
@Override @Override
@@ -805,52 +757,8 @@ 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);
return getItemFromProcess(itemId, 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;
} }
@Override @Override
@@ -867,46 +775,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
} }
validateIfUserAllowedToWorkWithProcess(processId); validateIfUserAllowedToWorkWithProcess(processId);
return createItemInProcess(item.getId(), 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;
} }
@Override @Override
@@ -922,49 +791,8 @@ 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);
deleteItemFromProcess(itemId, 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");
}
} }
@Override @Override
@@ -1233,33 +1061,4 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
processInfo.setProcessDefinitionKey(getLocalProcessDefinitionKey(definitionEntity.getKey())); processInfo.setProcessDefinitionKey(getLocalProcessDefinitionKey(definitionEntity.getKey()));
return processInfo; 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.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters; import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper; 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.Tasks;
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker.QueryVariableHolder; import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker.QueryVariableHolder;
import org.alfresco.rest.workflow.api.model.FormModelElement; import org.alfresco.rest.workflow.api.model.FormModelElement;
@@ -123,7 +122,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
private WorkflowObjectFactory workflowFactory; private WorkflowObjectFactory workflowFactory;
private WorkflowQNameConverter qNameConverter; private WorkflowQNameConverter qNameConverter;
private MessageService messageService; private MessageService messageService;
private Processes processes;
public void setRestVariableHelper(RestVariableHelper restVariableHelper) public void setRestVariableHelper(RestVariableHelper restVariableHelper)
{ {
@@ -135,11 +133,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
this.messageService = messageService; this.messageService = messageService;
} }
public void setProcesses(Processes processes)
{
this.processes = processes;
}
@Override @Override
public CollectionWithPagingInfo<Task> getTasks(Parameters parameters) public CollectionWithPagingInfo<Task> getTasks(Parameters parameters)
{ {
@@ -634,7 +627,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
throw new InvalidArgumentException("Task id is required"); throw new InvalidArgumentException("Task id is required");
} }
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId, true); HistoricTaskInstance taskInstance = getValidHistoricTask(taskId);
return new Task(taskInstance); return new Task(taskInstance);
} }
@@ -818,7 +811,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
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
HistoricTaskInstance task = getValidHistoricTask(taskId, true); HistoricTaskInstance task = getValidHistoricTask(taskId);
String formKey = task.getFormKey(); String formKey = task.getFormKey();
// Lookup type definition for the task // 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) 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.
HistoricTaskInstance taskInstance = getValidHistoricTask(taskId, true); HistoricTaskInstance taskInstance = getValidHistoricTask(taskId);
String formKey = taskInstance.getFormKey(); String formKey = taskInstance.getFormKey();
// Based on the scope, right variables are queried // Based on the scope, right variables are queried
@@ -878,13 +871,13 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override @Override
public TaskVariable updateTaskVariable(String taskId, TaskVariable taskVariable) 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); return updateVariableInTask(taskId, taskInstance, taskVariable);
} }
public List<TaskVariable> updateTaskVariables(String taskId, List<TaskVariable> variables) 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>(); List<TaskVariable> updatedVariables = new ArrayList<TaskVariable>();
if (variables != null) 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 // 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 // Check if variable is present on the scope
if (activitiProcessEngine.getTaskService().hasVariableLocal(taskId, variableName) == false) 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) public CollectionWithPagingInfo<TaskCandidate> getTaskCandidates(String taskId, Paging paging)
{ {
// Fetch task to check if user is authorized to perform the delete // 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<IdentityLink> links = activitiProcessEngine.getTaskService().getIdentityLinksForTask(taskId);
List<TaskCandidate> page = new ArrayList<TaskCandidate>(); List<TaskCandidate> page = new ArrayList<TaskCandidate>();
@@ -1038,49 +1031,49 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
@Override @Override
public Item createItem(String taskId, Item item) 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) 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.");
} }
return processes.createItem(task.getProcessInstanceId(), item); return createItemInProcess(item.getId(), task.getProcessInstanceId());
} }
@Override @Override
public void deleteItem(String taskId, String itemId) 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) 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.");
} }
processes.deleteItem(task.getProcessInstanceId(), itemId); deleteItemFromProcess(itemId, task.getProcessInstanceId());
} }
@Override @Override
public Item getItem(String taskId, String itemId) public Item getItem(String taskId, String itemId)
{ {
HistoricTaskInstance task = getValidHistoricTask(taskId, true); HistoricTaskInstance task = getValidHistoricTask(taskId);
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.");
} }
return processes.getItem(task.getProcessInstanceId(), itemId); return getItemFromProcess(itemId, task.getProcessInstanceId());
} }
@Override @Override
public CollectionWithPagingInfo<Item> getItems(String taskId, Paging paging) public CollectionWithPagingInfo<Item> getItems(String taskId, Paging paging)
{ {
HistoricTaskInstance task = getValidHistoricTask(taskId, true); HistoricTaskInstance task = getValidHistoricTask(taskId);
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.");
} }
return processes.getItems(task.getProcessInstanceId(), paging); return getItemsFromProcess(task.getProcessInstanceId(), paging);
} }
protected String getFormResourceKey(final org.activiti.engine.task.Task task) 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 EntityNotFoundException when the task was not found
* @throws PermissionDeniedException when the current logged in user isn't allowed to access task. * @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() HistoricTaskInstanceQuery query = activitiProcessEngine.getHistoryService()
.createHistoricTaskInstanceQuery() .createHistoricTaskInstanceQuery()
@@ -1214,9 +1207,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
else else
{ {
boolean isTaskClaimable = false; boolean isTaskClaimable = false;
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
@@ -1227,7 +1217,6 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
.taskId(taskId) .taskId(taskId)
.count() == 1; .count() == 1;
} }
}
if (isTaskClaimable == false) if (isTaskClaimable == false)
{ {
@@ -1246,7 +1235,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
* @throws EntityNotFoundException when the task was not found * @throws EntityNotFoundException when the task was not found
* @throws PermissionDeniedException when the current logged in user isn't allowed to access task. * @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) if (taskId == null)
{ {
@@ -1288,19 +1277,14 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
throw new EntityNotFoundException(taskId); throw new EntityNotFoundException(taskId);
} }
else 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 // 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() boolean 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 == false) if (isTaskClaimable == false)
{ {

View File

@@ -1,5 +1,6 @@
package org.alfresco.rest.workflow.api.impl; package org.alfresco.rest.workflow.api.impl;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
@@ -11,6 +12,7 @@ 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;
@@ -28,8 +30,10 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil; import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.workflow.WorkflowConstants; 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.ActivitiConstants;
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode; 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.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; 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.Paging;
import org.alfresco.rest.framework.resource.parameters.Parameters; import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.workflow.api.model.FormModelElement; 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.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.Constraint; 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.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.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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; 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;
@@ -60,10 +69,13 @@ import org.apache.commons.beanutils.ConvertUtils;
*/ */
public class WorkflowRestImpl public class WorkflowRestImpl
{ {
protected static final String BPM_PACKAGE = "bpm_package";
protected TenantService tenantService; protected TenantService tenantService;
protected AuthorityService authorityService; protected AuthorityService authorityService;
protected NamespaceService namespaceService; protected NamespaceService namespaceService;
protected DictionaryService dictionaryService; protected DictionaryService dictionaryService;
protected NodeService nodeService;
protected ProcessEngine activitiProcessEngine; protected ProcessEngine activitiProcessEngine;
protected boolean deployWorkflowsInTenant; protected boolean deployWorkflowsInTenant;
protected List<String> excludeModelTypes = new ArrayList<String>(Arrays.asList("bpm_priority", "bpm_description", "bpm_dueDate")); 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; this.dictionaryService = dictionaryService;
} }
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setActivitiProcessEngine(ProcessEngine activitiProcessEngine) public void setActivitiProcessEngine(ProcessEngine activitiProcessEngine)
{ {
this.activitiProcessEngine = activitiProcessEngine; this.activitiProcessEngine = activitiProcessEngine;
@@ -123,6 +140,192 @@ public class WorkflowRestImpl
return nodeRef; 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 * Get the process definition from the cache if available
* *
@@ -342,4 +545,33 @@ public class WorkflowRestImpl
return variableInstances; 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.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantUtil; 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.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiException; import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext; import org.alfresco.rest.api.tests.client.RequestContext;
@@ -118,40 +122,53 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt()); assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
} }
// @Test @Test
// public void testGetDeploymentsEmpty() throws Exception public void testGetDeploymentsEmpty() throws Exception
// { {
// // Create a new test-network, not added to the test-fixture to prevent being used // Create a new test-network, not added to the test-fixture to prevent being used
// // in other tests // in other tests
// String networkName = AbstractTestFixture.TEST_DOMAIN_PREFIX + UUID.randomUUID(); String networkName = AbstractTestFixture.TEST_DOMAIN_PREFIX + "999";
// TestNetwork testNetwork = repoService.createNetworkWithAlias(networkName, true); final TestNetwork testNetwork = repoService.createNetworkWithAlias(networkName, true);
// testNetwork.create(); transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
// {
// // Delete all deployments in the network @SuppressWarnings("synthetic-access")
// List<org.activiti.engine.repository.Deployment> deployments = activitiProcessEngine.getRepositoryService() public Void execute() throws Throwable
// .createDeploymentQuery() {
// .processDefinitionKeyLike("@" + networkName + "@") AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
// .list();
// testNetwork.create();
// for(org.activiti.engine.repository.Deployment deployment : deployments) {
// activitiProcessEngine.getRepositoryService().deleteDeployment(deployment.getId(), true); return null;
// } }
// }, false, true);
// // Fetch deployments using tenant-admin
// String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + networkName; // Delete all deployments in the network
// publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin)); List<org.activiti.engine.repository.Deployment> deployments = activitiProcessEngine.getRepositoryService()
// .createDeploymentQuery()
// DeploymentsClient deploymentsClient = publicApiClient.deploymentsClient(); .processDefinitionKeyLike("@" + testNetwork.getId() + "@%")
// .list();
// ListResponse<Deployment> deploymentResponse = deploymentsClient.getDeployments();
// assertEquals(0, deploymentResponse.getList().size()); 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 @Test
public void testGetDeploymentById() throws Exception public void testGetDeploymentById() throws Exception
{ {
// Use admin-user for tenant // Use admin-user for tenant
RequestContext requestContext = initApiClientWithTestUser(); RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId(); String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin)); publicApiClient.setRequestContext(new RequestContext(TenantUtil.DEFAULT_TENANT, tenantAdmin));
@@ -174,6 +191,28 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDeployment.getCategory(), deployment.getCategory()); assertEquals(activitiDeployment.getCategory(), deployment.getCategory());
assertEquals(activitiDeployment.getName(), deployment.getName()); assertEquals(activitiDeployment.getName(), deployment.getName());
assertEquals(activitiDeployment.getDeploymentTime(), deployment.getDeployedAt()); 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) { protected String createProcessDefinitionKey(String key, RequestContext requestContext) {

View File

@@ -175,6 +175,21 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(processDefinitionMap.containsKey("activitiAdhoc")); assertTrue(processDefinitionMap.containsKey("activitiAdhoc"));
assertEquals(1, processDefinitionMap.size()); 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 @Test
@@ -182,6 +197,9 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
{ {
RequestContext requestContext = initApiClientWithTestUser(); RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext); String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext);
org.activiti.engine.repository.ProcessDefinition activitiDefinition = activitiProcessEngine.getRepositoryService() org.activiti.engine.repository.ProcessDefinition activitiDefinition = activitiProcessEngine.getRepositoryService()
.createProcessDefinitionQuery() .createProcessDefinitionQuery()
@@ -204,6 +222,15 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDefinition.getVersion(), adhocDefinition.getVersion()); assertEquals(activitiDefinition.getVersion(), adhocDefinition.getVersion());
assertEquals(((ProcessDefinitionEntity) activitiDefinition).isGraphicalNotationDefined(), adhocDefinition.isGraphicNotationDefined()); assertEquals(((ProcessDefinitionEntity) activitiDefinition).isGraphicalNotationDefined(), adhocDefinition.isGraphicNotationDefined());
assertEquals("wf:submitAdhocTask", adhocDefinition.getStartFormResourceKey()); 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 @Test
@@ -227,6 +254,10 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
public void testGetProcessDefinitionStartModel() throws Exception public void testGetProcessDefinitionStartModel() throws Exception
{ {
RequestContext requestContext = initApiClientWithTestUser(); RequestContext requestContext = initApiClientWithTestUser();
String tenantAdmin = AuthenticationUtil.getAdminUserName() + "@" + requestContext.getNetworkId();
RequestContext adminContext = new RequestContext(requestContext.getNetworkId(), tenantAdmin);
ProcessDefinitionsClient processDefinitionsClient = publicApiClient.processDefinitionsClient(); ProcessDefinitionsClient processDefinitionsClient = publicApiClient.processDefinitionsClient();
String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext); String adhocKey = createProcessDefinitionKey("activitiAdhoc", requestContext);
@@ -322,6 +353,43 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(allowedValues.contains("On Hold")); assertTrue(allowedValues.contains("On Hold"));
assertTrue(allowedValues.contains("Cancelled")); assertTrue(allowedValues.contains("Cancelled"));
assertTrue(allowedValues.contains("Completed")); 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 @Test

View File

@@ -37,6 +37,7 @@ import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork; import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.workflow.activiti.ActivitiScriptNode; import org.alfresco.repo.workflow.activiti.ActivitiScriptNode;
import org.alfresco.rest.api.tests.RepoService.TestNetwork; 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.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiException; import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext; 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 @Test
public void testCreateProcessInstanceForPooledReview() throws Exception public void testCreateProcessInstanceForPooledReview() throws Exception
{ {
@@ -225,6 +289,7 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final ProcessInfo processInfo = startReviewPooledProcess(requestContext); final ProcessInfo processInfo = startReviewPooledProcess(requestContext);
assertNotNull(processInfo); assertNotNull(processInfo);
assertNotNull(processInfo.getId()); assertNotNull(processInfo.getId());
cleanupProcessInstance(processInfo.getId());
} }
@Test @Test
@@ -234,11 +299,12 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final ProcessInfo processInfo = startParallelReviewProcess(requestContext); final ProcessInfo processInfo = startParallelReviewProcess(requestContext);
assertNotNull(processInfo); assertNotNull(processInfo);
assertNotNull(processInfo.getId()); assertNotNull(processInfo.getId());
cleanupProcessInstance(processInfo.getId());
} }
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testCreateProcessInstanceFormOtherNetwork() throws Exception public void testCreateProcessInstanceFromOtherNetwork() throws Exception
{ {
final RequestContext requestContext = initApiClientWithTestUser(); final RequestContext requestContext = initApiClientWithTestUser();
@@ -432,10 +498,13 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
initApiClientWithTestUser(); initApiClientWithTestUser();
ProcessesClient processesClient = publicApiClient.processesClient(); ProcessesClient processesClient = publicApiClient.processesClient();
try { try
{
processesClient.findProcessById("unexisting"); processesClient.findProcessById("unexisting");
fail("Exception expected"); fail("Exception expected");
} catch(PublicApiException expected) { }
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode()); assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: unexisting was not found", expected.getHttpResponse()); 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 @Test
public void testGetProcessItems() throws Exception public void testGetProcessItems() throws Exception
{ {
@@ -974,6 +1062,16 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
assertTrue(doc2Found); assertTrue(doc2Found);
cleanupProcessInstance(processRest.getId()); cleanupProcessInstance(processRest.getId());
try
{
processesClient.findProcessItems("fakeid");
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(404, e.getHttpResponse().getStatusCode());
}
} }
@Test @Test
@@ -987,7 +1085,6 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
final String newProcessInstanceId = processRest.getId(); final String newProcessInstanceId = processRest.getId();
ProcessesClient processesClient = publicApiClient.processesClient(); ProcessesClient processesClient = publicApiClient.processesClient();
System.out.println("node ref " + docNodeRefs[0].toString());
JSONObject itemJSON = processesClient.findProcessItem(newProcessInstanceId, docNodeRefs[0].getId()); JSONObject itemJSON = processesClient.findProcessItem(newProcessInstanceId, docNodeRefs[0].getId());
assertNotNull(itemJSON); 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 @Test
public void testGetProcessVariables() throws Exception public void testGetProcessVariables() throws Exception
{ {
@@ -1458,16 +1629,20 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
{ {
initApiClientWithTestUser(); initApiClientWithTestUser();
try { try
{
publicApiClient.processesClient().deleteVariable("unexisting", "deleteMe"); publicApiClient.processesClient().deleteVariable("unexisting", "deleteMe");
fail("Exception expected"); fail("Exception expected");
} catch(PublicApiException expected) { }
catch(PublicApiException expected)
{
assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode()); assertEquals(HttpStatus.NOT_FOUND.value(), expected.getHttpResponse().getStatusCode());
assertErrorSummary("The entity with id: unexisting was not found", expected.getHttpResponse()); 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(); final Task task = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(instanceId).singleResult();
assertEquals(requestContext.getRunAsUser(), task.getAssignee()); 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.RequestContext;
import org.alfresco.rest.api.tests.client.data.MemberOfSite; import org.alfresco.rest.api.tests.client.data.MemberOfSite;
import org.alfresco.rest.workflow.api.model.ProcessInfo; 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.rest.workflow.api.tests.WorkflowApiClient.TasksClient;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ISO8601DateFormat; import org.alfresco.util.ISO8601DateFormat;
@@ -968,6 +967,8 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
String businessKey = UUID.randomUUID().toString(); String businessKey = UUID.randomUUID().toString();
ProcessInstance processInstance = startAdhocProcess(requestContext.getRunAsUser(), requestContext.getNetworkId(), businessKey); ProcessInstance processInstance = startAdhocProcess(requestContext.getRunAsUser(), requestContext.getNetworkId(), businessKey);
try
{
// Complete the adhoc task // Complete the adhoc task
final Task completedTask = activitiProcessEngine.getTaskService().createTaskQuery() final Task completedTask = activitiProcessEngine.getTaskService().createTaskQuery()
.processInstanceId(processInstance.getId()).singleResult(); .processInstanceId(processInstance.getId()).singleResult();
@@ -1294,6 +1295,11 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
params.put("where", "(variables/numberVar < 'd:int 10')"); params.put("where", "(variables/numberVar < 'd:int 10')");
assertEquals(0, getResultSizeForTaskQuery(params, tasksClient)); assertEquals(0, getResultSizeForTaskQuery(params, tasksClient));
} }
finally
{
cleanupProcessInstance(processInstance);
}
}
@Test @Test
public void testGetTasksWithPaging() throws Exception public void testGetTasksWithPaging() throws Exception
@@ -2463,20 +2469,26 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
{ {
final RequestContext requestContext = initApiClientWithTestUser(); 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 // Create test-document and add to package
NodeRef[] docNodeRefs = createTestDocuments(requestContext); NodeRef[] docNodeRefs = createTestDocuments(requestContext);
ProcessInfo processInfo = startAdhocProcess(requestContext, docNodeRefs); ProcessInfo processInfo = startAdhocProcess(requestContext, docNodeRefs);
ProcessInstance processInstance = activitiProcessEngine.getRuntimeService().createProcessInstanceQuery() Task task = activitiProcessEngine.getTaskService().createTaskQuery()
.processInstanceId(processInfo.getId()).singleResult(); .processInstanceId(processInfo.getId()).singleResult();
assertNotNull(processInstance); assertNotNull(task);
activitiProcessEngine.getTaskService().setAssignee(task.getId(), null);
try try
{ {
final String newProcessInstanceId = processInstance.getId(); TasksClient tasksClient = publicApiClient.tasksClient();
ProcessesClient processesClient = publicApiClient.processesClient(); JSONObject itemsJSON = tasksClient.findTaskItems(task.getId());
JSONObject itemsJSON = processesClient.findProcessItems(newProcessInstanceId);
assertNotNull(itemsJSON); assertNotNull(itemsJSON);
JSONArray entriesJSON = (JSONArray) itemsJSON.get("entries"); JSONArray entriesJSON = (JSONArray) itemsJSON.get("entries");
assertNotNull(entriesJSON); assertNotNull(entriesJSON);
@@ -2515,10 +2527,398 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
} }
assertTrue(doc1Found); assertTrue(doc1Found);
assertTrue(doc2Found); 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 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"); 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; 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 public JSONObject findProcessItems(String processInstanceId) throws PublicApiException
{ {
HttpResponse response = getAll("processes", processInstanceId, "items", null, null, HttpResponse response = getAll("processes", processInstanceId, "items", null, null,
@@ -283,6 +289,34 @@ public class WorkflowApiClient extends PublicApiClient
JSONObject list = (JSONObject) response.getJsonResponse().get("list"); JSONObject list = (JSONObject) response.getJsonResponse().get("list");
return 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) { public static Date parseDate(JSONObject entry, String fieldName) {