SHA-1598: Added support to Get Task Instances API to filter result, based on the given property.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@130404 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jamal Kaabi-Mofrad
2016-09-07 13:06:32 +00:00
parent 59eed12c13
commit f46962577f
3 changed files with 190 additions and 67 deletions

View File

@@ -4,7 +4,7 @@
Lists all Workflow Task Instances associated with an authority and of a given State.
The list of returned tasks also includes pooled tasks which the specified authority is eligible to claim.
</description>
<url>/api/task-instances?authority={authority?}&amp;state={state?}&amp;priority={priority?}&amp;pooledTasks={pooledTasks?}&amp;dueBefore={dueBefore?}&amp;dueAfter={dueAfter?}&amp;properties={properties?}&amp;maxItems={maxItems?}&amp;skipCount={skipCount?}&amp;exclude={exclude?}</url>
<url>/api/task-instances?authority={authority?}&amp;state={state?}&amp;priority={priority?}&amp;pooledTasks={pooledTasks?}&amp;dueBefore={dueBefore?}&amp;dueAfter={dueAfter?}&amp;properties={properties?}&amp;maxItems={maxItems?}&amp;skipCount={skipCount?}&amp;exclude={exclude?}&amp;property={propQName/propValue?}</url>
<url>/api/workflow-instances/{workflow_instance_id}/task-instances?authority={authority?}&amp;state={state?}&amp;priority={priority?}&amp;dueBefore={isoDate?}&amp;dueAfter={isoDate?}&amp;properties={prop1, prop2, prop3...?}&amp;maxItems={maxItems?}&amp;skipCount={skipCount?}&amp;exclude={exclude?}</url>
<format default="json"/>
<authentication>user</authentication>
@@ -55,6 +55,10 @@
<shortname>workflow_instance_id</shortname>
<description>Restricts the returned tasks to those that belong to the given workflow process instance id.</description>
</arg>
<arg>
<shortname>property</shortname>
<description>Restricts the returned tasks to only those that match the given property. The property name should be a valid QName format followed by '/' then the property value. E.g. bpm:description/myDescription</description>
</arg>
</args>
<responses>
<response>

View File

@@ -25,6 +25,7 @@
*/
package org.alfresco.repo.web.scripts.workflow;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -41,6 +42,8 @@ import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery.OrderBy;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ModelUtil;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
@@ -63,6 +66,7 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
public static final String PARAM_DUE_AFTER = "dueAfter";
public static final String PARAM_PROPERTIES = "properties";
public static final String PARAM_POOLED_TASKS = "pooledTasks";
public static final String PARAM_PROPERTY = "property";
public static final String VAR_WORKFLOW_INSTANCE_ID = "workflow_instance_id";
private WorkflowTaskDueAscComparator taskComparator = new WorkflowTaskDueAscComparator();
@@ -96,6 +100,7 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
// get filter param values
filters.put(PARAM_PRIORITY, req.getParameter(PARAM_PRIORITY));
filters.put(PARAM_PROPERTY, req.getParameter(PARAM_PROPERTY));
processDateFilter(req, PARAM_DUE_BEFORE, filters);
processDateFilter(req, PARAM_DUE_AFTER, filters);
@@ -179,10 +184,8 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
ArrayList<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
// Filter results
WorkflowTask task = null;
for(int i=0; i<allTasks.size(); i++)
for (WorkflowTask task : allTasks)
{
task = allTasks.get(i);
if (matches(task, filters))
{
// Total-count needs to be based on matching tasks only, so we can't just use allTasks.size() for this
@@ -341,6 +344,29 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
break;
}
}
else if(key.equals(PARAM_PROPERTY))
{
String[] propertyValuePair = filterValue.toString().split("/");
if (propertyValuePair.length != 2)
{
break;
}
QName propertyQName;
try
{
propertyQName = QName.createQName(propertyValuePair[0], namespaceService);
}
catch (NamespaceException ne)
{
break;
}
Serializable value = task.getProperties().get(propertyQName);
if (value != null && !value.equals(propertyValuePair[1]))
{
result = false;
break;
}
}
}
}

