Added tests to ensure multi-tenancy works and fixed several multi-tenancy issues in workflow.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30563 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
N Smith
2011-09-16 09:34:02 +00:00
parent 8e9f5be725
commit 6d46ef90ec
29 changed files with 1047 additions and 403 deletions

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.workflow.activiti;
import org.alfresco.repo.workflow.AbstractMultitenantWorkflowTest;
import org.alfresco.service.namespace.QName;
/**
* @author Nick Smith
* @since 4.0
*
*/
public class ActivitiMultitenantWorkflowTest extends AbstractMultitenantWorkflowTest
{
@Override
protected String getEngine()
{
return ActivitiConstants.ENGINE_ID;
}
@Override
protected String getTestDefinitionPath()
{
return "activiti/testTransaction.bpmn20.xml";
}
@Override
protected String getTestDefinitionKey()
{
return "activiti$testTask";
}
@Override
protected String getAdhocDefinitionKey()
{
return "activiti$activitiAdhoc";
}
}

View File

@@ -549,10 +549,8 @@ public class ActivitiTypeConverter
{
collectedVariables.putAll(variables);
}
boolean isActive = historicProcessInstance.getEndTime() == null;
return factory.createInstance(
id, definition, variables, isActive, startDate, endDate);
boolean isActive = endDate == null;
return factory.createInstance(id, definition, variables, isActive, startDate, endDate);
}
public WorkflowInstance convert(HistoricProcessInstance historicProcessInstance)

View File

