Reversed merged revisions 25061,25072,25261,25326

- ALF-1787 needs re-implementing on HEAD


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@26796 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2011-04-11 21:06:48 +00:00
parent 419ecfb9e7
commit 3e431fbca5
3 changed files with 33 additions and 613 deletions

View File

@@ -23,16 +23,14 @@ import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import java.util.Map.Entry;
import java.util.zip.ZipInputStream;
import org.alfresco.model.ContentModel;
@@ -72,9 +70,7 @@ import org.alfresco.service.namespace.NamespaceException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Conjunction;
@@ -134,8 +130,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
protected StoreRef companyHomeStore;
protected String companyHomePath;
private QNameCache qNameCache = new QNameCache();
// Note: jBPM query which is not provided out-of-the-box
// TODO: Check jBPM 3.2 and get this implemented in jBPM
private final static String COMPLETED_TASKS_QUERY = "select ti " + "from org.jbpm.taskmgmt.exe.TaskInstance as ti "
@@ -796,16 +790,26 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
return new WorkflowException(msg, e);
}
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#getActiveWorkflows(java.lang.String)
*/
@SuppressWarnings("unchecked")
public List<WorkflowInstance> getActiveWorkflows(final String workflowDefinitionId)
{
return getWorkflowsInternal(workflowDefinitionId, true);
}
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#getCompletedWorkflows(java.lang.String)
*/
public List<WorkflowInstance> getCompletedWorkflows(final String workflowDefinitionId)
{
return getWorkflowsInternal(workflowDefinitionId, false);
}
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#getWorkflows(java.lang.String)
*/
public List<WorkflowInstance> getWorkflows(final String workflowDefinitionId)
{
return getWorkflowsInternal(workflowDefinitionId, null);
@@ -1300,11 +1304,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
try
{
// arsenyko: I think it's necessary to avoid undesirable growth,
// since a cache implementation is quite simple and doesn't care about
// max elements in the cache.
qNameCache.clear();
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
{
public List<WorkflowTask> doInJbpm(JbpmContext context)
@@ -1313,22 +1312,16 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
List<TaskInstance> tasks;
if (state.equals(WorkflowTaskState.IN_PROGRESS))
{
Session session = context.getSession();
Query query = session.getNamedQuery("org.alfresco.repo.workflow.findTaskInstancesByActorId");
query.setString("actorId", authority);
query.setBoolean("true", true);
List<WorkflowTask> workflowTasks = getWorkflowTasks(session, query.list());
// Do we need to clear a session here? It takes 3 seconds with 2000 workflows.
// session.clear();
return workflowTasks;
TaskMgmtSession taskSession = context.getTaskMgmtSession();
tasks = taskSession.findTaskInstances(authority);
}
else
{
// Note: This method is not implemented by jBPM
tasks = findCompletedTaskInstances(context, authority);
return getWorkflowTasks(tasks);
}
return getWorkflowTasks(tasks);
}
/**
@@ -1343,7 +1336,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
* the actor to retrieve tasks for
* @return the tasks
*/
@SuppressWarnings("rawtypes")
private List<TaskInstance> findCompletedTaskInstances(JbpmContext jbpmContext, String actorId)
{
List<TaskInstance> result = null;
@@ -1370,6 +1362,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
}
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.TaskComponent#getPooledTasks(java.util.List)
*/
@SuppressWarnings("unchecked")
public List<WorkflowTask> getPooledTasks(final List<String> authorities)
{
@@ -1429,218 +1424,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
}
protected List<WorkflowTask> getWorkflowTasks(Session session, List<Object[]> rows)
{
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(rows.size());
/// ------------------------
// Preload data into L1 session
List<Long> taskInstanceIds = new ArrayList<Long>(rows.size());
List<Long> contextInstanceIds = new ArrayList<Long>(rows.size());
for (Object[] row : rows)
{
TaskInstance ti = (TaskInstance) row[0];
taskInstanceIds.add(ti.getId());
ContextInstance ci = (ContextInstance) row[8];
contextInstanceIds.add(ci.getId());
}
Map<Long, TaskInstance> taskInstanceCache = new HashMap<Long, TaskInstance>(rows.size());
if (taskInstanceIds.size() > 0)
{
taskInstanceCache = cacheTasks(session, taskInstanceIds);
}
Map<Long, TokenVariableMap> variablesCache = new HashMap<Long, TokenVariableMap>(rows.size());
if (contextInstanceIds.size() > 0)
{
variablesCache = cacheVariables(session, contextInstanceIds);
}
taskInstanceIds.clear();
contextInstanceIds.clear();
/// ------------------------
for(Object[] row : rows)
{
TaskInstance ti = (TaskInstance) row[0];
Token token = (Token)row[2];
ProcessInstance processInstance = (ProcessInstance)row[3];
Node node = (Node)row[4];
Task task = (Task)row[5];
ProcessDefinition processDefinition = (ProcessDefinition)row[6];
Task startTask = (Task)row[7];
ContextInstance contextInstance = (ContextInstance) row[8];
if (tenantService.isEnabled())
{
try
{
tenantService.checkDomain(processDefinition.getName());
}
catch (RuntimeException re)
{
// deliberately skip this one - due to domain mismatch - eg. when querying by group authority
continue;
}
}
// TaskInstance with some precached properties
TaskInstance helperTi = taskInstanceCache.get(ti.getId());
// WorkflowTask
WorkflowTask workflowTask = new WorkflowTask();
workflowTask.id = createGlobalId(new Long(ti.getId()).toString());
workflowTask.name = ti.getName();
workflowTask.state = getWorkflowTaskState(ti);
// WorkflowPath
WorkflowPath path = new WorkflowPath();
String tokenId = token.getFullName().replace("/", WORKFLOW_TOKEN_SEPERATOR);
path.id = createGlobalId(processInstance.getId() + WORKFLOW_PATH_SEPERATOR + tokenId);
// WorkflowInstance
WorkflowInstance workflowInstance = new WorkflowInstance();
workflowInstance.id = createGlobalId(new Long(processInstance.getId()).toString());
@SuppressWarnings("unchecked")
Map<String, Object> variables = variablesCache.get(contextInstance.getId()).getVariables();
workflowInstance.description = (String)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_DESCRIPTION));
String name = tenantService.getBaseName(processDefinition.getName());
String title = getLabel(name + ".workflow", TITLE_LABEL, name);
String description = getLabel(name + ".workflow", DESC_LABEL, title);
workflowInstance.definition = new WorkflowDefinition(createGlobalId(new Long(processDefinition.getId()).toString()),
createGlobalId(name),
new Integer(processDefinition.getVersion()).toString(),
title,
description,
(startTask != null
? createWorkflowTaskDefinition(startTask)
: null));
workflowInstance.active = !processInstance.hasEnded();
JBPMNode initiator = (JBPMNode)variables.get("initiator");
if (initiator != null)
{
workflowInstance.initiator = initiator.getNodeRef();
}
JBPMNode context = (JBPMNode)variables.get(mapQNameToName(WorkflowModel.PROP_CONTEXT));
if (context != null)
{
workflowInstance.context = context.getNodeRef();
}
JBPMNode workflowPackage = (JBPMNode)variables.get(mapQNameToName(WorkflowModel.ASSOC_PACKAGE));
if (workflowPackage != null)
{
workflowInstance.workflowPackage = workflowPackage.getNodeRef();
}
workflowInstance.priority = (Integer)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_PRIORITY));
workflowInstance.dueDate = (Date)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_DUE_DATE));
workflowInstance.startDate = processInstance.getStart();
workflowInstance.endDate = processInstance.getEnd();
path.instance = workflowInstance;
// WorkflowNode
path.node = createWorkflowNode(node);
path.active = !token.hasEnded();
workflowTask.path = path;
// WorkflowTaskDefinition
workflowTask.definition = createWorkflowTaskDefinition(task);
// WorkflowTaskProperies
workflowTask.properties = getTaskProperties(helperTi != null ? helperTi : ti, false, variablesCache);
String workflowDisplayId = processDefinition.getName() + ".task." + workflowTask.name;
workflowTask.title = getLabel(workflowDisplayId, TITLE_LABEL, null);
if (workflowTask.title == null)
{
workflowTask.title = workflowTask.definition.metadata.getTitle();
if (workflowTask.title == null)
{
workflowTask.title = workflowTask.name;
}
}
workflowTask.description = getLabel(workflowDisplayId, DESC_LABEL, null);
if (workflowTask.description == null)
{
description = workflowTask.definition.metadata.getDescription();
workflowTask.description = (description == null) ? workflowTask.title : description;
}
workflowTasks.add(workflowTask);
}
return workflowTasks;
}
private Map<Long, TokenVariableMap> cacheVariables(Session session, List<Long> ids)
{
// Preload data into L1 session
int batchSize = 800; // Must limit IN clause size!
List<Long> batch = new ArrayList<Long>(ids.size());
Map<Long, TokenVariableMap> cachedResults = new HashMap<Long, TokenVariableMap>();
for (Long id : ids)
{
batch.add(id);
if (batch.size() >= batchSize)
{
cacheVariablesNoBatch(session, batch, cachedResults);
batch.clear();
}
}
if (batch.size() > 0)
{
cacheVariablesNoBatch(session, batch, cachedResults);
}
batch.clear();
return cachedResults;
}
@SuppressWarnings("unchecked")
private void cacheVariablesNoBatch(Session session, List<Long> contextInstanceIds, Map<Long, TokenVariableMap> variablesCache)
{
Query query = session.getNamedQuery("org.alfresco.repo.workflow.cacheInstanceVariables");
query.setParameterList("ids", contextInstanceIds);
query.setCacheMode(CacheMode.PUT);
query.setFlushMode(FlushMode.MANUAL);
query.setCacheable(true);
List<TokenVariableMap> results = (List<TokenVariableMap>) query.list();
for (TokenVariableMap tokenVariableMap : results)
{
variablesCache.put(tokenVariableMap.getContextInstance().getId(), tokenVariableMap);
}
}
private Map<Long, TaskInstance> cacheTasks(Session session, List<Long> ids)
{
// Preload data into L1 session
int batchSize = 800; // Must limit IN clause size!
List<Long> batch = new ArrayList<Long>(ids.size());
Map<Long, TaskInstance> cachedResults = new HashMap<Long, TaskInstance>();
for (Long id : ids)
{
batch.add(id);
if (batch.size() >= batchSize)
{
cacheTasksNoBatch(session, batch, cachedResults);
batch.clear();
}
}
if (batch.size() > 0)
{
cacheTasksNoBatch(session, batch, cachedResults);
}
batch.clear();
return cachedResults;
}
@SuppressWarnings("unchecked")
private void cacheTasksNoBatch(Session session, List<Long> taskInstanceIds, Map<Long, TaskInstance> returnMap)
{
Query query = session.getNamedQuery("org.alfresco.repo.workflow.cacheTaskInstanceProperties");
query.setParameterList("ids", taskInstanceIds);
query.setCacheMode(CacheMode.PUT);
query.setFlushMode(FlushMode.MANUAL);
query.setCacheable(true);
List<TaskInstance> results = (List<TaskInstance>) query.list();
for (TaskInstance taskInstance : results)
{
returnMap.put(taskInstance.getId(), taskInstance);
}
}
protected List<WorkflowTask> getWorkflowTasks(List<TaskInstance> tasks)
{
// convert tasks to appropriate service response format
@@ -2003,11 +1786,12 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
// create properties to set on task instance
Map<QName, Serializable> newProperties = new HashMap<QName, Serializable>(10);
if(properties!=null)
{
newProperties.putAll(properties);
}
Map<QName, Serializable> existingProperties = getTaskProperties(taskInstance, false, null);
Map<QName, Serializable> existingProperties = getTaskProperties(taskInstance, false);
if (add != null)
{
// add new associations
@@ -2419,10 +2203,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*
* @param instance task instance
* @param properties properties to set
* @param variablesCache cahce og context instance variables if any exists
*/
@SuppressWarnings("unchecked")
protected Map<QName, Serializable> getTaskProperties(TaskInstance instance, boolean localProperties, Map<Long, TokenVariableMap> variablesCache)
protected Map<QName, Serializable> getTaskProperties(TaskInstance instance, boolean localProperties)
{
// retrieve type definition for task
TypeDefinition taskDef = getFullTaskDefinition(instance);
@@ -2437,16 +2220,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
Token token = instance.getToken();
while (token != null)
{
TokenVariableMap varMap = null;
if (variablesCache != null && variablesCache.containsKey(context.getId()))
{
varMap = variablesCache.get(context.getId());
}
else
{
varMap = context.getTokenVariableMap(token);
}
TokenVariableMap varMap = context.getTokenVariableMap(token);
if (varMap != null)
{
Map<String, Object> tokenVars = varMap.getVariablesLocally();
@@ -2498,11 +2272,11 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
// map jBPM task instance collections to associations
Set<PooledActor> pooledActors = instance.getPooledActors();
Set pooledActors = instance.getPooledActors();
if (pooledActors != null)
{
List<NodeRef> pooledNodeRefs = new ArrayList<NodeRef>(pooledActors.size());
for (PooledActor pooledActor : pooledActors)
for (PooledActor pooledActor : (Set<PooledActor>)pooledActors)
{
NodeRef pooledNodeRef = null;
String pooledActorId = pooledActor.getActorId();
@@ -2732,7 +2506,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*/
protected void setDefaultTaskProperties(TaskInstance instance)
{
Map<QName, Serializable> existingValues = getTaskProperties(instance, true, null);
Map<QName, Serializable> existingValues = getTaskProperties(instance, true);
Map<QName, Serializable> defaultValues = new HashMap<QName, Serializable>();
// construct an anonymous type that flattens all mandatory aspects
@@ -2806,7 +2580,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*/
protected void setDefaultWorkflowProperties(TaskInstance startTask)
{
Map<QName, Serializable> taskProperties = getTaskProperties(startTask, true, null);
Map<QName, Serializable> taskProperties = getTaskProperties(startTask, true);
ContextInstance processContext = startTask.getContextInstance();
String workflowDescriptionName = mapQNameToName(WorkflowModel.PROP_WORKFLOW_DESCRIPTION);
@@ -2852,7 +2626,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
List<QName> missingProps = null;
// retrieve properties of task
Map<QName, Serializable> existingValues = getTaskProperties(instance, false, null);
Map<QName, Serializable> existingValues = getTaskProperties(instance, false);
// retrieve definition of task
ClassDefinition classDef = getFullTaskDefinition(instance);
@@ -3067,11 +2841,8 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*/
private QName mapNameToQName(String name)
{
QName qname = qNameCache.getNameToQName(name);
if (qname == null)
{
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as
// new scheme (i.e. } -> _)
QName qname = null;
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
String qnameStr = (name.indexOf('}') == -1) ? name.replaceFirst("_", ":") : name.replace("}", ":");
try
{
@@ -3080,8 +2851,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
catch(NamespaceException e)
{
qname = QName.createQName(name, this.namespaceService);
}
qNameCache.putNameToQName(name, qname);
}
return qname;
}
@@ -3095,21 +2864,14 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*/
private String mapQNameToName(QName name)
{
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as
// new scheme (i.e. } -> _)
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
// NOTE: Use new scheme
String cachedName = qNameCache.getQNameToName(name);
if (cachedName == null)
{
String nameStr = name.toPrefixString(this.namespaceService);
if (nameStr.indexOf('_') != -1 && nameStr.indexOf('_') < nameStr.indexOf(':'))
{
cachedName = nameStr.replace(':', '}');
}
cachedName = nameStr.replace(':', '_');
return nameStr.replace(':', '}');
}
qNameCache.putQNameToName(name, cachedName);
return cachedName;
return nameStr.replace(':', '_');
}
/**
@@ -3200,7 +2962,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
String type = getRealNode(node).getClass().getSimpleName();
// TODO: Is there a formal way of determing if task node?
boolean isTaskNode = type.equals("TaskNode");
@SuppressWarnings("rawtypes")
List<Transition> transitions = node.getLeavingTransitions();
List<WorkflowTransition> wfTransitions;
if (transitions != null)
@@ -3323,7 +3084,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
WorkflowPath path = createWorkflowPath(task.getToken());
WorkflowTaskState state = getWorkflowTaskState(task);
WorkflowTaskDefinition definition = createWorkflowTaskDefinition(task.getTask());
Map<QName, Serializable> properties = getTaskProperties(task, false, null);
Map<QName, Serializable> properties = getTaskProperties(task, false);
return factory.createTask(id, definition, name, null, null, state, path, properties);
}
@@ -3420,103 +3181,4 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
}
/**
* Basic cache implementation for performance improvement with mapping QNames and Names of properties.
*/
private class QNameCache
{
private Map<QName, String> mapQNameToNameCache;
private Map<String, QName> mapNameToQNameCache;
private ReentrantReadWriteLock qNameToNameLock = new ReentrantReadWriteLock();
private WriteLock qNameToNameWriteLock = qNameToNameLock.writeLock();
private ReadLock qNameToNameReadLock = qNameToNameLock.readLock();
private ReentrantReadWriteLock nameToQNameLock = new ReentrantReadWriteLock();
private WriteLock nameToQNameWriteLock = nameToQNameLock.writeLock();
private ReadLock nameToQNameReadLock = nameToQNameLock.readLock();
QNameCache()
{
mapQNameToNameCache = new HashMap<QName, String>();
mapNameToQNameCache = new HashMap<String, QName>();
}
String getQNameToName(QName qName)
{
qNameToNameReadLock.lock();
try
{
return mapQNameToNameCache.get(qName);
}
finally
{
qNameToNameReadLock.unlock();
}
}
void putQNameToName(QName qName, String name)
{
qNameToNameWriteLock.lock();
try
{
mapQNameToNameCache.put(qName, name);
}
finally
{
qNameToNameWriteLock.unlock();
}
}
QName getNameToQName(String name)
{
nameToQNameReadLock.lock();
try
{
return mapNameToQNameCache.get(name);
}
finally
{
nameToQNameReadLock.unlock();
}
}
void putNameToQName(String name, QName qName)
{
nameToQNameWriteLock.lock();
try
{
mapNameToQNameCache.put(name, qName);
}
finally
{
nameToQNameWriteLock.unlock();
}
}
void clear()
{
nameToQNameWriteLock.lock();
try
{
mapNameToQNameCache.clear();
}
finally
{
nameToQNameWriteLock.unlock();
}
qNameToNameWriteLock.lock();
try
{
mapQNameToNameCache.clear();
}
finally
{
qNameToNameWriteLock.unlock();
}
}
}
}

View File

@@ -1,239 +0,0 @@
package org.alfresco.repo.workflow.jbpm;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.workflow.BPMEngineRegistry;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.QName;
import org.hibernate.Query;
import org.hibernate.Session;
import org.jbpm.JbpmContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springmodules.workflow.jbpm31.JbpmCallback;
import org.springmodules.workflow.jbpm31.JbpmTemplate;
/**
* This test shows a performance benefit from a usage of direct queries
* instead of creating required classes like WorkflowTask in a loop with collecting
* required properties from different services.
*
* @author arsenyko
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:alfresco/application-context.xml" })
public class JBPMJunit4LoadTests
{
private static String WORKFLOW_NAME = "jbpm$wf:adhoc";
private static String WORKFLOW_NODE_NAME = "workflow-test-19243cbb-c58a-485e-bcd9-2e2be030dfb9.txt";
private static int WORKFLOW_COUNT = 2000;
@Autowired
protected ApplicationContext applicationContext;
protected ServiceRegistry serviceRegistry;
protected RetryingTransactionHelper retryingTransactionHelper;
protected NodeService nodeService;
protected WorkflowService workflowService;
protected FileFolderService fileFolderService;
protected JBPMEngine jbpmEngine;
protected AuthenticationComponent authenticationComponent;
private NodeRef companyHomeNodeRef;
@Before
public void setUp() throws Exception
{
serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
serviceRegistry.getAuthenticationService().authenticate("admin", "admin".toCharArray());
retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
fileFolderService = serviceRegistry.getFileFolderService();
workflowService = serviceRegistry.getWorkflowService();
nodeService = serviceRegistry.getNodeService();
BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
jbpmEngine = (JBPMEngine) registry.getWorkflowComponent("jbpm");
NodeRef storeRootNodeRef = nodeService.getRootNode(new StoreRef("workspace://SpacesStore"));
companyHomeNodeRef = serviceRegistry.getSearchService().selectNodes(storeRootNodeRef, "/app:company_home", null, serviceRegistry.getNamespaceService(), false).get(0);
System.out.println(" -------------- ");
createWorkflowStuff();
}
public void createWorkflowStuff() throws Exception
{
System.out.println(" [createWorkflowStuff] Started at " + new Date().toString());
NodeRef workflowNode = nodeService.getChildByName(companyHomeNodeRef, ContentModel.ASSOC_CONTAINS, WORKFLOW_NODE_NAME);
if (workflowNode == null)
{
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
@Override
public Void execute() throws Throwable
{
FileInfo fileInfo = fileFolderService.create(companyHomeNodeRef, WORKFLOW_NODE_NAME, ContentModel.TYPE_CONTENT);
ContentWriter writer = serviceRegistry.getContentService().getWriter(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
writer.setMimetype("text/plain");
writer.setEncoding("UTF-8");
writer.putContent("many workflows many workflows many workflows many workflows many workflows many workflows many workflows many workflows");
System.out.println(" [createWorkflowStuff] Workflow node '" + WORKFLOW_NODE_NAME + "' has been created");
//WorkflowDefinition wfDef = workflowService.getDefinitionByName(WORKFLOW_NAME);
WorkflowDefinition wfDef = jbpmEngine.getDefinitionByName(WORKFLOW_NAME);
long startTime = new Date().getTime();
for (Integer i = 0; i < WORKFLOW_COUNT; i++)
{
// We are creating workflows in usual way, but with new persistent objects.
// There is a some performance issue with sesssion.flash() in each iteration,
// but this was made to avoid a lot of changes in a logic related to org.alfresco.service.cmr.workflow.*
// classes.
workflowService.startWorkflow(wfDef.id, prepareWorkflowProperties(fileInfo.getNodeRef(), i.toString()));
// jbpmEngine.startWorkflow_ALF1787(wfDef.id, prepareWorkflowProperties(fileInfo.getNodeRef(), i.toString()));
}
long endTime = new Date().getTime();
System.out.println(" [createWorkflowStuff] Execution time (ms): " + (endTime - startTime));
return null;
}
};
retryingTransactionHelper.setMaxRetries(1);
retryingTransactionHelper.doInTransaction(callback);
System.out.println(" [createWorkflowStuff] Finished at " + new Date().toString());
}
else
{
System.out.println(" [createWorkflowStuff] Workflow node '" + WORKFLOW_NODE_NAME + "' already exists");
}
}
@SuppressWarnings("unchecked")
//@Test
public void testQuery1() throws Exception
{
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
@Override
public Void execute() throws Throwable
{
JbpmTemplate jbpmTemplate = (JbpmTemplate) applicationContext.getBean("jbpm_template");
List<Object[]> result = (List<Object[]>) jbpmTemplate.execute(new JbpmCallback()
{
public List<Object[]> doInJbpm(JbpmContext context)
{
Session session = context.getSession();
Query query = session.getNamedQuery("org.alfresco.repo.workflow.findTaskInstancesByActorId");
return query.setString("actorId", "admin").list();
}
});
for(Object[] ti : result)
{
System.out.println(Arrays.toString(ti));
}
System.out.println(result.size());
return null;
}
};
retryingTransactionHelper.setMaxRetries(1);
retryingTransactionHelper.doInTransaction(callback);
}
@Test
public void testGetAssignedTasks_NEW() throws Exception
{
final int RUN_COUNT = 7;
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
@Override
public Void execute() throws Throwable
{
Date beginTime = new Date();
System.out.println(" [testGetAssignedTasks_NEW] Started at " + beginTime.toString());
List<WorkflowTask> tasks = workflowService.getAssignedTasks("admin", WorkflowTaskState.IN_PROGRESS);
Date endTime = new Date();
System.out.println(" [testGetAssignedTasks_NEW] Retrieved tasks: " + tasks.size() + " in " + (endTime.getTime() - beginTime.getTime()) + " ms");
System.out.println(" [testGetAssignedTasks_NEW] Finished at " + endTime.toString());
return null;
}
};
retryingTransactionHelper.setMaxRetries(1);
for(int i=0; i<RUN_COUNT; i++)
{
retryingTransactionHelper.doInTransaction(callback);
}
}
/*
@Test
public void testGetAssignedTasks_OLD() throws Exception
{
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
@Override
public Void execute() throws Throwable
{
Date beginTime = new Date();
System.out.println(" [testGetAssignedTasks_OLD] Started at " + beginTime.toString());
List<WorkflowTask> tasks = jbpmEngine.getAssignedTasks_OLD("admin", WorkflowTaskState.IN_PROGRESS);
Date endTime = new Date();
System.out.println(" [testGetAssignedTasks_OLD] Retrieved tasks: " + tasks.size() + " in " + (endTime.getTime() - beginTime.getTime()) + " ms");
System.out.println(" [testGetAssignedTasks_OLD] Finished at " + new Date().toString());
return null;
}
};
retryingTransactionHelper.setMaxRetries(1);
retryingTransactionHelper.doInTransaction(callback);
}
*/
@After
public void tearDown() throws Exception
{
System.out.println(" -------------- ");
}
private Map<QName, Serializable> prepareWorkflowProperties(NodeRef nodeRef, String id)
{
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(WorkflowModel.ASSOC_PACKAGE, nodeRef);
parameters.put(WorkflowModel.ASSOC_ASSIGNEE, "admin");
parameters.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Test workflow '" + id + "'");
parameters.put(WorkflowModel.PROP_WORKFLOW_DEFINITION_NAME, "test_workflow_" + id);
return parameters;
}
}