View File

@@ -306,6 +306,89 @@ public abstract class AbstractWorkflowRestApiTest extends BaseWebScriptTest
assertEquals(0, resultArray.length());
}
public void testTaskInstancesGetWithFiltering() throws Exception
{
// Check USER2 starts with no tasks.
personManager.setUser(USER2);
Response response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2)), 200);
getJsonArray(response, 0);
// Start workflow as USER1 and assign the task to GROUP.
personManager.setUser(USER1);
WorkflowDefinition wfDefinition = workflowService.getDefinitionByName(getReviewPooledWorkflowDefinitionName());
Map<QName, Serializable> params = new HashMap<>(3);
params.put(WorkflowModel.ASSOC_GROUP_ASSIGNEE, groupManager.get(GROUP));
params.put(WorkflowModel.ASSOC_PACKAGE, packageRef);
params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "descTest1");
WorkflowPath wfPath = workflowService.startWorkflow(wfDefinition.getId(), params);
String workflowId = wfPath.getInstance().getId();
workflows.add(workflowId);
WorkflowTask startTask = workflowService.getStartTask(workflowId);
workflowService.endTask(startTask.getId(), null);
// Start another workflow as USER1 and assign the task to GROUP.
wfDefinition = workflowService.getDefinitionByName(getReviewPooledWorkflowDefinitionName());
params.put(WorkflowModel.ASSOC_GROUP_ASSIGNEE, groupManager.get(GROUP));
params.put(WorkflowModel.ASSOC_PACKAGE, workflowService.createPackage(null));
params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "descTest2");
wfPath = workflowService.startWorkflow(wfDefinition.getId(), params);
workflowId = wfPath.getInstance().getId();
workflows.add(workflowId);
startTask = workflowService.getStartTask(workflowId);
workflowService.endTask(startTask.getId(), null);
// Check USER2's tasks without filtering. It should return two tasks as USER2 is a member of the GROUP
personManager.setUser(USER2);
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2)), 200);
getJsonArray(response, 2);
//Check USER2's tasks With filtering where property bpm:description should match "descTest1"
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=bpm:description/descTest1"), 200);
JSONArray results = getJsonArray(response, 1);
JSONObject result = results.getJSONObject(0);
assertNotNull(result);
JSONObject properties = result.getJSONObject("properties");
assertNotNull(properties);
assertEquals("descTest1", properties.getString("bpm_description"));
//Check USER2's tasks With filtering where property bpm:description should match "descTest2"
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=bpm:description/descTest2"), 200);
results = getJsonArray(response, 1);
result = results.getJSONObject(0);
assertNotNull(result);
properties = result.getJSONObject("properties");
assertNotNull(properties);
assertEquals("descTest2", properties.getString("bpm_description"));
/*
* -ve tests
*/
// Mismatched property value - There is no task with the description "somePropValue"
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=bpm:description/somePropValue"), 200);
getJsonArray(response, 0);
//Unregistered namespace prefix (ignores "property" parameter)
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=unknownPrefix:description/test"), 200);
getJsonArray(response, 2);
// Nonexistent property (ignores "property" parameter)
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=bpm:nonexistentProp/test"), 200);
getJsonArray(response, 2);
// Not well-formed parameter
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2) + "&property=bpm:description/"), 200);
getJsonArray(response, 2);
// Check USER3's tasks without filtering. It should return 0 task as USER3 is not a member of the GROUP
personManager.setUser(USER3);
response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER3)), 200);
getJsonArray(response, 0);
}
public void testWorkflowPermissions() throws Exception
{
// Start workflow as USER1 and assign task to USER1.
@@ -1786,6 +1869,16 @@ public abstract class AbstractWorkflowRestApiTest extends BaseWebScriptTest
assertEquals(skipCount, paging.getInt("skipCount"));
}
private JSONArray getJsonArray(Response response, int expectedLength) throws Exception
{
String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr);
JSONArray results = json.getJSONArray("data");
assertNotNull(results);
assertEquals(expectedLength, results.length());
return results;
}
protected abstract String getEngine();
}