ALF-20190, ALF-20178 fixes for workflow rest api

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@56272 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tijs Rademakers
2013-10-02 17:42:33 +00:00
parent 3e148f0b29
commit a402cc75ed
12 changed files with 826 additions and 156 deletions

View File

@@ -882,6 +882,7 @@
<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="personService" ref="PersonService" />
</bean>
<bean id="Tasks" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -57,6 +57,7 @@ public class DeploymentsImpl extends WorkflowRestImpl implements Deployments
query.orderByDeploymenTime().desc();
List<org.activiti.engine.repository.Deployment> deployments = query.listPage(paging.getSkipCount(), paging.getMaxItems());
int totalCount = (int) query.count();
List<Deployment> page = new ArrayList<Deployment>(deployments.size());
for (org.activiti.engine.repository.Deployment deployment: deployments)
@@ -64,7 +65,7 @@ public class DeploymentsImpl extends WorkflowRestImpl implements Deployments
page.add(new Deployment(deployment));
}
return CollectionWithPagingInfo.asPaged(paging, page, false, page.size());
return CollectionWithPagingInfo.asPaged(paging, page, page.size() != totalCount, totalCount);
}
@Override

View File

@@ -224,6 +224,7 @@ public class ProcessDefinitionsImpl extends WorkflowRestImpl implements ProcessD
List<org.activiti.engine.repository.ProcessDefinition> processDefinitions =
query.listPage(parameters.getPaging().getSkipCount(), parameters.getPaging().getMaxItems());
int totalCount = (int) query.count();
List<ProcessDefinition> page = new ArrayList<ProcessDefinition>(processDefinitions.size());
for (org.activiti.engine.repository.ProcessDefinition processDefinition: processDefinitions)
@@ -231,7 +232,7 @@ public class ProcessDefinitionsImpl extends WorkflowRestImpl implements ProcessD
page.add(createProcessDefinitionRest((ProcessDefinitionEntity) processDefinition));
}
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, false, page.size());
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, page.size() != totalCount, totalCount);
}
@Override

View File