@@ -435,7 +435,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
{
try
{
String key =factory.getProcessKey(workflowName);
String key =factory.getDomainProcessKey(workflowName);
ProcessDefinition definition = repoService.createProcessDefinitionQuery()
.processDefinitionKey(key)
.latestVersion()
@@ -918,7 +918,8 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
{
throw new IllegalAccessError("The process definition does not have an id!");
}
return idAttrib.getNodeValue();
String key = idAttrib.getNodeValue();
return factory.getDomainProcessKey(key);
}
finally
{

View File

@@ -72,12 +72,7 @@ public class AlfrescoBpmnParseListener implements BpmnParseListener
@Override
public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition)
{
processDefinition.addExecutionListener(ExecutionListener.EVENTNAME_START, processCreateListener);
if (tenantService.isEnabled())
{
String key = tenantService.getName(processDefinition.getKey());
processDefinition.setKey(key);
}
//NOOP
}
@Override
@@ -187,7 +182,15 @@ public class AlfrescoBpmnParseListener implements BpmnParseListener
@Override
public void parseRootElement(Element arg0, List<ProcessDefinitionEntity> arg1)
{
// Nothing to do here
for (ProcessDefinitionEntity processDefinition : arg1)
{
processDefinition.addExecutionListener(ExecutionListener.EVENTNAME_START, processCreateListener);
if (tenantService.isEnabled())
{
String key = tenantService.getName(processDefinition.getKey());
processDefinition.setKey(key);
}
}
}
@Override

View File

@@ -65,6 +65,9 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.collections.CollectionUtils;
import org.alfresco.util.collections.EntryTransformer;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
@@ -110,14 +113,13 @@ public class ActivitiPropertyConverter
Map<QName, PropertyDefinition> taskProperties = taskDef.getProperties();
Map<QName, AssociationDefinition> taskAssociations = taskDef.getAssociations();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
TaskService taskService = activitiUtil.getTaskService();
// Get all task variables including execution vars.
Map<String, Object> variables = taskService.getVariables(task.getId());
Map<String, Object> localVariables = taskService.getVariablesLocal(task.getId());
// Map the arbitrary properties
Map<String, Object> localVariables = taskService.getVariablesLocal(task.getId());
mapArbitraryProperties(variables, properties, localVariables, taskProperties, taskAssociations);
Map<QName, Serializable> properties =mapArbitraryProperties(variables, localVariables, taskProperties, taskAssociations);
// Map activiti task instance fields to properties
properties.put(WorkflowModel.PROP_TASK_ID, task.getId());
@@ -200,8 +202,6 @@ public class ActivitiPropertyConverter
Map<QName, PropertyDefinition> taskProperties = typeDefinition.getProperties();
Map<QName, AssociationDefinition> taskAssociations = typeDefinition.getAssociations();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
// Get the local task variables
Map<String, Object> localVariables = task.getVariablesLocal();
Map<String, Object> variables = null;
@@ -228,9 +228,8 @@ public class ActivitiPropertyConverter
// Only local variables should be used.
variables = localVariables;
}
// Map the arbitrary properties
mapArbitraryProperties(variables, properties, localVariables, taskProperties, taskAssociations);
Map<QName, Serializable> properties =mapArbitraryProperties(variables, localVariables, taskProperties, taskAssociations);
// Map activiti task instance fields to properties
properties.put(WorkflowModel.PROP_TASK_ID, task.getId());
@@ -255,19 +254,20 @@ public class ActivitiPropertyConverter
}
@SuppressWarnings("unchecked")
public Map<QName, Serializable> getTaskProperties(HistoricTaskInstance historicTask, Map<String,Object> variables)
public Map<QName, Serializable> getTaskProperties(HistoricTaskInstance historicTask, Map<String,Object> localVariables)
{
// Retrieve type definition for task, based on taskFormKey variable
String formKey = (String) variables.get(ActivitiConstants.PROP_TASK_FORM_KEY);
String formKey = (String) localVariables.get(ActivitiConstants.PROP_TASK_FORM_KEY);
TypeDefinition taskDef = typeManager.getFullTaskDefinition(formKey);
Map<QName, PropertyDefinition> taskProperties = taskDef.getProperties();
Map<QName, AssociationDefinition> taskAssociations = taskDef.getAssociations();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
Map<String, Object> allVariables = getHistoricProcessVariables(historicTask.getProcessInstanceId());
allVariables.putAll(localVariables);
// Map the arbitrary properties
mapArbitraryProperties(variables, properties, variables, taskProperties, taskAssociations);
Map<QName, Serializable> properties =mapArbitraryProperties(allVariables, localVariables, taskProperties, taskAssociations);
// Map activiti task instance fields to properties
properties.put(WorkflowModel.PROP_TASK_ID, historicTask.getId());
@@ -286,14 +286,14 @@ public class ActivitiPropertyConverter
// Be sure to fetch the outcome
String outcomeVarName = factory.mapQNameToName(WorkflowModel.PROP_OUTCOME);
if(variables.get(outcomeVarName) != null)
if(localVariables.get(outcomeVarName) != null)
{
properties.put(WorkflowModel.PROP_OUTCOME, (Serializable) variables.get(outcomeVarName));
properties.put(WorkflowModel.PROP_OUTCOME, (Serializable) localVariables.get(outcomeVarName));
}
// History of pooled actors is stored in task variable
List<NodeRef> pooledActors = new ArrayList<NodeRef>();
List<String> pooledActorRefIds = (List<String>) variables.get(ActivitiConstants.PROP_POOLED_ACTORS_HISTORY);
List<String> pooledActorRefIds = (List<String>) localVariables.get(ActivitiConstants.PROP_POOLED_ACTORS_HISTORY);
if(pooledActorRefIds != null)
{
for(String nodeId : pooledActorRefIds)
@@ -406,8 +406,6 @@ public class ActivitiPropertyConverter
public Map<QName, Serializable> getStartTaskProperties(HistoricProcessInstance historicProcessInstance, String taskDefId, boolean completed)
{
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
TypeDefinition taskDef = typeManager.getStartTaskDefinition(taskDefId);
Map<QName, PropertyDefinition> taskProperties = taskDef.getProperties();
Map<QName, AssociationDefinition> taskAssociations = taskDef.getAssociations();
@@ -415,7 +413,7 @@ public class ActivitiPropertyConverter
Map<String, Object> variables = getStartVariables(historicProcessInstance);
// Map all the properties
mapArbitraryProperties(variables, properties, variables, taskProperties, taskAssociations);
Map<QName, Serializable> properties =mapArbitraryProperties(variables, variables, taskProperties, taskAssociations);
// Map activiti task instance fields to properties
properties.put(WorkflowModel.PROP_TASK_ID, ActivitiConstants.START_TASK_PREFIX + historicProcessInstance.getId());
@@ -535,28 +533,31 @@ public class ActivitiPropertyConverter
return convertHistoricDetails(historicDetails);
}
private void mapArbitraryProperties(Map<String, Object> variables,
Map<QName, Serializable> properties,
Map<String, Object> localVariables,
Map<QName, PropertyDefinition> taskProperties,
Map<QName, AssociationDefinition> taskAssociations)
private Map<QName, Serializable> mapArbitraryProperties(Map<String, Object> variables,
final Map<String, Object> localVariables,
final Map<QName, PropertyDefinition> taskProperties,
final Map<QName, AssociationDefinition> taskAssociations)
{
// Map arbitrary task variables
for (Entry<String, Object> entry : variables.entrySet())
EntryTransformer<String, Object, QName, Serializable> transformer = new EntryTransformer<String, Object, QName, Serializable>()
{
String key = entry.getKey();
QName qname = factory.mapNameToQName(key);
// Add variable, only if part of task definition or locally defined
// on task
if (taskProperties.containsKey(qname)
|| taskAssociations.containsKey(qname)
|| localVariables.containsKey(key))
@Override
public Pair<QName, Serializable> apply(Entry<String, Object> entry)
{
Serializable value = convertPropertyValue(entry.getValue());
properties.put(qname, value);
String key = entry.getKey();
QName qname = factory.mapNameToQName(key);
// Add variable, only if part of task definition or locally defined
// on task
if (taskProperties.containsKey(qname)
|| taskAssociations.containsKey(qname)
|| localVariables.containsKey(key))
{
Serializable value = convertPropertyValue(entry.getValue());
return new Pair<QName, Serializable>(qname, value);
}
return null;
}
}
};
return CollectionUtils.transform(variables, transformer);
}
/**