Merged BRANCHES/DEV/BELARUS/HEAD_2010_08_17 to HEAD:

21853: ALF-4304 : F101 All relevant REST APIs have filtering capabilities i.e. authority, state, priority and date range
               ALF-3902: F77 REST API to get all task instances

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21899 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2010-08-20 12:31:58 +00:00
parent 55bd4fc42e
commit 79c700b6fb
5 changed files with 413 additions and 216 deletions

View File

@@ -2,9 +2,9 @@
<shortname>List Workflow Tasks</shortname> <shortname>List Workflow Tasks</shortname>
<description> <description>
Lists all Workflow Task Instances associated with an authority and of a given State. 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. The list of returned tasks also includes pooled tasks which the specified authority is eligible to claim.
</description> </description>
<url>/api/task-instances?authority={authority?}&amp;state={state?}&amp;properties={properties?}&amp;detailed={detailed?}</url> <url>/api/task-instances?authority={authority?}&amp;state={state?}&amp;priority={priority?}&amp;dueBefore={dueBefore?}&amp;dueAfter={dueAfter?}&amp;properties={properties?}&amp;detailed={detailed?}</url>
<format default="json"/> <format default="json"/>
<authentication>user</authentication> <authentication>user</authentication>
<transaction allow="readonly">required</transaction> <transaction allow="readonly">required</transaction>

View File

@@ -1,8 +1,8 @@
<webscript> <webscript>
<shortname>Get Workflow Instance Collection</shortname> <shortname>Get Workflow Instance Collection</shortname>
<description>Retrieves all workflow instances, the returned list can be optionally filtered by the state of the workflow instance and by the authority that initiated the workflow instance.</description> <description>Retrieves all workflow instances, the returned list can be optionally filtered by the state of the workflow instance and by the authority that initiated the workflow instance.</description>
<url>/api/workflow-instances?state={state?}&amp;initiator={initiator?}&amp;priority={priority?}</url> <url>/api/workflow-instances?state={state?}&amp;initiator={initiator?}&amp;priority={priority?}&amp;dueBefore={dueBefore?}&amp;dueAfter={dueAfter?}&amp;startedBefore={startedBefore?}&amp;startedAfter={startedAfter?}&amp;completedBefore={completedBefore?}&amp;completedAfter={completedAfter?}</url>
<url>/api/workflow-definitions/{workflow_definition_id}/workflow-instances?state={state?}&amp;initiator={initiator?}&amp;date={date?}&amp;priority={priority?}</url> <url>/api/workflow-definitions/{workflow_definition_id}/workflow-instances?state={state?}&amp;initiator={initiator?}&amp;priority={priority?}&amp;dueBefore={dueBefore?}&amp;dueAfter={dueAfter?}&amp;startedBefore={startedBefore?}&amp;startedAfter={startedAfter?}&amp;completedBefore={completedBefore?}&amp;completedAfter={completedAfter?}</url>
<format default="json"/> <format default="json"/>
<authentication>user</authentication> <authentication>user</authentication>
<transaction allow="readonly">required</transaction> <transaction allow="readonly">required</transaction>

View File