@@ -607,74 +607,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
if (taskAssociations.containsKey(propNameMap.get(variableName)))
{
AssociationDefinition associationDef = taskAssociations.get(propNameMap.get(variableName));
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> personList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef personRef = getPersonNodeRef(value.toString());
if (personRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
}
personList.add(personRef);
}
variableValue = personList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef personRef = getPersonNodeRef(variableValue.toString());
if (personRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
}
variableValue = personRef;
}
}
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> authorityList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
}
authorityList.add(authorityRef);
}
variableValue = authorityList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
}
variableValue = authorityRef;
}
}
variableValue = convertAssociationDefinitionValue(associationDef, variableName, variableValue);
}
else if (taskProperties.containsKey(propNameMap.get(variableName)))
{
@@ -921,7 +854,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new EntityNotFoundException(processId);
}
return updateVariableInProcess(processId, variable);
return updateVariableInProcess(processId, processInstance.getProcessDefinitionId(), variable);
}
@Override
@@ -944,21 +877,45 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
{
for (Variable variable : variables)
{
updatedVariables.add(updateVariableInProcess(processId, variable));
updatedVariables.add(updateVariableInProcess(processId, processInstance.getProcessDefinitionId(), variable));
}
}
return updatedVariables;
}
protected Variable updateVariableInProcess(String processId,Variable variable)
protected Variable updateVariableInProcess(String processId, String processDefinitionId, Variable variable)
{
if (variable.getName() == null)
{
throw new InvalidArgumentException("Variable name is required.");
}
// Get start-task definition for explicit typing of variables submitted at the start
String formKey = null;
StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(processDefinitionId);
if (startFormData != null)
{
formKey = startFormData.getFormKey();
}
DataTypeDefinition dataTypeDefinition = null;
if(variable.getType() != null)
TypeDefinition startTaskTypeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, true);
TypeDefinitionContext context = new TypeDefinitionContext(startTaskTypeDefinition, getQNameConverter());
if (context.getPropertyDefinition(variable.getName()) != null)
{
dataTypeDefinition = context.getPropertyDefinition(variable.getName()).getDataType();
if (variable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(variable.getType()) == false) {
throw new InvalidArgumentException("type of variable " + variable.getName() + " should be " +
dataTypeDefinition.getName().toPrefixString(namespaceService));
}
}
else if (context.getAssociationDefinition(variable.getName()) != null)
{
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
}
if (dataTypeDefinition == null && variable.getType() != null)
{
try
{
@@ -970,13 +927,13 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
throw new InvalidArgumentException("Unsupported type of variable: '" + variable.getType() +"'.");
}
}
else
else if (dataTypeDefinition == null)
{
// Fallback to raw value when no type has been passed and not present in model
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(variable.getValue()));
}
if(dataTypeDefinition == null)
if (dataTypeDefinition == null)
{
throw new InvalidArgumentException("Unsupported type of variable: '" + variable.getType() +"'.");
}
@@ -989,7 +946,15 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
}
else
{
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, variable.getValue());
if (context.getAssociationDefinition(variable.getName()) != null)
{
actualValue = convertAssociationDefinitionValue(context.getAssociationDefinition(variable.getName()),
variable.getName(), variable.getValue());
}
else
{
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, variable.getValue());
}
}
variable.setValue(actualValue);
@@ -1066,6 +1031,79 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
}
}
protected Object convertAssociationDefinitionValue(AssociationDefinition associationDef, String variableName, Object variableValue)
{
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> personList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef personRef = getPersonNodeRef(value.toString());
if (personRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
}
personList.add(personRef);
}
variableValue = personList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef personRef = getPersonNodeRef(variableValue.toString());
if (personRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
}
variableValue = personRef;
}
}
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> authorityList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
}
authorityList.add(authorityRef);
}
variableValue = authorityList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
}
variableValue = authorityRef;
}
}
return variableValue;
}
protected String getProcessDefinitionKey(String paramProcessDefinitionKey)
{
String processDefinitionKey = null;

View File

@@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -94,13 +93,13 @@ public class RestVariableHelper
List<TaskVariable> result = new ArrayList<TaskVariable>();
if (localVariables != null && localVariables.size() > 0)
{
TypeDefinitionContext context = new TypeDefinitionContext(taskTypeDefinition);
TypeDefinitionContext context = new TypeDefinitionContext(taskTypeDefinition, getQNameConverter());
addTaskVariables(result, localVariables, context, VariableScope.LOCAL);
}
if (globalVariables != null && globalVariables.size() > 0)
{
TypeDefinitionContext context = new TypeDefinitionContext(startFormTypeDefinition);
TypeDefinitionContext context = new TypeDefinitionContext(startFormTypeDefinition, getQNameConverter());
addTaskVariables(result, globalVariables, context, VariableScope.GLOBAL);
}
@@ -115,7 +114,7 @@ public class RestVariableHelper
public List<Variable> getVariables(Map<String, Object> variables, TypeDefinition typeDefinition)
{
List<Variable> result = new ArrayList<Variable>();
TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition);
TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition, getQNameConverter());
Variable variable = null;
for(Entry<String, Object> entry : variables.entrySet())
@@ -372,40 +371,4 @@ public class RestVariableHelper
QName type = extractTypeFromValue(value);
return type.toPrefixString(namespaceService);
}
/**
* Helper contxt class used when checking variable types based on {@link TypeDefinition}.
*
* @author Frederik Heremans
*/
private class TypeDefinitionContext {
private Map<String, PropertyDefinition> propertyDefinitions;
private Map<String, AssociationDefinition> associationDefinitions;
public TypeDefinitionContext(TypeDefinition typeDefinition)
{
propertyDefinitions = new HashMap<String, PropertyDefinition>();
associationDefinitions = new HashMap<String, AssociationDefinition>();
for (Entry<QName, PropertyDefinition> entry : typeDefinition.getProperties().entrySet())
{
propertyDefinitions.put(getQNameConverter().mapQNameToName(entry.getKey()), entry.getValue());
}
for (Entry<QName, AssociationDefinition> entry : typeDefinition.getAssociations().entrySet())
{
associationDefinitions.put(getQNameConverter().mapQNameToName(entry.getKey()), entry.getValue());
}
}
public PropertyDefinition getPropertyDefinition(String rawVariableName)
{
return propertyDefinitions.get(rawVariableName);
}
public AssociationDefinition getAssociationDefinition(String rawVariableName)
{
return associationDefinitions.get(rawVariableName);
}
}
}

View File

@@ -36,6 +36,7 @@ import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
import org.activiti.engine.task.TaskQuery;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.i18n.MessageService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantUtil;
@@ -65,10 +66,11 @@ import org.alfresco.rest.workflow.api.model.TaskVariable;
import org.alfresco.rest.workflow.api.model.VariableScope;
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.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.InvalidQNameException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ISO8601DateFormat;
@@ -123,6 +125,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
private WorkflowObjectFactory workflowFactory;
private WorkflowQNameConverter qNameConverter;
private MessageService messageService;
private PersonService personService;
public void setRestVariableHelper(RestVariableHelper restVariableHelper)
{
@@ -134,6 +137,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
this.messageService = messageService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
@Override
public CollectionWithPagingInfo<Task> getTasks(Parameters parameters)
{
@@ -1054,9 +1062,63 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
{
throw new InvalidArgumentException("Variable scope is required and can only be 'local' or 'global'.");
}
DataTypeDefinition dataTypeDefinition = null;
if (taskVariable.getType() != null)
TypeDefinitionContext context = null;
if (taskVariable.getVariableScope() == VariableScope.GLOBAL)
{
// Get start-task definition for explicit typing of variables submitted at the start
String formKey = null;
StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(taskInstance.getProcessDefinitionId());
if (startFormData != null)
{
formKey = startFormData.getFormKey();
}
TypeDefinition startTaskTypeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, true);
context = new TypeDefinitionContext(startTaskTypeDefinition, getQNameConverter());
if (context.getPropertyDefinition(taskVariable.getName()) != null)
{
dataTypeDefinition = context.getPropertyDefinition(taskVariable.getName()).getDataType();
if (taskVariable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(taskVariable.getType()) == false) {
throw new InvalidArgumentException("type of variable " + taskVariable.getName() + " should be " +
dataTypeDefinition.getName().toPrefixString(namespaceService));
}
}
else if (context.getAssociationDefinition(taskVariable.getName()) != null)
{
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
}
}
else
{
// Revert to either the content-model type or the raw type provided by the request
try
{
String formKey = activitiProcessEngine.getFormService().getTaskFormKey(taskInstance.getProcessDefinitionId(), taskInstance.getTaskDefinitionKey());
TypeDefinition typeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, false);
context = new TypeDefinitionContext(typeDefinition, getQNameConverter());
if (context.getPropertyDefinition(taskVariable.getName()) != null)
{
dataTypeDefinition = context.getPropertyDefinition(taskVariable.getName()).getDataType();
if (taskVariable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(taskVariable.getType()) == false) {
throw new InvalidArgumentException("type of variable " + taskVariable.getName() + " should be " +
dataTypeDefinition.getName().toPrefixString(namespaceService));
}
}
else if (context.getAssociationDefinition(taskVariable.getName()) != null)
{
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
}
}
catch (InvalidQNameException ignore)
{
// In case the property is not part of the model, it's possible that the property-name is not a valid.
// This can be ignored safeley as it falls back to the raw type
}
}
if (dataTypeDefinition == null && taskVariable.getType() != null)
{
try
{
@@ -1067,41 +1129,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
{
throw new InvalidArgumentException("Unsupported type of variable: '" + taskVariable.getType() +"'.");
}
}
else
}
else if (dataTypeDefinition == null)
{
// Revert to either the content-model type or the raw type provided by the request
try
{
String formKey = activitiProcessEngine.getFormService().getTaskFormKey(taskInstance.getProcessDefinitionId(), taskInstance.getTaskDefinitionKey());
TypeDefinition typeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, false);
QName propQName = WorkflowQNameConverter.convertNameToQName(taskVariable.getName(), namespaceService);
PropertyDefinition propDef = typeDefinition.getProperties().get(propQName);
if (propDef != null)
{
dataTypeDefinition = propDef.getDataType();
}
else
{
AssociationDefinition assocDef = typeDefinition.getAssociations().get(propQName);
if(assocDef != null)
{
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
}
}
}
catch (InvalidQNameException ignore)
{
// In case the property is not part of the model, it's possible that the property-name is not a valid.
// This can be ignored safeley as it falls back to the raw type
}
if (dataTypeDefinition == null)
{
// Final fallback to raw value when no type has been passed and not present in model
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue()));
}
// Final fallback to raw value when no type has been passed and not present in model
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue()));
}
if (dataTypeDefinition == null)
@@ -1117,7 +1149,15 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
}
else
{
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, taskVariable.getValue());
if (context != null && context.getAssociationDefinition(taskVariable.getName()) != null)
{
actualValue = convertAssociationDefinitionValue(context.getAssociationDefinition(taskVariable.getName()),
taskVariable.getName(), taskVariable.getValue());
}
else
{
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, taskVariable.getValue());
}
}
taskVariable.setValue(actualValue);
@@ -1556,6 +1596,92 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
}
}
protected Object convertAssociationDefinitionValue(AssociationDefinition associationDef, String variableName, Object variableValue)
{
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> personList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef personRef = getPersonNodeRef(value.toString());
if (personRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
}
personList.add(personRef);
}
variableValue = personList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef personRef = getPersonNodeRef(variableValue.toString());
if (personRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
}
variableValue = personRef;
}
}
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
{
if (associationDef.isTargetMany())
{
if (variableValue instanceof List<?>)
{
List<NodeRef> authorityList = new ArrayList<NodeRef>();
List<?> values = (List<?>) variableValue;
for (Object value : values)
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
}
authorityList.add(authorityRef);
}
variableValue = authorityList;
}
else
{
throw new InvalidArgumentException(variableName + " should have an array value");
}
}
else
{
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
if (authorityRef == null)
{
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
}
variableValue = authorityRef;
}
}
return variableValue;
}
protected NodeRef getPersonNodeRef(String name)
{
NodeRef authority = null;
if (name != null)
{
if (personService.personExists(name))
{
authority = personService.getPerson(name);
}
}
return authority;
}
protected WorkflowQNameConverter getQNameConverter()
{
if (qNameConverter == null)

View File

@@ -0,0 +1,48 @@
package org.alfresco.rest.workflow.api.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.alfresco.repo.workflow.WorkflowQNameConverter;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.namespace.QName;
/**
* Helper contxt class used when checking variable types based on {@link TypeDefinition}.
*
* @author Frederik Heremans
*/
public class TypeDefinitionContext {
private Map<String, PropertyDefinition> propertyDefinitions;
private Map<String, AssociationDefinition> associationDefinitions;
public TypeDefinitionContext(TypeDefinition typeDefinition, WorkflowQNameConverter qNameConverter)
{
propertyDefinitions = new HashMap<String, PropertyDefinition>();
associationDefinitions = new HashMap<String, AssociationDefinition>();
for (Entry<QName, PropertyDefinition> entry : typeDefinition.getProperties().entrySet())
{
propertyDefinitions.put(qNameConverter.mapQNameToName(entry.getKey()), entry.getValue());
}
for (Entry<QName, AssociationDefinition> entry : typeDefinition.getAssociations().entrySet())
{
associationDefinitions.put(qNameConverter.mapQNameToName(entry.getKey()), entry.getValue());
}
}
public PropertyDefinition getPropertyDefinition(String rawVariableName)
{
return propertyDefinitions.get(rawVariableName);
}
public AssociationDefinition getAssociationDefinition(String rawVariableName)
{
return associationDefinitions.get(rawVariableName);
}
}

View File

@@ -38,6 +38,7 @@ import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext;
import org.alfresco.rest.workflow.api.model.Deployment;
import org.alfresco.rest.workflow.api.tests.WorkflowApiClient.DeploymentsClient;
import org.json.simple.JSONObject;
import org.junit.Test;
import org.springframework.http.HttpStatus;
@@ -120,6 +121,58 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals(activitiDeployment.getCategory(), adhocDeployment.getCategory());
assertEquals(activitiDeployment.getName(), adhocDeployment.getName());
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
Map<String, String> params = new HashMap<String, String>();
params.put("maxItems", "2");
JSONObject deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
assertNotNull(deploymentsListObject);
JSONObject paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
assertEquals(2l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
assertNotNull(deploymentsListObject);
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
assertEquals(5l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(false, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "2");
params.put("maxItems", "2");
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
assertNotNull(deploymentsListObject);
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
assertEquals(2l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(2l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "2");
params.put("maxItems", "5");
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
assertNotNull(deploymentsListObject);
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
assertEquals(3l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(2l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "0");
params.put("maxItems", "7");
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
assertNotNull(deploymentsListObject);
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
assertEquals(5l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(false, paginationJSON.get("hasMoreItems"));
}
@Test

View File

@@ -88,6 +88,58 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals("wf:submitAdhocTask", adhocDefinitionRest.getStartFormResourceKey());
assertEquals("New Task", adhocDefinitionRest.getTitle());
assertEquals("Assign a new task to yourself or a colleague", adhocDefinitionRest.getDescription());
Map<String, String> params = new HashMap<String, String>();
params.put("maxItems", "2");
JSONObject definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
assertNotNull(definitionListObject);
JSONObject paginationJSON = (JSONObject) definitionListObject.get("pagination");
assertEquals(2l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
assertNotNull(definitionListObject);
paginationJSON = (JSONObject) definitionListObject.get("pagination");
assertEquals(5l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(false, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "2");
params.put("maxItems", "2");
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
assertNotNull(definitionListObject);
paginationJSON = (JSONObject) definitionListObject.get("pagination");
assertEquals(2l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(2l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "2");
params.put("maxItems", "5");
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
assertNotNull(definitionListObject);
paginationJSON = (JSONObject) definitionListObject.get("pagination");
assertEquals(3l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(2l, paginationJSON.get("skipCount"));
assertEquals(true, paginationJSON.get("hasMoreItems"));
params = new HashMap<String, String>();
params.put("skipCount", "0");
params.put("maxItems", "7");
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
assertNotNull(definitionListObject);
paginationJSON = (JSONObject) definitionListObject.get("pagination");
assertEquals(5l, paginationJSON.get("count"));
assertEquals(5l, paginationJSON.get("totalItems"));
assertEquals(0l, paginationJSON.get("skipCount"));
assertEquals(false, paginationJSON.get("hasMoreItems"));
}
@Test

View File

@@ -1749,6 +1749,25 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
assertEquals("d:long", result.get("type"));
assertEquals(4567L, activitiProcessEngine.getRuntimeService().getVariable(processId, "newVariable"));
JSONObject processvariables = publicApiClient.processesClient().getProcessvariables(processId);
assertNotNull(processvariables);
JSONObject newVariableEntry = null;
JSONArray entries = (JSONArray) processvariables.get("entries");
assertNotNull(entries);
for(int i=0; i<entries.size(); i++)
{
JSONObject entry = (JSONObject) entries.get(i);
assertNotNull(entry);
entry = (JSONObject) entry.get("entry");
assertNotNull(entry);
if ("newVariable".equals((String) entry.get("name"))) {
newVariableEntry = entry;
}
}
assertNotNull(newVariableEntry);
assertEquals(4567L, newVariableEntry.get("value"));
// Update an existing variable, creates a new one using no explicit typing
variableJson = new JSONObject();
variableJson.put("name", "stringVariable");
@@ -1856,6 +1875,187 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
}
}
@SuppressWarnings("unchecked")
@Test
public void testUpdateProcessVariableWithWrongType() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
ProcessInfo processRest = startParallelReviewProcess(requestContext);
try
{
assertNotNull(processRest);
String processId = processRest.getId();
// Update an existing variable with wrong type
JSONObject variableJson = new JSONObject();
variableJson.put("name", "wf_requiredApprovePercent");
variableJson.put("value", 55.99);
variableJson.put("type", "d:double");
try
{
publicApiClient.processesClient().updateVariable(processId, "wf_requiredApprovePercent", variableJson);
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
}
variableJson = new JSONObject();
variableJson.put("name", "wf_requiredApprovePercent");
variableJson.put("value", 55.99);
variableJson.put("type", "d:int");
JSONObject resultEntry = publicApiClient.processesClient().updateVariable(processId, "wf_requiredApprovePercent", variableJson);
assertNotNull(resultEntry);
JSONObject result = (JSONObject) resultEntry.get("entry");
assertEquals("wf_requiredApprovePercent", result.get("name"));
assertEquals(55l, result.get("value"));
assertEquals("d:int", result.get("type"));
assertEquals(55, activitiProcessEngine.getRuntimeService().getVariable(processId, "wf_requiredApprovePercent"));
JSONObject processvariables = publicApiClient.processesClient().getProcessvariables(processId);
assertNotNull(processvariables);
// Add process variables to map for easy lookup
Map<String, JSONObject> variablesByName = new HashMap<String, JSONObject>();
JSONObject entry = null;
JSONArray entries = (JSONArray) processvariables.get("entries");
assertNotNull(entries);
for(int i=0; i<entries.size(); i++)
{
entry = (JSONObject) entries.get(i);
assertNotNull(entry);
entry = (JSONObject) entry.get("entry");
assertNotNull(entry);
variablesByName.put((String) entry.get("name"), entry);
}
JSONObject approvePercentObject = variablesByName.get("wf_requiredApprovePercent");
assertNotNull(approvePercentObject);
assertEquals(55l, approvePercentObject.get("value"));
assertEquals("d:int", approvePercentObject.get("type"));
// set a new variable
variableJson = new JSONObject();
variableJson.put("name", "testVariable");
variableJson.put("value", "text");
variableJson.put("type", "d:text");
resultEntry = publicApiClient.processesClient().updateVariable(processId, "testVariable", variableJson);
assertNotNull(resultEntry);
result = (JSONObject) resultEntry.get("entry");
assertEquals("testVariable", result.get("name"));
assertEquals("text", result.get("value"));
assertEquals("d:text", result.get("type"));
assertEquals("text", activitiProcessEngine.getRuntimeService().getVariable(processId, "testVariable"));
// change the variable value and type (should be working because no content model type)
variableJson = new JSONObject();
variableJson.put("name", "testVariable");
variableJson.put("value", 123);
variableJson.put("type", "d:int");
resultEntry = publicApiClient.processesClient().updateVariable(processId, "testVariable", variableJson);
assertNotNull(resultEntry);
result = (JSONObject) resultEntry.get("entry");
assertEquals("testVariable", result.get("name"));
assertEquals(123l, result.get("value"));
assertEquals("d:int", result.get("type"));
assertEquals(123, activitiProcessEngine.getRuntimeService().getVariable(processId, "testVariable"));
// change the variable value for a list of noderefs (bpm_assignees)
final JSONObject updateAssigneesJson = new JSONObject();
updateAssigneesJson.put("name", "bpm_assignees");
updateAssigneesJson.put("type", "d:noderef");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
JSONArray assigneeArray = new JSONArray();
assigneeArray.add(requestContext.getRunAsUser());
updateAssigneesJson.put("value", assigneeArray);
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
resultEntry = publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", updateAssigneesJson);
assertNotNull(resultEntry);
final JSONObject updateAssigneeResult = (JSONObject) resultEntry.get("entry");
assertEquals("bpm_assignees", updateAssigneeResult.get("name"));
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
JSONArray assigneeArray = (JSONArray) updateAssigneeResult.get("value");
assertNotNull(assigneeArray);
assertEquals(1, assigneeArray.size());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
assertEquals("d:noderef", updateAssigneeResult.get("type"));
// update the bpm_assignees with a single entry, should result in an error
final JSONObject updateAssigneeJson = new JSONObject();
updateAssigneeJson.put("name", "bpm_assignees");
updateAssigneeJson.put("type", "d:noderef");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
updateAssigneeJson.put("value", requestContext.getRunAsUser());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
try
{
publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", updateAssigneeJson);
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
}
// change the variable value with a non-existing person
variableJson = new JSONObject();
variableJson.put("name", "bpm_assignees");
JSONArray assigneeArray = new JSONArray();
assigneeArray.add("nonExistingPerson");
variableJson.put("value", assigneeArray);
variableJson.put("type", "d:noderef");
try
{
publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", variableJson);
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
}
}
finally
{
cleanupProcessInstance(processRest.getId());
}
}
@Test
public void testDeleteProcessVariable() throws Exception
{

View File

@@ -1106,7 +1106,7 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
JSONObject variableBody = new JSONObject();
variableBody.put("name", "bpm_workflowDueDate");
variableBody.put("value", formatDate(new Date()));
variableBody.put("type", "d:datetime");
variableBody.put("type", "d:date");
variableBody.put("scope", "global");
tasksClient.updateTaskVariable(task.getId(), "bpm_workflowDueDate", variableBody);
@@ -2397,6 +2397,179 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
}
}
@SuppressWarnings("unchecked")
@Test
public void testUpdateTaskVariableWithWrongType() throws Exception
{
final RequestContext requestContext = initApiClientWithTestUser();
ProcessInfo processRest = startParallelReviewProcess(requestContext);
try
{
List<Task> tasks = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processRest.getId()).list();
assertNotNull(tasks);
String taskId = tasks.get(0).getId();
// Update an existing variable with wrong type
JSONObject variableJson = new JSONObject();
variableJson.put("name", "wf_requiredApprovePercent");
variableJson.put("value", 55.99);
variableJson.put("type", "d:double");
variableJson.put("scope", "global");
try
{
publicApiClient.tasksClient().updateTaskVariable(taskId, "wf_requiredApprovePercent", variableJson);
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
}
variableJson = new JSONObject();
variableJson.put("name", "wf_requiredApprovePercent");
variableJson.put("value", 55.99);
variableJson.put("type", "d:int");
variableJson.put("scope", "global");
JSONObject resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "wf_requiredApprovePercent", variableJson);
assertNotNull(resultEntry);
JSONObject result = (JSONObject) resultEntry.get("entry");
assertEquals("wf_requiredApprovePercent", result.get("name"));
assertEquals(55l, result.get("value"));
assertEquals("d:int", result.get("type"));
assertEquals(55, activitiProcessEngine.getRuntimeService().getVariable(processRest.getId(), "wf_requiredApprovePercent"));
JSONObject taskVariables = publicApiClient.tasksClient().findTaskVariables(taskId);
assertNotNull(taskVariables);
JSONObject list = (JSONObject) taskVariables.get("list");
assertNotNull(list);
// Add process variables to map for easy lookup
Map<String, JSONObject> variablesByName = new HashMap<String, JSONObject>();
JSONObject entry = null;
JSONArray entries = (JSONArray) list.get("entries");
assertNotNull(entries);
for(int i=0; i<entries.size(); i++)
{
entry = (JSONObject) entries.get(i);
assertNotNull(entry);
entry = (JSONObject) entry.get("entry");
assertNotNull(entry);
variablesByName.put((String) entry.get("name"), entry);
}
JSONObject approvePercentObject = variablesByName.get("wf_requiredApprovePercent");
assertNotNull(approvePercentObject);
assertEquals(55l, approvePercentObject.get("value"));
assertEquals("d:int", approvePercentObject.get("type"));
// set a new variable
variableJson = new JSONObject();
variableJson.put("name", "testVariable");
variableJson.put("value", "text");
variableJson.put("type", "d:text");
variableJson.put("scope", "local");
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "testVariable", variableJson);
assertNotNull(resultEntry);
result = (JSONObject) resultEntry.get("entry");
assertEquals("testVariable", result.get("name"));
assertEquals("text", result.get("value"));
assertEquals("d:text", result.get("type"));
assertEquals("text", activitiProcessEngine.getTaskService().getVariable(taskId, "testVariable"));
// change the variable value and type (should be working because no content model type)
variableJson = new JSONObject();
variableJson.put("name", "testVariable");
variableJson.put("value", 123);
variableJson.put("type", "d:int");
variableJson.put("scope", "local");
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "testVariable", variableJson);
assertNotNull(resultEntry);
result = (JSONObject) resultEntry.get("entry");
assertEquals("testVariable", result.get("name"));
assertEquals(123l, result.get("value"));
assertEquals("d:int", result.get("type"));
assertEquals(123, activitiProcessEngine.getTaskService().getVariable(taskId, "testVariable"));
// change the variable value for a list of noderefs (bpm_assignees)
final JSONObject updateAssigneesJson = new JSONObject();
updateAssigneesJson.put("name", "bpm_assignees");
updateAssigneesJson.put("type", "d:noderef");
updateAssigneesJson.put("scope", "global");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
JSONArray assigneeArray = new JSONArray();
assigneeArray.add(requestContext.getRunAsUser());
updateAssigneesJson.put("value", assigneeArray);
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "bpm_assignees", updateAssigneesJson);
assertNotNull(resultEntry);
final JSONObject updateAssigneeResult = (JSONObject) resultEntry.get("entry");
assertEquals("bpm_assignees", updateAssigneeResult.get("name"));
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
JSONArray assigneeArray = (JSONArray) updateAssigneeResult.get("value");
assertNotNull(assigneeArray);
assertEquals(1, assigneeArray.size());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
assertEquals("d:noderef", updateAssigneeResult.get("type"));
// update the bpm_assignees with a single entry, should result in an error
final JSONObject updateAssigneeJson = new JSONObject();
updateAssigneeJson.put("name", "bpm_assignees");
updateAssigneeJson.put("type", "d:noderef");
updateAssigneeJson.put("scope", "global");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
updateAssigneeJson.put("value", requestContext.getRunAsUser());
return null;
}
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
try
{
publicApiClient.tasksClient().updateTaskVariable(taskId, "bpm_assignees", updateAssigneeJson);
fail("Exception expected");
}
catch (PublicApiException e)
{
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
}
}
finally
{
cleanupProcessInstance(processRest.getId());
}
}
@Test
@SuppressWarnings("unchecked")
public void testUpdateTaskVariablesAuthentication() throws Exception

View File

@@ -69,6 +69,13 @@ public class WorkflowApiClient extends PublicApiClient
HttpResponse response = getAll("deployments", null, null, null, params, "Failed to get deploymentsClient");
return DeploymentParser.INSTANCE.parseList(response.getJsonResponse());
}
public JSONObject getDeploymentsWithRawResponse(Map<String, String> params) throws PublicApiException
{
HttpResponse response = getAll("deployments", null, null, null, params, "Failed to get deploymentsClient");
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
return list;
}
public ListResponse<Deployment> getDeployments() throws PublicApiException
{
@@ -106,6 +113,13 @@ public class WorkflowApiClient extends PublicApiClient
HttpResponse response = getAll("process-definitions", null, null, null, params, "Failed to get process definitions");
return ProcessDefinitionParser.INSTANCE.parseList(response.getJsonResponse());
}
public JSONObject getProcessDefinitionsWithRawResponse(Map<String, String> params) throws PublicApiException
{
HttpResponse response = getAll("process-definitions", null, null, null, params, "Failed to get process definitions");
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
return list;
}
public ProcessDefinition findProcessDefinitionById(String processDefinitionId) throws PublicApiException
{