@@ -18,17 +18,21 @@
*/ */
package org.alfresco.repo.web.scripts.workflow; package org.alfresco.repo.web.scripts.workflow;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.springframework.extensions.surf.util.ISO8601DateFormat;
import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptException;
@@ -41,38 +45,63 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
public class TaskInstancesGet extends AbstractWorkflowWebscript public class TaskInstancesGet extends AbstractWorkflowWebscript
{ {
public static final String PARAM_AUTHORITY = "authority"; public static final String PARAM_AUTHORITY = "authority";
public static final String PARAM_STATUS= "status"; public static final String PARAM_STATE = "state";
public static final String PARAM_PROPERTIES= "properties"; public static final String PARAM_PRIORITY = "priority";
public static final String PARAM_DETAILED= "detailed"; public static final String PARAM_DUE_BEFORE = "dueBefore";
public static final String PARAM_DUE_AFTER = "dueAfter";
public static final String PARAM_PROPERTIES = "properties";
public static final String PARAM_DETAILED = "detailed";
@Override @Override
protected Map<String, Object> buildModel(WorkflowModelBuilder modelBuilder, WebScriptRequest req, Status status, protected Map<String, Object> buildModel(WorkflowModelBuilder modelBuilder, WebScriptRequest req, Status status, Cache cache)
Cache cache)
{ {
Map<String, Object> filters = new HashMap<String, Object>(4);
// authority is not included into filters list as it will be taken into account before filtering
String authority = getAuthority(req); String authority = getAuthority(req);
// state is also not included into filters list, for the same reason
WorkflowTaskState state = getState(req); WorkflowTaskState state = getState(req);
filters.put(PARAM_PRIORITY, req.getParameter(PARAM_PRIORITY));
filters.put(PARAM_DUE_BEFORE, getDateParameter(req, PARAM_DUE_BEFORE));
filters.put(PARAM_DUE_AFTER, getDateParameter(req, PARAM_DUE_AFTER));
List<String> properties = getProperties(req); List<String> properties = getProperties(req);
boolean detailed = "true".equals(req.getParameter(PARAM_DETAILED)); boolean detailed = "true".equals(req.getParameter(PARAM_DETAILED));
//TODO Handle possible thrown exceptions here? List<WorkflowTask> allTasks;
List<WorkflowTask> tasks = workflowService.getAssignedTasks(authority, state);
List<WorkflowTask> pooledTasks= workflowService.getPooledTasks(authority); if (authority != null)
ArrayList<WorkflowTask> allTasks = new ArrayList<WorkflowTask>(tasks.size() + pooledTasks.size());
allTasks.addAll(tasks);
allTasks.addAll(pooledTasks);
ArrayList<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
for (WorkflowTask task : allTasks)
{ {
if (detailed) List<WorkflowTask> tasks = workflowService.getAssignedTasks(authority, state);
List<WorkflowTask> pooledTasks = workflowService.getPooledTasks(authority);
allTasks = new ArrayList<WorkflowTask>(tasks.size() + pooledTasks.size());
allTasks.addAll(tasks);
allTasks.addAll(pooledTasks);
}
else
{
// authority was not provided -> return all active tasks in the system
WorkflowTaskQuery taskQuery = new WorkflowTaskQuery();
taskQuery.setTaskState(state);
allTasks = workflowService.queryTasks(taskQuery);
}
ArrayList<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
for (WorkflowTask task : allTasks)
{
if (matches(task, filters))
{ {
results.add(modelBuilder.buildDetailed(task)); if (detailed)
} {
else { results.add(modelBuilder.buildDetailed(task));
results.add(modelBuilder.buildSimple(task, properties)); }
else
{
results.add(modelBuilder.buildSimple(task, properties));
}
} }
} }
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
model.put("taskInstances", results); model.put("taskInstances", results);
return model; return model;
@@ -81,7 +110,7 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
private List<String> getProperties(WebScriptRequest req) private List<String> getProperties(WebScriptRequest req)
{ {
String propertiesStr = req.getParameter(PARAM_PROPERTIES); String propertiesStr = req.getParameter(PARAM_PROPERTIES);
if(propertiesStr != null) if (propertiesStr != null)
{ {
return Arrays.asList(propertiesStr.split(",")); return Arrays.asList(propertiesStr.split(","));
} }
@@ -95,16 +124,16 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
*/ */
private WorkflowTaskState getState(WebScriptRequest req) private WorkflowTaskState getState(WebScriptRequest req)
{ {
String stateName= req.getParameter(PARAM_STATUS); String stateName = req.getParameter(PARAM_STATE);
if(stateName != null) if (stateName != null)
{ {
try try
{ {
return WorkflowTaskState.valueOf(stateName.toUpperCase()); return WorkflowTaskState.valueOf(stateName.toUpperCase());
} }
catch(IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
String msg = "Unrecognised State parameter: "+stateName; String msg = "Unrecognised State parameter: " + stateName;
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, msg); throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, msg);
} }
} }
@@ -120,11 +149,89 @@ public class TaskInstancesGet extends AbstractWorkflowWebscript
private String getAuthority(WebScriptRequest req) private String getAuthority(WebScriptRequest req)
{ {
String authority = req.getParameter(PARAM_AUTHORITY); String authority = req.getParameter(PARAM_AUTHORITY);
if(authority == null) if (authority == null || authority.length() == 0)
{ {
authority = AuthenticationUtil.getFullyAuthenticatedUser(); authority = null;
} }
return authority; return authority;
} }
private Date getDateParameter(WebScriptRequest req, String name)
{
String dateString = req.getParameter(name);
if (dateString != null)
{
try
{
return ISO8601DateFormat.parse(dateString.replaceAll(" ", "+"));
}
catch (Exception e)
{
String msg = "Invalid date value: " + dateString;
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
return null;
}
/*
* If workflow task matches at list one filter value or if no filter was specified, then it will be included in response
*/
private boolean matches(WorkflowTask task, Map<String, Object> filters)
{
// by default we assume that workflow task should be included to response
boolean result = true;
boolean firstFilter = true;
for (String key : filters.keySet())
{
Object filterValue = filters.get(key);
// skip null filters (null value means that filter was not specified)
if (filterValue != null)
{
// some of the filter was specified, so the decision to include or not task to response
// based on matching to filter parameter (by default false)
if (firstFilter)
{
result = false;
firstFilter = false;
}
boolean matches = false;
if (key.equals(PARAM_DUE_BEFORE))
{
Serializable dueDate = task.getProperties().get(WorkflowModel.PROP_DUE_DATE);
if (dueDate == null || ((Date) dueDate).getTime() <= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_DUE_AFTER))
{
Serializable dueDate = task.getProperties().get(WorkflowModel.PROP_DUE_DATE);
if (dueDate == null || ((Date) dueDate).getTime() >= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_PRIORITY))
{
if (filterValue.equals(task.getProperties().get(WorkflowModel.PROP_PRIORITY).toString()))
{
matches = true;
}
}
// update global result
result = result || matches;
}
}
return result;
}
} }

View File

@@ -18,11 +18,15 @@
*/ */
package org.alfresco.repo.web.scripts.workflow; package org.alfresco.repo.web.scripts.workflow;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
@@ -31,6 +35,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.springframework.extensions.surf.util.ISO8601DateFormat; import org.springframework.extensions.surf.util.ISO8601DateFormat;
import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptRequest;
/** /**
@@ -43,26 +48,36 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
public static final String PARAM_STATE = "state"; public static final String PARAM_STATE = "state";
public static final String PARAM_INITIATOR = "initiator"; public static final String PARAM_INITIATOR = "initiator";
public static final String PARAM_DATE = "date";
public static final String PARAM_PRIORITY = "priority"; public static final String PARAM_PRIORITY = "priority";
public static final String PARAM_DUE_BEFORE = "dueBefore";
public static final String PARAM_DUE_AFTER = "dueAfter";
public static final String PARAM_STARTED_BEFORE = "startedBefore";
public static final String PARAM_STARTED_AFTER = "startedAfter";
public static final String PARAM_COMPLETED_BEFORE = "completedBefore";
public static final String PARAM_COMPLETED_AFTER = "completedAfter";
public static final String PARAM_DEFINITION_ID = "workflow_definition_id"; public static final String PARAM_DEFINITION_ID = "workflow_definition_id";
@Override @Override
protected Map<String, Object> buildModel(WorkflowModelBuilder modelBuilder, WebScriptRequest req, Status status, Cache cache) protected Map<String, Object> buildModel(WorkflowModelBuilder modelBuilder, WebScriptRequest req, Status status, Cache cache)
{ {
Map<String, String> params = req.getServiceMatch().getTemplateVars(); Map<String, String> params = req.getServiceMatch().getTemplateVars();
// get request parameters // get request parameters
Map<String, String> filters = new HashMap<String, String>(4); Map<String, Object> filters = new HashMap<String, Object>(9);
filters.put(PARAM_STATE, req.getParameter(PARAM_STATE)); filters.put(PARAM_STATE, req.getParameter(PARAM_STATE));
filters.put(PARAM_INITIATOR, req.getParameter(PARAM_INITIATOR)); filters.put(PARAM_INITIATOR, req.getParameter(PARAM_INITIATOR));
filters.put(PARAM_DATE, req.getParameter(PARAM_DATE));
filters.put(PARAM_PRIORITY, req.getParameter(PARAM_PRIORITY)); filters.put(PARAM_PRIORITY, req.getParameter(PARAM_PRIORITY));
filters.put(PARAM_DUE_BEFORE, getDateParameter(req, PARAM_DUE_BEFORE));
filters.put(PARAM_DUE_AFTER, getDateParameter(req, PARAM_DUE_AFTER));
filters.put(PARAM_STARTED_BEFORE, getDateParameter(req, PARAM_STARTED_BEFORE));
filters.put(PARAM_STARTED_AFTER, getDateParameter(req, PARAM_STARTED_AFTER));
filters.put(PARAM_COMPLETED_BEFORE, getDateParameter(req, PARAM_COMPLETED_BEFORE));
filters.put(PARAM_COMPLETED_AFTER, getDateParameter(req, PARAM_COMPLETED_AFTER));
String workflowDefinitionId = params.get(PARAM_DEFINITION_ID); String workflowDefinitionId = params.get(PARAM_DEFINITION_ID);
List<WorkflowInstance> workflows = new ArrayList<WorkflowInstance>(); List<WorkflowInstance> workflows = new ArrayList<WorkflowInstance>();
if (workflowDefinitionId != null) if (workflowDefinitionId != null)
{ {
// list workflows for specified workflow definition // list workflows for specified workflow definition
@@ -71,17 +86,17 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
else else
{ {
List<WorkflowDefinition> workflowDefinitions = workflowService.getAllDefinitions(); List<WorkflowDefinition> workflowDefinitions = workflowService.getAllDefinitions();
// list workflows for all definitions // list workflows for all definitions
for (WorkflowDefinition workflowDefinition : workflowDefinitions) for (WorkflowDefinition workflowDefinition : workflowDefinitions)
{ {
workflows.addAll(workflowService.getWorkflows(workflowDefinition.getId())); workflows.addAll(workflowService.getWorkflows(workflowDefinition.getId()));
} }
} }
// filter result // filter result
List<Map<String, Object>> results = new ArrayList<Map<String,Object>>(workflows.size()); List<Map<String, Object>> results = new ArrayList<Map<String, Object>>(workflows.size());
for (WorkflowInstance workflow : workflows) for (WorkflowInstance workflow : workflows)
{ {
if (matches(workflow, filters, modelBuilder)) if (matches(workflow, filters, modelBuilder))
@@ -89,18 +104,18 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
results.add(modelBuilder.buildSimple(workflow)); results.add(modelBuilder.buildSimple(workflow));
} }
} }
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
// build the model for ftl // build the model for ftl
model.put("workflowInstances", results); model.put("workflowInstances", results);
return model; return model;
} }
/* /*
* If workflow instance matches at list one filter value or if no filter was specified, then it will included in response * If workflow instance matches at list one filter value or if no filter was specified, then it will be included in response
*/ */
private boolean matches(WorkflowInstance workflowInstance, Map<String, String> filters, WorkflowModelBuilder modelBuilder) private boolean matches(WorkflowInstance workflowInstance, Map<String, Object> filters, WorkflowModelBuilder modelBuilder)
{ {
// by default we assume that workflow instance should be included to response // by default we assume that workflow instance should be included to response
boolean result = true; boolean result = true;
@@ -108,7 +123,7 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
for (String key : filters.keySet()) for (String key : filters.keySet())
{ {
String filterValue = filters.get(key); Object filterValue = filters.get(key);
// skip null filters (null value means that filter was not specified) // skip null filters (null value means that filter was not specified)
if (filterValue != null) if (filterValue != null)
@@ -125,7 +140,7 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
if (key.equals(PARAM_STATE)) if (key.equals(PARAM_STATE))
{ {
WorkflowState filter = WorkflowState.getState(filterValue); WorkflowState filter = WorkflowState.getState(filterValue.toString());
if (filter != null) if (filter != null)
{ {
@@ -135,17 +150,66 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
} }
} }
} }
else if (key.equals(PARAM_DATE)) else if (key.equals(PARAM_DUE_BEFORE))
{ {
// only workflows that was started after specified time are returned WorkflowTask startTask = modelBuilder.getStartTaskForWorkflow(workflowInstance);
if (workflowInstance.getStartDate().getTime() >= ISO8601DateFormat.parse(filterValue.replaceAll(" ", "+")).getTime()) Serializable dueDate = startTask.getProperties().get(WorkflowModel.PROP_WORKFLOW_DUE_DATE);
if (dueDate == null || ((Date) dueDate).getTime() <= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_DUE_AFTER))
{
WorkflowTask startTask = modelBuilder.getStartTaskForWorkflow(workflowInstance);
Serializable dueDate = startTask.getProperties().get(WorkflowModel.PROP_WORKFLOW_DUE_DATE);
if (dueDate == null || ((Date) dueDate).getTime() >= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_STARTED_BEFORE))
{
Date startDate = workflowInstance.getStartDate();
if (startDate == null || startDate.getTime() <= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_STARTED_AFTER))
{
Date startDate = workflowInstance.getStartDate();
if (startDate == null || startDate.getTime() >= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_COMPLETED_BEFORE))
{
Date endDate = workflowInstance.getEndDate();
if (endDate == null || endDate.getTime() <= ((Date) filterValue).getTime())
{
matches = true;
}
}
else if (key.equals(PARAM_COMPLETED_AFTER))
{
Date endDate = workflowInstance.getEndDate();
if (endDate == null || endDate.getTime() >= ((Date) filterValue).getTime())
{ {
matches = true; matches = true;
} }
} }
else if (key.equals(PARAM_INITIATOR)) else if (key.equals(PARAM_INITIATOR))
{ {
if (workflowInstance.getInitiator() != null && nodeService.exists(workflowInstance.getInitiator()) && filterValue.equals(nodeService.getProperty(workflowInstance.getInitiator(), ContentModel.PROP_USERNAME))) if (workflowInstance.getInitiator() != null && nodeService.exists(workflowInstance.getInitiator())
&& filterValue.equals(nodeService.getProperty(workflowInstance.getInitiator(), ContentModel.PROP_USERNAME)))
{ {
matches = true; matches = true;
} }
@@ -163,22 +227,41 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
result = result || matches; result = result || matches;
} }
} }
return result; return result;
} }
private Date getDateParameter(WebScriptRequest req, String name)
{
String dateString = req.getParameter(name);
if (dateString != null)
{
try
{
return ISO8601DateFormat.parse(dateString.replaceAll(" ", "+"));
}
catch (Exception e)
{
String msg = "Invalid date value: " + dateString;
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
return null;
}
private enum WorkflowState private enum WorkflowState
{ {
ACTIVE ("active"), ACTIVE ("active"),
COMPLETED ("completed"); COMPLETED ("completed");
String value; String value;
WorkflowState(String value) WorkflowState(String value)
{ {
this.value = value; this.value = value;
} }
static WorkflowState getState(String value) static WorkflowState getState(String value)
{ {
for (WorkflowState state : WorkflowState.values()) for (WorkflowState state : WorkflowState.values())
@@ -188,7 +271,7 @@ public class WorkflowInstancesGet extends AbstractWorkflowWebscript
return state; return state;
} }
} }
return null; return null;
} }
} }

View File

@@ -56,9 +56,9 @@ import org.json.JSONObject;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.extensions.surf.util.ISO8601DateFormat; import org.springframework.extensions.surf.util.ISO8601DateFormat;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PutRequest; import org.springframework.extensions.webscripts.TestWebScriptServer.PutRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response; import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
/** /**
@@ -69,84 +69,98 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
{ {
private final static String USER1 = "Bob" + GUID.generate(); private final static String USER1 = "Bob" + GUID.generate();
private final static String USER2 = "Jane" + GUID.generate(); private final static String USER2 = "Jane" + GUID.generate();
private final static String USER3 = "Nick" + GUID.generate(); private final static String USER3 = "Nick" + GUID.generate();
private static final String URL_TASKS = "api/task-instances"; private static final String URL_TASKS = "api/task-instances";
private static final String URL_USER_TASKS = "api/task-instances?authority={0}";
private static final String URL_WORKFLOW_DEFINITIONS = "api/workflow-definitions"; private static final String URL_WORKFLOW_DEFINITIONS = "api/workflow-definitions";
private static final String URL_WORKFLOW_INSTANCES = "api/workflow-instances"; private static final String URL_WORKFLOW_INSTANCES = "api/workflow-instances";
private static final String URL_WORKFLOW_INSTANCES_FOR_DEFINITION = "api/workflow-definitions/{0}/workflow-instances"; private static final String URL_WORKFLOW_INSTANCES_FOR_DEFINITION = "api/workflow-definitions/{0}/workflow-instances";
private static final String URL_WORKFLOW_INSTANCES_FOR_NODE = "api/node/{0}/{1}/{2}/workflow-instances"; private static final String URL_WORKFLOW_INSTANCES_FOR_NODE = "api/node/{0}/{1}/{2}/workflow-instances";
private static final String COMPANY_HOME = "/app:company_home"; private static final String COMPANY_HOME = "/app:company_home";
private static final String TEST_CONTENT = "TestContent"; private static final String TEST_CONTENT = "TestContent";
private TestPersonManager personManager; private TestPersonManager personManager;
private WorkflowService workflowService; private WorkflowService workflowService;
private NodeService nodeService; private NodeService nodeService;
private NamespaceService namespaceService; private NamespaceService namespaceService;
private NodeRef packageRef; private NodeRef packageRef;
private NodeRef contentNodeRef; private NodeRef contentNodeRef;
public void testTaskInstancesGet() throws Exception public void testTaskInstancesGet() throws Exception
{ {
// Check USER2 starts with no tasks. // Check USER2 starts with no tasks.
personManager.setUser(USER2); personManager.setUser(USER2);
Response response = sendRequest(new GetRequest(URL_TASKS), 200); Response response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2)), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
String jsonStr = response.getContentAsString(); String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONArray results = json.getJSONArray("data"); JSONArray results = json.getJSONArray("data");
assertNotNull(results); assertNotNull(results);
assertTrue(results.length() == 0); assertTrue(results.length() == 0);
// Start workflow as USER1 and assign task to USER2. // Start workflow as USER1 and assign task to USER2.
personManager.setUser(USER1); personManager.setUser(USER1);
WorkflowDefinition adhocDef = workflowService.getDefinitionByName("jbpm$wf:adhoc"); WorkflowDefinition adhocDef = workflowService.getDefinitionByName("jbpm$wf:adhoc");
Map<QName, Serializable> params = new HashMap<QName, Serializable>(); Map<QName, Serializable> params = new HashMap<QName, Serializable>();
params.put(WorkflowModel.ASSOC_ASSIGNEE, personManager.get(USER2)); params.put(WorkflowModel.ASSOC_ASSIGNEE, personManager.get(USER2));
params.put(WorkflowModel.PROP_DUE_DATE, new Date()); Date dueDate = new Date();
params.put(WorkflowModel.PROP_DUE_DATE, dueDate);
params.put(WorkflowModel.PROP_PRIORITY, 1); params.put(WorkflowModel.PROP_PRIORITY, 1);
params.put(WorkflowModel.ASSOC_PACKAGE, packageRef); params.put(WorkflowModel.ASSOC_PACKAGE, packageRef);
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params); WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params);
WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0); WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0);
workflowService.endTask(startTask.id, null); workflowService.endTask(startTask.id, null);
// Check USER2 now has one task. // Check USER2 now has one task.
List<WorkflowTask> tasks = workflowService.getAssignedTasks(USER2, WorkflowTaskState.IN_PROGRESS); List<WorkflowTask> tasks = workflowService.getAssignedTasks(USER2, WorkflowTaskState.IN_PROGRESS);
WorkflowTask task = tasks.get(0); WorkflowTask task = tasks.get(0);
personManager.setUser(USER2); personManager.setUser(USER2);
response = sendRequest(new GetRequest(URL_TASKS), 200); response = sendRequest(new GetRequest(MessageFormat.format(URL_USER_TASKS, USER2)), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
jsonStr = response.getContentAsString(); jsonStr = response.getContentAsString();
System.out.println(jsonStr);
json = new JSONObject(jsonStr); json = new JSONObject(jsonStr);
results = json.getJSONArray("data"); results = json.getJSONArray("data");
assertNotNull(results); assertNotNull(results);
assertTrue(results.length() == tasks.size()); assertTrue(results.length() == tasks.size());
JSONObject result = results.getJSONObject(0); JSONObject result = results.getJSONObject(0);
String expUrl = "api/task-instances/" + task.id; String expUrl = "api/task-instances/" + task.id;
assertEquals(expUrl, result.getString("url")); assertEquals(expUrl, result.getString("url"));
assertEquals(task.name, result.getString("name")); assertEquals(task.name, result.getString("name"));
assertEquals(task.title, result.getString("title")); assertEquals(task.title, result.getString("title"));
assertEquals(task.description, result.getString("description")); assertEquals(task.description, result.getString("description"));
assertEquals(task.state.name(), result.getString("state")); assertEquals(task.state.name(), result.getString("state"));
assertEquals(task.definition.metadata.getTitle(), result.getString("typeDefinitionTitle")); assertEquals(task.definition.metadata.getName().toPrefixString(this.namespaceService),
assertEquals(false, result.getBoolean("isPooled")); result.getString("type"));
assertEquals( "api/workflow-paths/" + adhocPath.getId(), result.getString("path"));
assertFalse(result.getBoolean("isPooled"));
assertTrue(result.getBoolean("isEditable"));
assertTrue(result.getBoolean("isReassignable"));
assertFalse(result.getBoolean("isClaimable"));
assertFalse(result.getBoolean("isReleasable"));
JSONObject owner = result.getJSONObject("owner"); JSONObject owner = result.getJSONObject("owner");
assertEquals(USER2, owner.getString("userName")); assertEquals(USER2, owner.getString("userName"));
assertEquals(personManager.getFirstName(USER2), owner.getString("firstName")); assertEquals(personManager.getFirstName(USER2), owner.getString("firstName"));
assertEquals(personManager.getLastName(USER2), owner.getString("lastName")); assertEquals(personManager.getLastName(USER2), owner.getString("lastName"));
JSONObject properties = result.getJSONObject("properties"); JSONObject properties = result.getJSONObject("properties");
assertNotNull(properties); assertNotNull(properties);
JSONObject instance = result.getJSONObject("workflowInstance"); JSONObject instance = result.getJSONObject("workflowInstance");
assertNotNull(instance); assertNotNull(instance);
// TODO: Add more tests to check property filtering and pooled actors. // TODO: Add more tests to check property filtering and pooled actors.
// filtering
checkFiltering(URL_TASKS + "?priority=2");
checkFiltering(URL_TASKS + "?dueAfter=" + ISO8601DateFormat.format(dueDate));
checkFiltering(URL_TASKS + "?dueBefore=" + ISO8601DateFormat.format(dueDate));
} }
public void testTaskInstanceGet() throws Exception public void testTaskInstanceGet() throws Exception
@@ -177,7 +191,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertEquals(startTask.description, result.getString("description")); assertEquals(startTask.description, result.getString("description"));
assertEquals(startTask.state.name(), result.getString("state")); assertEquals(startTask.state.name(), result.getString("state"));
assertEquals(startTask.name, result.getString("type")); assertEquals(startTask.name, result.getString("type"));
assertEquals( "api/workflow-paths/" + adhocPath.getId(), result.getString("path")); assertEquals("api/workflow-paths/" + adhocPath.getId(), result.getString("path"));
assertFalse(result.getBoolean("isPooled")); assertFalse(result.getBoolean("isPooled"));
assertTrue(result.getBoolean("isEditable")); assertTrue(result.getBoolean("isEditable"));
assertTrue(result.getBoolean("isReassignable")); assertTrue(result.getBoolean("isReassignable"));
@@ -194,12 +208,12 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertTrue(properties.has("bpm_priority")); assertTrue(properties.has("bpm_priority"));
assertTrue(properties.has("bpm_description")); assertTrue(properties.has("bpm_description"));
assertTrue(properties.has("bpm_reassignable")); assertTrue(properties.has("bpm_reassignable"));
JSONObject instance = result.getJSONObject("workflowInstance"); JSONObject instance = result.getJSONObject("workflowInstance");
WorkflowInstance startInstance = startTask.path.instance; WorkflowInstance startInstance = startTask.path.instance;
assertNotNull(instance); assertNotNull(instance);
assertEquals(startInstance.id, instance.getString("id")); assertEquals(startInstance.id, instance.getString("id"));
assertTrue(instance.has("url")); assertTrue(instance.has("url"));
assertEquals(startInstance.definition.name, instance.getString("name")); assertEquals(startInstance.definition.name, instance.getString("name"));
@@ -207,13 +221,13 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertEquals(startInstance.definition.description, instance.getString("description")); assertEquals(startInstance.definition.description, instance.getString("description"));
assertEquals(startInstance.active, instance.getBoolean("isActive")); assertEquals(startInstance.active, instance.getBoolean("isActive"));
assertTrue(instance.has("startDate")); assertTrue(instance.has("startDate"));
JSONObject initiator = instance.getJSONObject("initiator"); JSONObject initiator = instance.getJSONObject("initiator");
assertEquals(USER1, initiator.getString("userName")); assertEquals(USER1, initiator.getString("userName"));
assertEquals(personManager.getFirstName(USER1), initiator.getString("firstName")); assertEquals(personManager.getFirstName(USER1), initiator.getString("firstName"));
assertEquals(personManager.getLastName(USER1), initiator.getString("lastName")); assertEquals(personManager.getLastName(USER1), initiator.getString("lastName"));
JSONObject definition = result.getJSONObject("definition"); JSONObject definition = result.getJSONObject("definition");
WorkflowTaskDefinition startDefinitiont = startTask.definition; WorkflowTaskDefinition startDefinitiont = startTask.definition;
@@ -264,7 +278,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
} }
} }
public void testTaskInstancePut() throws Exception public void testTaskInstancePut() throws Exception
{ {
// Start workflow as USER1 and assign task to USER2. // Start workflow as USER1 and assign task to USER2.
@@ -278,18 +292,18 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params); WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params);
WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0); WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0);
Response getResponse = sendRequest(new GetRequest(URL_TASKS + "/" + startTask.id), 200); Response getResponse = sendRequest(new GetRequest(URL_TASKS + "/" + startTask.id), 200);
JSONObject jsonProperties = new JSONObject(getResponse.getContentAsString()).getJSONObject("data").getJSONObject("properties"); JSONObject jsonProperties = new JSONObject(getResponse.getContentAsString()).getJSONObject("data").getJSONObject("properties");
// make some changes // make some changes
jsonProperties.remove(qnameToString(WorkflowModel.ASSOC_PACKAGE)); jsonProperties.remove(qnameToString(WorkflowModel.ASSOC_PACKAGE));
jsonProperties.put(qnameToString(WorkflowModel.PROP_COMMENT), "Edited comment"); jsonProperties.put(qnameToString(WorkflowModel.PROP_COMMENT), "Edited comment");
jsonProperties.put(qnameToString(WorkflowModel.PROP_DUE_DATE), ISO8601DateFormat.format(new Date())); jsonProperties.put(qnameToString(WorkflowModel.PROP_DUE_DATE), ISO8601DateFormat.format(new Date()));
jsonProperties.put(qnameToString(WorkflowModel.PROP_DESCRIPTION), "Edited description"); jsonProperties.put(qnameToString(WorkflowModel.PROP_DESCRIPTION), "Edited description");
jsonProperties.put(qnameToString(WorkflowModel.PROP_PRIORITY), 1); jsonProperties.put(qnameToString(WorkflowModel.PROP_PRIORITY), 1);
// test USER3 can not update the task // test USER3 can not update the task
personManager.setUser(USER3); personManager.setUser(USER3);
Response unauthResponse = sendRequest(new PutRequest(URL_TASKS + "/" + startTask.id, jsonProperties.toString(), "application/json"), 401); Response unauthResponse = sendRequest(new PutRequest(URL_TASKS + "/" + startTask.id, jsonProperties.toString(), "application/json"), 401);
@@ -298,26 +312,26 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
// test USER1 (the task owner) can update the task // test USER1 (the task owner) can update the task
personManager.setUser(USER1); personManager.setUser(USER1);
Response putResponse = sendRequest(new PutRequest(URL_TASKS + "/" + startTask.id, jsonProperties.toString(), "application/json"), 200); Response putResponse = sendRequest(new PutRequest(URL_TASKS + "/" + startTask.id, jsonProperties.toString(), "application/json"), 200);
assertEquals(Status.STATUS_OK, putResponse.getStatus()); assertEquals(Status.STATUS_OK, putResponse.getStatus());
String jsonStr = putResponse.getContentAsString(); String jsonStr = putResponse.getContentAsString();
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONObject result = json.getJSONObject("data"); JSONObject result = json.getJSONObject("data");
assertNotNull(result); assertNotNull(result);
JSONObject editedJsonProperties = result.getJSONObject("properties"); JSONObject editedJsonProperties = result.getJSONObject("properties");
compareProperties(jsonProperties, editedJsonProperties); compareProperties(jsonProperties, editedJsonProperties);
// get the next task where USER2 is the owner // get the next task where USER2 is the owner
workflowService.endTask(startTask.id, null); workflowService.endTask(startTask.id, null);
List<WorkflowPath> paths = workflowService.getWorkflowPaths(adhocPath.getInstance().getId()); List<WorkflowPath> paths = workflowService.getWorkflowPaths(adhocPath.getInstance().getId());
WorkflowTask nextTask = workflowService.getTasksForWorkflowPath(paths.get(0).getId()).get(0); WorkflowTask nextTask = workflowService.getTasksForWorkflowPath(paths.get(0).getId()).get(0);
// make sure USER1 (the workflow initiator) can update // make sure USER1 (the workflow initiator) can update
putResponse = sendRequest(new PutRequest(URL_TASKS + "/" + nextTask.id, jsonProperties.toString(), "application/json"), 200); putResponse = sendRequest(new PutRequest(URL_TASKS + "/" + nextTask.id, jsonProperties.toString(), "application/json"), 200);
} }
public void testWorkflowDefinitionsGet() throws Exception public void testWorkflowDefinitionsGet() throws Exception
{ {
Response response = sendRequest(new GetRequest(URL_WORKFLOW_DEFINITIONS), 200); Response response = sendRequest(new GetRequest(URL_WORKFLOW_DEFINITIONS), 200);
@@ -325,30 +339,30 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
JSONObject json = new JSONObject(response.getContentAsString()); JSONObject json = new JSONObject(response.getContentAsString());
JSONArray results = json.getJSONArray("data"); JSONArray results = json.getJSONArray("data");
assertNotNull(results); assertNotNull(results);
for (int i = 0; i < results.length(); i++) for (int i = 0; i < results.length(); i++)
{ {
JSONObject workflowDefinitionJSON = results.getJSONObject(i); JSONObject workflowDefinitionJSON = results.getJSONObject(i);
assertTrue(workflowDefinitionJSON.has("id")); assertTrue(workflowDefinitionJSON.has("id"));
assertTrue(workflowDefinitionJSON.getString("id").length() > 0); assertTrue(workflowDefinitionJSON.getString("id").length() > 0);
assertTrue(workflowDefinitionJSON.has("url")); assertTrue(workflowDefinitionJSON.has("url"));
String url = workflowDefinitionJSON.getString("url"); String url = workflowDefinitionJSON.getString("url");
assertTrue(url.length() > 0); assertTrue(url.length() > 0);
assertTrue(url.startsWith("api/workflow-definitions/")); assertTrue(url.startsWith("api/workflow-definitions/"));
assertTrue(workflowDefinitionJSON.has("name")); assertTrue(workflowDefinitionJSON.has("name"));
assertTrue(workflowDefinitionJSON.getString("name").length() > 0); assertTrue(workflowDefinitionJSON.getString("name").length() > 0);
assertTrue(workflowDefinitionJSON.has("title")); assertTrue(workflowDefinitionJSON.has("title"));
assertTrue(workflowDefinitionJSON.getString("title").length() > 0); assertTrue(workflowDefinitionJSON.getString("title").length() > 0);
assertTrue(workflowDefinitionJSON.has("description")); assertTrue(workflowDefinitionJSON.has("description"));
assertTrue(workflowDefinitionJSON.getString("description").length() > 0); assertTrue(workflowDefinitionJSON.getString("description").length() > 0);
} }
} }
public void testWorkflowInstanceGet() throws Exception public void testWorkflowInstanceGet() throws Exception
{ {
//Start workflow as USER1 and assign task to USER2. //Start workflow as USER1 and assign task to USER2.
@@ -365,16 +379,16 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params); WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params);
WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0); WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0);
startTask = workflowService.endTask(startTask.id, null); startTask = workflowService.endTask(startTask.id, null);
WorkflowInstance adhocInstance = startTask.path.instance; WorkflowInstance adhocInstance = startTask.path.instance;
Response response = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.id + "?includeTasks=true"), 200); Response response = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.id + "?includeTasks=true"), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
String jsonStr = response.getContentAsString(); String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONObject result = json.getJSONObject("data"); JSONObject result = json.getJSONObject("data");
assertNotNull(result); assertNotNull(result);
assertEquals(adhocInstance.id, result.getString("id")); assertEquals(adhocInstance.id, result.getString("id"));
assertEquals(adhocInstance.definition.name, result.getString("name")); assertEquals(adhocInstance.definition.name, result.getString("name"));
assertEquals(adhocInstance.definition.title, result.getString("title")); assertEquals(adhocInstance.definition.title, result.getString("title"));
@@ -385,20 +399,20 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertNotNull(result.getString("endDate")); assertNotNull(result.getString("endDate"));
assertEquals(2, result.getInt("priority")); assertEquals(2, result.getInt("priority"));
JSONObject initiator = result.getJSONObject("initiator"); JSONObject initiator = result.getJSONObject("initiator");
assertEquals(USER1, initiator.getString("userName")); assertEquals(USER1, initiator.getString("userName"));
assertEquals(personManager.getFirstName(USER1), initiator.getString("firstName")); assertEquals(personManager.getFirstName(USER1), initiator.getString("firstName"));
assertEquals(personManager.getLastName(USER1), initiator.getString("lastName")); assertEquals(personManager.getLastName(USER1), initiator.getString("lastName"));
assertEquals(adhocInstance.context.toString(), result.getString("context")); assertEquals(adhocInstance.context.toString(), result.getString("context"));
assertEquals(adhocInstance.workflowPackage.toString(), result.getString("package")); assertEquals(adhocInstance.workflowPackage.toString(), result.getString("package"));
assertNotNull(result.getString("startTaskInstanceId")); assertNotNull(result.getString("startTaskInstanceId"));
JSONObject jsonDefinition = result.getJSONObject("definition"); JSONObject jsonDefinition = result.getJSONObject("definition");
WorkflowDefinition adhocDefinition = adhocInstance.definition; WorkflowDefinition adhocDefinition = adhocInstance.definition;
assertNotNull(jsonDefinition); assertNotNull(jsonDefinition);
assertEquals(adhocDefinition.id, jsonDefinition.getString("id")); assertEquals(adhocDefinition.id, jsonDefinition.getString("id"));
assertEquals(adhocDefinition.name, jsonDefinition.getString("name")); assertEquals(adhocDefinition.name, jsonDefinition.getString("name"));
assertEquals(adhocDefinition.title, jsonDefinition.getString("title")); assertEquals(adhocDefinition.title, jsonDefinition.getString("title"));
@@ -406,11 +420,11 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertEquals(adhocDefinition.version, jsonDefinition.getString("version")); assertEquals(adhocDefinition.version, jsonDefinition.getString("version"));
assertEquals(adhocDefinition.getStartTaskDefinition().metadata.getName().toPrefixString(namespaceService), jsonDefinition.getString("startTaskDefinitionType")); assertEquals(adhocDefinition.getStartTaskDefinition().metadata.getName().toPrefixString(namespaceService), jsonDefinition.getString("startTaskDefinitionType"));
assertTrue(jsonDefinition.has("taskDefinitions")); assertTrue(jsonDefinition.has("taskDefinitions"));
JSONArray tasks = result.getJSONArray("tasks"); JSONArray tasks = result.getJSONArray("tasks");
assertTrue(tasks.length() > 1); assertTrue(tasks.length() > 1);
} }
public void testWorkflowInstancesGet() throws Exception public void testWorkflowInstancesGet() throws Exception
{ {
//Start workflow as USER1 and assign task to USER2. //Start workflow as USER1 and assign task to USER2.
@@ -426,9 +440,9 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.getId(), params); WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.getId(), params);
WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.getId()).get(0); WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.getId()).get(0);
WorkflowInstance adhocInstance = startTask.getPath().getInstance(); WorkflowInstance adhocInstance = startTask.getPath().getInstance();
// Get Workflow Instance Collection // Get Workflow Instance Collection
Response response = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES), 200); Response response = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
@@ -436,74 +450,55 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONArray result = json.getJSONArray("data"); JSONArray result = json.getJSONArray("data");
assertNotNull(result); assertNotNull(result);
for (int i = 0; i < result.length(); i++) for (int i = 0; i < result.length(); i++)
{ {
checkSimpleWorkflowInstanceResponse(result.getJSONObject(i)); checkSimpleWorkflowInstanceResponse(result.getJSONObject(i));
} }
Response forDefinitionResponse = sendRequest(new GetRequest(MessageFormat.format(URL_WORKFLOW_INSTANCES_FOR_DEFINITION, adhocDef.getId())), 200); Response forDefinitionResponse = sendRequest(new GetRequest(MessageFormat.format(URL_WORKFLOW_INSTANCES_FOR_DEFINITION, adhocDef.getId())), 200);
assertEquals(Status.STATUS_OK, forDefinitionResponse.getStatus()); assertEquals(Status.STATUS_OK, forDefinitionResponse.getStatus());
String forDefinitionJsonStr = forDefinitionResponse.getContentAsString(); String forDefinitionJsonStr = forDefinitionResponse.getContentAsString();
JSONObject forDefinitionJson = new JSONObject(forDefinitionJsonStr); JSONObject forDefinitionJson = new JSONObject(forDefinitionJsonStr);
JSONArray forDefinitionResult = forDefinitionJson.getJSONArray("data"); JSONArray forDefinitionResult = forDefinitionJson.getJSONArray("data");
assertNotNull(forDefinitionResult); assertNotNull(forDefinitionResult);
for (int i = 0; i < forDefinitionResult.length(); i++) for (int i = 0; i < forDefinitionResult.length(); i++)
{ {
checkSimpleWorkflowInstanceResponse(forDefinitionResult.getJSONObject(i)); checkSimpleWorkflowInstanceResponse(forDefinitionResult.getJSONObject(i));
} }
// filter by initiator // filter by initiator
String initiatorFilter = "?initiator=" + USER1; checkFiltering(URL_WORKFLOW_INSTANCES + "?initiator=" + USER1);
Response initiatorFilteredResponse = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + initiatorFilter), 200);
// filter by startedAfter
assertEquals(Status.STATUS_OK, initiatorFilteredResponse.getStatus()); checkFiltering(URL_WORKFLOW_INSTANCES + "?startedAfter=" + ISO8601DateFormat.format(adhocInstance.getStartDate()));
String initiatorFilteredJsonStr = initiatorFilteredResponse.getContentAsString();
JSONObject initiatorFilteredJson = new JSONObject(initiatorFilteredJsonStr); // filter by startedBefore
JSONArray initiatorFilteredResult = initiatorFilteredJson.getJSONArray("data"); checkFiltering(URL_WORKFLOW_INSTANCES + "?startedBefore=" + ISO8601DateFormat.format(adhocInstance.getStartDate()));
assertNotNull(initiatorFilteredResult);
// filter by dueAfter
assertEquals(1, initiatorFilteredResult.length()); checkFiltering(URL_WORKFLOW_INSTANCES + "?dueAfter=" + ISO8601DateFormat.format(dueDate));
assertEquals(adhocInstance.getId(), initiatorFilteredResult.getJSONObject(0).getString("id"));
// filter by dueBefore
// filter by date checkFiltering(URL_WORKFLOW_INSTANCES + "?dueBefore=" + ISO8601DateFormat.format(dueDate));
String dateFilter = "?date=" + ISO8601DateFormat.format(adhocInstance.startDate);
Response dateFilteredResponse = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + dateFilter), 200); if (adhocInstance.getEndDate() != null)
{
assertEquals(Status.STATUS_OK, dateFilteredResponse.getStatus()); // filter by completedAfter
String dateFilteredJsonStr = dateFilteredResponse.getContentAsString(); checkFiltering(URL_WORKFLOW_INSTANCES + "?completedAfter=" + ISO8601DateFormat.format(adhocInstance.getEndDate()));
JSONObject dateFilteredJson = new JSONObject(dateFilteredJsonStr);
JSONArray dateFilteredResult = dateFilteredJson.getJSONArray("data"); // filter by completedBefore
assertNotNull(dateFilteredResult); checkFiltering(URL_WORKFLOW_INSTANCES + "?completedBefore=" + ISO8601DateFormat.format(adhocInstance.getEndDate()));
}
assertTrue(dateFilteredResult.length() > 0);
// filter by priority
// filter by priority checkFiltering(URL_WORKFLOW_INSTANCES + "?priority=1");
String priorityFilter = "?priority=1";
Response priorityFilteredResponse = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + priorityFilter), 200);
assertEquals(Status.STATUS_OK, priorityFilteredResponse.getStatus());
String priorityFilteredJsonStr = priorityFilteredResponse.getContentAsString();
JSONObject priorityFilteredJson = new JSONObject(priorityFilteredJsonStr);
JSONArray priorityFilteredResult = priorityFilteredJson.getJSONArray("data");
assertNotNull(priorityFilteredResult);
assertTrue(priorityFilteredResult.length() > 0);
// filter by state // filter by state
String stateFilter = "?state=active"; checkFiltering(URL_WORKFLOW_INSTANCES + "?state=active");
Response stateFilteredResponse = sendRequest(new GetRequest(URL_WORKFLOW_INSTANCES + stateFilter), 200);
assertEquals(Status.STATUS_OK, stateFilteredResponse.getStatus());
String stateFilteredJsonStr = stateFilteredResponse.getContentAsString();
JSONObject stateFilteredJson = new JSONObject(stateFilteredJsonStr);
JSONArray stateFilteredResult = stateFilteredJson.getJSONArray("data");
assertNotNull(stateFilteredResult);
assertTrue(stateFilteredResult.length() > 1);
} }
public void testWorkflowInstancesForNodeGet() throws Exception public void testWorkflowInstancesForNodeGet() throws Exception
{ {
//Start workflow as USER1 and assign task to USER2. //Start workflow as USER1 and assign task to USER2.
@@ -514,38 +509,38 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
params.put(WorkflowModel.PROP_DUE_DATE, new Date()); params.put(WorkflowModel.PROP_DUE_DATE, new Date());
params.put(WorkflowModel.PROP_PRIORITY, 1); params.put(WorkflowModel.PROP_PRIORITY, 1);
params.put(WorkflowModel.ASSOC_PACKAGE, packageRef); params.put(WorkflowModel.ASSOC_PACKAGE, packageRef);
nodeService.addChild(packageRef, contentNodeRef, nodeService.addChild(packageRef, contentNodeRef,
WorkflowModel.ASSOC_PACKAGE_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, WorkflowModel.ASSOC_PACKAGE_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName((String)nodeService.getProperty( QName.createValidLocalName((String)nodeService.getProperty(
contentNodeRef, ContentModel.PROP_NAME)))); contentNodeRef, ContentModel.PROP_NAME))));
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params); WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params);
String url = MessageFormat.format(URL_WORKFLOW_INSTANCES_FOR_NODE, contentNodeRef.getStoreRef().getProtocol(), contentNodeRef.getStoreRef().getIdentifier(), contentNodeRef.getId()); String url = MessageFormat.format(URL_WORKFLOW_INSTANCES_FOR_NODE, contentNodeRef.getStoreRef().getProtocol(), contentNodeRef.getStoreRef().getIdentifier(), contentNodeRef.getId());
Response response = sendRequest(new GetRequest(url), 200); Response response = sendRequest(new GetRequest(url), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
String jsonStr = response.getContentAsString(); String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr); JSONObject json = new JSONObject(jsonStr);
JSONArray result = json.getJSONArray("data"); JSONArray result = json.getJSONArray("data");
assertNotNull(result); assertNotNull(result);
assertTrue(result.length() > 0); assertTrue(result.length() > 0);
workflowService.cancelWorkflow(adhocPath.getInstance().getId()); workflowService.cancelWorkflow(adhocPath.getInstance().getId());
Response afterCancelResponse = sendRequest(new GetRequest(url), 200); Response afterCancelResponse = sendRequest(new GetRequest(url), 200);
assertEquals(Status.STATUS_OK, afterCancelResponse.getStatus()); assertEquals(Status.STATUS_OK, afterCancelResponse.getStatus());
String afterCancelJsonStr = afterCancelResponse.getContentAsString(); String afterCancelJsonStr = afterCancelResponse.getContentAsString();
JSONObject afterCancelJson = new JSONObject(afterCancelJsonStr); JSONObject afterCancelJson = new JSONObject(afterCancelJsonStr);
JSONArray afterCancelResult = afterCancelJson.getJSONArray("data"); JSONArray afterCancelResult = afterCancelJson.getJSONArray("data");
assertNotNull(afterCancelResult); assertNotNull(afterCancelResult);
assertTrue(afterCancelResult.length() == 0); assertTrue(afterCancelResult.length() == 0);
} }
public void testWorkflowInstanceDelete() throws Exception public void testWorkflowInstanceDelete() throws Exception
{ {
//Start workflow as USER1 and assign task to USER2. //Start workflow as USER1 and assign task to USER2.
@@ -567,7 +562,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
Response response = sendRequest(new DeleteRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.getId()), 200); Response response = sendRequest(new DeleteRequest(URL_WORKFLOW_INSTANCES + "/" + adhocInstance.getId()), 200);
assertEquals(Status.STATUS_OK, response.getStatus()); assertEquals(Status.STATUS_OK, response.getStatus());
assertNull(workflowService.getWorkflowById(adhocInstance.getId())); assertNull(workflowService.getWorkflowById(adhocInstance.getId()));
} }
@@ -576,32 +571,31 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
{ {
super.setUp(); super.setUp();
ApplicationContext appContext = getServer().getApplicationContext(); ApplicationContext appContext = getServer().getApplicationContext();
namespaceService = (NamespaceService)appContext.getBean("NamespaceService"); namespaceService = (NamespaceService) appContext.getBean("NamespaceService");
workflowService = (WorkflowService)appContext.getBean("WorkflowService"); workflowService = (WorkflowService) appContext.getBean("WorkflowService");
MutableAuthenticationService authenticationService = (MutableAuthenticationService)appContext.getBean("AuthenticationService"); MutableAuthenticationService authenticationService = (MutableAuthenticationService) appContext.getBean("AuthenticationService");
PersonService personService = (PersonService)appContext.getBean("PersonService"); PersonService personService = (PersonService) appContext.getBean("PersonService");
SearchService searchService = (SearchService)appContext.getBean("SearchService"); SearchService searchService = (SearchService) appContext.getBean("SearchService");
FileFolderService fileFolderService = (FileFolderService)appContext.getBean("FileFolderService"); FileFolderService fileFolderService = (FileFolderService) appContext.getBean("FileFolderService");
nodeService = (NodeService)appContext.getBean("NodeService"); nodeService = (NodeService) appContext.getBean("NodeService");
personManager = new TestPersonManager(authenticationService, personService, nodeService); personManager = new TestPersonManager(authenticationService, personService, nodeService);
personManager.createPerson(USER1); personManager.createPerson(USER1);
personManager.createPerson(USER2); personManager.createPerson(USER2);
personManager.createPerson(USER3); personManager.createPerson(USER3);
packageRef = workflowService.createPackage(null); packageRef = workflowService.createPackage(null);
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
NodeRef companyHome = searchService.selectNodes(nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), NodeRef companyHome = searchService.selectNodes(nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), COMPANY_HOME, null, namespaceService, false).get(0);
COMPANY_HOME, null, namespaceService, false).get(0);
contentNodeRef = fileFolderService.create(companyHome, TEST_CONTENT + System.currentTimeMillis(), ContentModel.TYPE_CONTENT).getNodeRef(); contentNodeRef = fileFolderService.create(companyHome, TEST_CONTENT + System.currentTimeMillis(), ContentModel.TYPE_CONTENT).getNodeRef();
AuthenticationUtil.clearCurrentSecurityContext(); AuthenticationUtil.clearCurrentSecurityContext();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see junit.framework.TestCase#tearDown() * @see junit.framework.TestCase#tearDown()
*/ */
@@ -611,14 +605,14 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
super.tearDown(); super.tearDown();
personManager.clearPeople(); personManager.clearPeople();
} }
private String qnameToString(QName qName) private String qnameToString(QName qName)
{ {
String separator = Character.toString(QName.NAMESPACE_PREFIX); String separator = Character.toString(QName.NAMESPACE_PREFIX);
return qName.toPrefixString(namespaceService).replaceFirst(separator, "_"); return qName.toPrefixString(namespaceService).replaceFirst(separator, "_");
} }
private void compareProperties(JSONObject before, JSONObject after) throws JSONException private void compareProperties(JSONObject before, JSONObject after) throws JSONException
{ {
for (String name : JSONObject.getNames(after)) for (String name : JSONObject.getNames(after))
@@ -629,7 +623,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
{ {
for (int i = 0; i < before.getJSONArray(name).length(); i++) for (int i = 0; i < before.getJSONArray(name).length(); i++)
{ {
assertEquals(before.getJSONArray(name).get(i), after.getJSONArray(name).get(i)); assertEquals(before.getJSONArray(name).get(i), after.getJSONArray(name).get(i));
} }
} }
else else
@@ -639,41 +633,54 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
} }
} }
} }
private void checkSimpleWorkflowInstanceResponse(JSONObject json) throws JSONException private void checkSimpleWorkflowInstanceResponse(JSONObject json) throws JSONException
{ {
assertTrue(json.has("id")); assertTrue(json.has("id"));
assertTrue(json.getString("id").length() > 0); assertTrue(json.getString("id").length() > 0);
assertTrue(json.has("url")); assertTrue(json.has("url"));
assertTrue(json.getString("url").startsWith(URL_WORKFLOW_INSTANCES)); assertTrue(json.getString("url").startsWith(URL_WORKFLOW_INSTANCES));
assertTrue(json.has("name")); assertTrue(json.has("name"));
assertTrue(json.getString("name").length() > 0); assertTrue(json.getString("name").length() > 0);
assertTrue(json.has("title")); assertTrue(json.has("title"));
assertTrue(json.getString("title").length() > 0); assertTrue(json.getString("title").length() > 0);
assertTrue(json.has("description")); assertTrue(json.has("description"));
assertTrue(json.getString("description").length() > 0); assertTrue(json.getString("description").length() > 0);
assertTrue(json.has("isActive")); assertTrue(json.has("isActive"));
assertTrue(json.has("startDate")); assertTrue(json.has("startDate"));
assertTrue(json.getString("startDate").length() > 0); assertTrue(json.getString("startDate").length() > 0);
assertTrue(json.has("endDate")); assertTrue(json.has("endDate"));
assertTrue(json.has("initiator")); assertTrue(json.has("initiator"));
Object initiator = json.get("initiator"); Object initiator = json.get("initiator");
if (!initiator.equals(JSONObject.NULL)) if (!initiator.equals(JSONObject.NULL))
{ {
assertTrue(((JSONObject)initiator).has("userName")); assertTrue(((JSONObject) initiator).has("userName"));
assertTrue(((JSONObject)initiator).has("firstName")); assertTrue(((JSONObject) initiator).has("firstName"));
assertTrue(((JSONObject)initiator).has("lastName")); assertTrue(((JSONObject) initiator).has("lastName"));
} }
assertTrue(json.has("definitionUrl")); assertTrue(json.has("definitionUrl"));
assertTrue(json.getString("definitionUrl").startsWith(URL_WORKFLOW_DEFINITIONS)); assertTrue(json.getString("definitionUrl").startsWith(URL_WORKFLOW_DEFINITIONS));
} }
private void checkFiltering(String url) throws Exception
{
Response response = sendRequest(new GetRequest(url), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr);
JSONArray result = json.getJSONArray("data");
assertNotNull(result);
assertTrue(result.length() > 0);
}
} }