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

@@ -2,8 +2,7 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
@@ -47,7 +46,8 @@
<property name="databaseSchemaUpdate" value="none" />
<property name="history" value="full" />
<!-- Job-executor will be enabled once the SchemaAvailableEvent has been fired -->
<!-- Job-executor will be enabled once the SchemaAvailableEvent has
been fired -->
<property name="jobExecutorActivate" value="false" />
<!-- Limit the visible beans in expressions -->
@@ -74,7 +74,8 @@
<entry key="services" value-ref="ServiceRegistry" />
</util:map>
<bean id="baseJavaDelegate" class="org.alfresco.repo.workflow.activiti.BaseJavaDelegate" abstract="true">
<bean id="baseJavaDelegate" class="org.alfresco.repo.workflow.activiti.BaseJavaDelegate"
abstract="true">
<property name="serviceRegistry" ref="ServiceRegistry" />
<property name="beanRegistry" ref="activitiBeanRegistry" />
</bean>
@@ -125,8 +126,7 @@
<!-- Activiti Base Property Handler -->
<bean id="activitiPropertyHandler"
class="org.alfresco.repo.workflow.AbstractWorkflowPropertyHandler"
depends-on="activitiWorkflowManager"
abstract="true">
depends-on="activitiWorkflowManager" abstract="true">
<property name="messageService" ref="messageService" />
<property name="nodeConverter" ref="activitiNodeConverter" />
<property name="registry" ref="activitiPropertyHandlerRegistry" />
@@ -180,7 +180,8 @@
<property name="services" ref="ServiceRegistry" />
</bean>
<bean id="activitiProcessCreateListener" class="org.alfresco.repo.workflow.activiti.listener.ProcessStartExecutionListener" />
<bean id="activitiProcessCreateListener"
class="org.alfresco.repo.workflow.activiti.listener.ProcessStartExecutionListener" />
<bean id="activitiRepositoryService" factory-bean="activitiProcessEngine"
factory-method="getRepositoryService" />
@@ -194,7 +195,8 @@
factory-method="getHistoryService" />
<!-- Starting job-executor, after SchemaAvailableEvent has been broadcasted -->
<bean id="activitiEngineInitializer" class="org.alfresco.repo.workflow.activiti.ActivitiEngineInitializer">
<bean id="activitiEngineInitializer"
class="org.alfresco.repo.workflow.activiti.ActivitiEngineInitializer">
<property name="processEngine" ref="activitiProcessEngine" />
<property name="workflowAdminService" ref="workflowAdminService" />
</bean>

View File

@@ -25,7 +25,6 @@
<property name="companyHomeStore" value="${spaces.store}" />
<property name="companyHomePath" value="/${spaces.company_home.childname}" />
<property name="unprotectedSearchService" ref="searchService" />
<property name="workflowAdminService" ref="workflowAdminService" />
</bean>
</beans>

View File

@@ -50,7 +50,10 @@ system.workflow.jbpm.config.location=classpath:org/alfresco/repo/workflow/jbpm/j
# workflow definitions from the getDefinitions and
# getAllDefinitions WorkflowService API but still allows
# any in-flight JBPM workflows to be completed.
system.workflow.jbpm.definitions.visible=false
system.workflow.engine.jbpm.definitions.visible=false
#Determines if Activiti definitions are visible
system.workflow.engine.activiti.definitions.visible=true
# Determines if the JBPM engine is enabled
system.workflow.engine.jbpm.enabled=true

View File

@@ -30,6 +30,7 @@
<property name="dictionaryService" ref="dictionaryService"/>
<property name="protectedNodeService" ref="NodeService"/>
<property name="services" ref="ServiceRegistry"/>
<property name="workflowAdminService" ref="workflowAdminService"/>
</bean>
<bean id="workflowPackageImpl" class="org.alfresco.repo.workflow.WorkflowPackageImpl">
@@ -66,19 +67,32 @@
<!-- -->
<!-- Workflow Admin Service Implementation -->
<!-- -->
<bean id="workflowAdminService" class="org.alfresco.repo.workflow.WorkflowAdminServiceImpl" >
<property name="activitiEngineEnabled">
<value>${system.workflow.engine.activiti.enabled}</value>
</property>
<property name="JBPMEngineEnabled">
<value>${system.workflow.engine.jbpm.enabled}</value>
</property>
<property name="JBPMWorkflowDefinitionsVisible">
<value>${system.workflow.jbpm.definitions.visible}</value>
<property name="workflowEngineConfigurations">
<list>
<!-- JbpmEngine configuration -->
<props>
<prop key="engineId">jbpm</prop>
<prop key="enabled">${system.workflow.engine.jbpm.enabled}</prop>
<prop key="visible">${system.workflow.engine.jbpm.definitions.visible}</prop>
</props>
<!-- ActivitiWorkflowEngine configuration -->
<props>
<prop key="engineId">activiti</prop>
<prop key="enabled">${system.workflow.engine.activiti.enabled}</prop>
<prop key="visible">${system.workflow.engine.activiti.definitions.visible}</prop>
</props>
</list>
</property>
</bean>
<!-- -->
<!-- Base Workflow Engine Status -->
<!-- -->
<bean id="baseWorkflowEngineStatus" class="org.alfresco.repo.workflow.WorkflowEngineStatus" abstract="true">
<property name="workflowAdminService" ref="workflowAdminService" />
</bean>
<!-- -->
<!-- Workflow Action -->
<!-- -->

View File

@@ -21,6 +21,7 @@ package org.alfresco.repo.invitation;
import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -33,8 +34,6 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.workflow.WorkflowAdminServiceImpl;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.Invitation.ResourceType;
import org.alfresco.service.cmr.invitation.InvitationSearchCriteria;
@@ -83,6 +82,8 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
public final static String USER_ONE_EMAIL = USER_ONE + "@alfrescotesting.com";
public final static String USER_TWO_EMAIL = USER_TWO + "@alfrescotesting.com";
private Collection<String> enabledEngines;
private Collection<String> visibleEngines;
/**
* Called during the transaction setup
*/
@@ -101,9 +102,8 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
this.startSendEmails = invitationServiceImpl.isSendEmails();
// Check both workflow engines are active.
assertTrue(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID));
assertTrue(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID));
this.enabledEngines = workflowAdminService.getEnabledEngines();
this.visibleEngines = workflowAdminService.getVisibleEngines();
invitationServiceImpl.setSendEmails(true);
@@ -150,11 +150,13 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri
@Override
protected void onTearDownInTransaction() throws Exception
{
// Make sure both workflow engines are enabled.
workflowAdminService.setActivitiEngineEnabled(true);
workflowAdminService.setJBPMEngineEnabled(true);
// Make sure both workflow engines are enabled.and visible
this.authenticationComponent.setSystemUserAsCurrentUser();
workflowAdminService.setEnabledEngines(enabledEngines);
workflowAdminService.setVisibleEngines(visibleEngines);
invitationServiceImpl.setSendEmails(startSendEmails);
siteService.deleteSite(SITE_SHORT_NAME_INVITE);
siteService.deleteSite(SITE_SHORT_NAME_RED);

View File

@@ -19,8 +19,20 @@
package org.alfresco.repo.invitation;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.NominatedInvitation;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.namespace.QName;
/**
* @author Nick Smith
@@ -29,16 +41,59 @@ import org.alfresco.service.cmr.invitation.Invitation;
*/
public class ActivitiInvitationServiceImplTests extends AbstractInvitationServiceImplTest
{
private WorkflowService workflowService;
public void testWorkflowTaskContainsProps()
{
Invitation.ResourceType resourceType = Invitation.ResourceType.WEB_SITE;
String resourceName = SITE_SHORT_NAME_INVITE;
String inviteeRole = SiteModel.SITE_COLLABORATOR;
String serverPath = "wibble";
String acceptUrl = "froob";
String rejectUrl = "marshmallow";
NominatedInvitation nomInvite = invitationService.inviteNominated(USER_ONE,
resourceType, resourceName, inviteeRole, serverPath, acceptUrl, rejectUrl);
WorkflowTask task = getTaskForInvitation(nomInvite);
Map<QName, Serializable> props = task.getProperties();
assertEquals(inviteeRole, props.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE));
assertEquals(nomInvite.getResourceDescription(), props.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_DESCRIPTION));
assertEquals(nomInvite.getResourceTitle(), props.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TITLE));
// Accept the invitation
invitationService.accept(nomInvite.getInviteId(), nomInvite.getTicket());
task = workflowService.getTaskById(task.getId());
props = task.getProperties();
assertEquals(inviteeRole, props.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE));
assertEquals(nomInvite.getResourceDescription(), props.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_DESCRIPTION));
assertEquals(nomInvite.getResourceTitle(), props.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TITLE));
}
private WorkflowTask getTaskForInvitation(Invitation invite)
{
String instanceId = invite.getInviteId();
List<WorkflowPath> paths = workflowService.getWorkflowPaths(instanceId);
assertEquals(1, paths.size());
WorkflowPath path = paths.get(0);
List<WorkflowTask> tasks = workflowService.getTasksForWorkflowPath(path.getId());
assertEquals(1, tasks.size());
WorkflowTask task = tasks.get(0);
return task;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
@Override
protected void onSetUpInTransaction() throws Exception
{
super.onSetUpInTransaction();
this.workflowService = (WorkflowService) applicationContext.getBean("WorkflowService");
// Add a few Jbpm invitations to check they dont' interfere with Activiti invitations.
workflowAdminService.setActivitiEngineEnabled(false);
workflowAdminService.setEnabledEngines(Arrays.asList(JBPMEngine.ENGINE_ID));
String invitee = USER_ONE;
Invitation.ResourceType resourceType = Invitation.ResourceType.WEB_SITE;
@@ -59,7 +114,6 @@ public class ActivitiInvitationServiceImplTests extends AbstractInvitationServic
resourceType, resourceName, inviteeRole);
// Disable Jbpm and enable Activiti
workflowAdminService.setJBPMEngineEnabled(false);
workflowAdminService.setActivitiEngineEnabled(true);
workflowAdminService.setEnabledEngines(Arrays.asList(ActivitiConstants.ENGINE_ID));
}
}

View File

@@ -19,7 +19,11 @@
package org.alfresco.repo.invitation;
import java.util.Arrays;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
import org.alfresco.service.cmr.invitation.Invitation;
/**
@@ -38,7 +42,7 @@ public class JbpmInvitationServiceImplTests extends AbstractInvitationServiceImp
super.onSetUpInTransaction();
// Add a few Jbpm invitations to check they dont' interfere with Activiti invitations.
workflowAdminService.setJBPMEngineEnabled(false);
workflowAdminService.setEnabledEngines(Arrays.asList(ActivitiConstants.ENGINE_ID));
String invitee = USER_ONE;
Invitation.ResourceType resourceType = Invitation.ResourceType.WEB_SITE;
@@ -59,7 +63,6 @@ public class JbpmInvitationServiceImplTests extends AbstractInvitationServiceImp
resourceType, resourceName, inviteeRole);
// Disable Jbpm and enable Activiti
workflowAdminService.setActivitiEngineEnabled(false);
workflowAdminService.setJBPMEngineEnabled(true);
workflowAdminService.setEnabledEngines(Arrays.asList(JBPMEngine.ENGINE_ID));
}
}

View File

@@ -138,6 +138,7 @@ public class MultiTDemoTest extends TestCase
public MultiTDemoTest()
{
super();
}

View File

@@ -0,0 +1,274 @@
/*
* 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;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.junit.Test;
/**
* @author Nick Smith
* @since 4.0
*
*/
public abstract class AbstractMultitenantWorkflowTest extends BaseSpringTest
{
private static final String XML = MimetypeMap.MIMETYPE_XML;
public static final String DEFAULT_ADMIN_PW = "admin";
private final static QName ADHOC_TASK = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "adhocTask");
private final String tenant1 = "wfMTTest1"+GUID.generate();
private final String tenant2 = "wfMTTest2"+GUID.generate();
private TenantAdminService tenantAdminService;
private TenantService tenantService;
private ServiceRegistry serviceRegistry;
private WorkflowService workflowService;
private PersonService personService;
private String user1;
private String user2;
private WorkflowTestHelper wfTestHelper;
@Test
public void testDeployWorkflow() throws Exception
{
// Run as User1 so tenant domain 1
AuthenticationUtil.setFullyAuthenticatedUser(user1);
List<WorkflowDefinition> allDefs = workflowService.getAllDefinitions();
int allDefsSize = allDefs.size();
List<WorkflowDefinition> defs = workflowService.getDefinitions();
int defsSize = defs.size();
String definitionKey = getTestDefinitionKey();
// Deploy to tenant1.
WorkflowDefinition definition = workflowService.getDefinitionByName(definitionKey);
assertNull(definition);
// Check definition was successfully deployed on tenant1.
definition = deployDefinition(getTestDefinitionPath());
assertNotNull(definition);
assertEquals(definitionKey, definition.getName());
assertNotNull(workflowService.getDefinitionById(definition.getId()));
assertNotNull(workflowService.getDefinitionByName(definitionKey));
assertEquals(defsSize + 1, workflowService.getDefinitions().size());
assertEquals(allDefsSize + 1, workflowService.getAllDefinitions().size());
// Switch to tenant2.
AuthenticationUtil.setFullyAuthenticatedUser(user2);
// Check definition not visible on tenant2.
try
{
assertNull(workflowService.getDefinitionById(definition.getId()));
fail("Should throw Exception here!");
}
catch (Exception e)
{
// NOOP
}
assertNull(workflowService.getDefinitionByName(definitionKey));
assertEquals(defsSize, workflowService.getDefinitions().size());
assertEquals(allDefsSize, workflowService.getAllDefinitions().size());
// Check can deploy same definition to tenant2.
assertNotNull(deployDefinition(getTestDefinitionPath()));
// Switch back to tenant1.
AuthenticationUtil.setFullyAuthenticatedUser(user1);
// Check the definition hasn't changed
WorkflowDefinition definitionByName = workflowService.getDefinitionByName(definitionKey);
assertEquals(definition.getId(), definitionByName.getId());
}
public void testQueryTasks() throws Exception
{
WorkflowTaskQuery query = new WorkflowTaskQuery();
query.setTaskName(ADHOC_TASK);
// Run as User1 so tenant domain 1
AuthenticationUtil.setFullyAuthenticatedUser(user1);
// Check no tasks to start with
List<WorkflowTask> tasks = workflowService.queryTasks(query);
assertEquals(0, tasks.size());
String adhocKey = getAdhocDefinitionKey();
WorkflowDefinition adhocDef1= workflowService.getDefinitionByName(adhocKey);
//Check Adhoc definition exists
assertNotNull(adhocDef1);
//Start Adhoc workflow on tenant1.
NodeRef assignee1 = personService.getPerson(user1);
NodeRef pckg1 = workflowService.createPackage(null);
Map<QName, Serializable> parameters1 = new HashMap<QName, Serializable>();
parameters1.put(WorkflowModel.ASSOC_PACKAGE, pckg1);
parameters1.put(WorkflowModel.ASSOC_ASSIGNEE, assignee1);
WorkflowPath path = workflowService.startWorkflow(adhocDef1.getId(), parameters1);
// End start task
String instanceId = path.getInstance().getId();
WorkflowTask startTask = workflowService.getStartTask(instanceId);
workflowService.endTask(startTask.getId(), null);
// Should have found the new task.
tasks = workflowService.queryTasks(query);
assertEquals(1, tasks.size());
//Switch to tenant2
AuthenticationUtil.setFullyAuthenticatedUser(user2);
// Tenant2 should not find the task
tasks = workflowService.queryTasks(query);
assertEquals(0, tasks.size());
//Start Adhoc workflow on tenant2.
WorkflowDefinition adhocDef2 = workflowService.getDefinitionByName(adhocKey);
NodeRef assignee2 = personService.getPerson(user2);
NodeRef pckg2 = workflowService.createPackage(null);
Map<QName, Serializable> parameters2 = new HashMap<QName, Serializable>();
parameters2.put(WorkflowModel.ASSOC_PACKAGE, pckg2);
parameters2.put(WorkflowModel.ASSOC_ASSIGNEE, assignee2);
WorkflowPath path2 = workflowService.startWorkflow(adhocDef2.getId(), parameters2);
String path2Id = path2.getId();
// End start task
String instanceId2 = path2.getInstance().getId();
WorkflowTask startTask2 = workflowService.getStartTask(instanceId2);
workflowService.endTask(startTask2.getId(), null);
// Tenant2 should find the new task
tasks = workflowService.queryTasks(query);
assertEquals(1, tasks.size());
assertEquals(path2Id, tasks.get(0).getPath().getId());
}
@SuppressWarnings("deprecation")
@Override
protected void onSetUpBeforeTransaction() throws Exception
{
super.onSetUpBeforeTransaction();
this.serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
this.tenantService= (TenantService) applicationContext.getBean("tenantService");
this.tenantAdminService= (TenantAdminService) applicationContext.getBean("tenantAdminService");
this.workflowService = serviceRegistry.getWorkflowService();
this.personService = serviceRegistry.getPersonService();
WorkflowAdminServiceImpl workflowAdminService = (WorkflowAdminServiceImpl)applicationContext.getBean(WorkflowAdminServiceImpl.NAME);
this.wfTestHelper = new WorkflowTestHelper(workflowAdminService, getEngine(), true);
AuthenticationUtil.clearCurrentSecurityContext();
this.user1 = createTenant(tenant1);
this.user2 = createTenant(tenant2);
}
private String createTenant(final String tenantDomain)
{
// create tenants (if not already created)
return AuthenticationUtil.runAsSystem(new RunAsWork<String>()
{
public String doWork() throws Exception
{
if (! tenantAdminService.existsTenant(tenantDomain))
{
//tenantAdminService.createTenant(tenantDomain, DEFAULT_ADMIN_PW.toCharArray(), ROOT_DIR + "/" + tenantDomain);
tenantAdminService.createTenant(tenantDomain, (DEFAULT_ADMIN_PW+" "+tenantDomain).toCharArray(), null); // use default root dir
}
return tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
}
});
}
@SuppressWarnings("deprecation")
@Override
protected void onTearDown() throws Exception
{
wfTestHelper.tearDown();
super.onTearDown();
WorkflowSuiteContextShutdownTest.closeContext();
}
protected WorkflowDefinition deployDefinition(String resource)
{
InputStream input = getInputStream(resource);
WorkflowDeployment deployment = workflowService.deployDefinition(getEngine(), input, XML);
WorkflowDefinition definition = deployment.getDefinition();
return definition;
}
private InputStream getInputStream(String resource)
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return classLoader.getResourceAsStream(resource);
}
/**
* {@inheritDoc}
*/
@Override
protected String[] getConfigLocations()
{
return new String[] {ApplicationContextHelper.CONFIG_LOCATIONS[0],
"classpath:tenant/mt-*context.xml"};
}
protected abstract String getTestDefinitionPath();
protected abstract String getTestDefinitionKey();
protected abstract String getAdhocDefinitionKey();
protected abstract String getEngine();
}

View File

@@ -79,8 +79,8 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
protected TestPersonManager personManager;
protected TestGroupManager groupManager;
protected NodeService nodeService;
protected WorkflowAdminServiceImpl workflowAdminService;
private NodeRef companyHome;
protected WorkflowTestHelper wfTestHelper;
public void testDeployWorkflowDefinition()
{
@@ -104,6 +104,20 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
// Check getDefinitionByName().
WorkflowDefinition defByName = workflowService.getDefinitionByName(definition.getName());
checkDefinition(definition, defByName);
//Disable all other workflow engines
wfTestHelper.enableThisEngineOnly();
// Check contains some definitions.
assertFalse(workflowService.getDefinitions().isEmpty());
assertFalse(workflowService.getAllDefinitions().isEmpty());
// turn off workflow definition visibility
wfTestHelper.setVisible(false);
// ensure the list of workflow definitions are empty
assertTrue(workflowService.getDefinitions().isEmpty());
assertTrue(workflowService.getAllDefinitions().isEmpty());
}
public void testStartWorkflow()
@@ -1048,8 +1062,7 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
private InputStream getInputStream(String resource)
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input= classLoader.getResourceAsStream(resource);
return input;
return classLoader.getResourceAsStream(resource);
}
private void checkDefinitions(WorkflowDefinition expDefinition, boolean expContainsDef, WorkflowDefinition... definitions)
@@ -1138,6 +1151,7 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
@Override
protected void onSetUpInTransaction() throws Exception
{
super.onSetUpInTransaction();
ServiceRegistry registry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
this.workflowService = registry.getWorkflowService();
this.authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
@@ -1152,9 +1166,8 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
authenticationComponent.setSystemUserAsCurrentUser();
// for the purposes of the tests make sure JBPM workflow definitions are visible
this.workflowAdminService = (WorkflowAdminServiceImpl) applicationContext.getBean("workflowAdminService");
this.workflowAdminService.setJBPMWorkflowDefinitionsVisible(true);
WorkflowAdminServiceImpl workflowAdminService = (WorkflowAdminServiceImpl) applicationContext.getBean(WorkflowAdminServiceImpl.NAME);
this.wfTestHelper = new WorkflowTestHelper(workflowAdminService, getEngine(), true);
// create test users
this.personManager = new TestPersonManager(authenticationService, personService, nodeService);
@@ -1178,12 +1191,13 @@ public abstract class AbstractWorkflowServiceIntegrationTest extends BaseSpringT
@Override
protected void onTearDownInTransaction() throws Exception
{
super.onTearDownInTransaction();
wfTestHelper.tearDown();
authenticationComponent.setSystemUserAsCurrentUser();
groupManager.clearGroups();
personManager.clearPeople();
authenticationComponent.clearCurrentSecurityContext();
super.onTearDownInTransaction();
}
protected abstract String getEngine();

View File

@@ -19,10 +19,14 @@
package org.alfresco.repo.workflow;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.util.collections.CollectionUtils;
import org.alfresco.util.collections.Filter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -83,20 +87,10 @@ public class BPMEngineRegistry
{
throw new WorkflowException("Workflow Component already registered for engine id '" + engineId + "'");
}
if (workflowAdminService.isEngineEnabled(engineId))
{
workflowComponents.put(engineId, engine);
if (logger.isDebugEnabled())
logger.debug("Registered Workflow Component '" + engineId + "' (" + engine.getClass() + ")");
}
else
{
if (logger.isWarnEnabled())
logger.warn("Ignoring Workflow Component '" + engineId + "' (" + engine.getClass() + ") as the engine is disabled");
}
}
/**
* Gets all registered Workflow Components
@@ -105,7 +99,7 @@ public class BPMEngineRegistry
*/
public String[] getWorkflowComponents()
{
return workflowComponents.keySet().toArray(new String[workflowComponents.keySet().size()]);
return getComponents(workflowComponents.keySet());
}
/**
@@ -116,6 +110,14 @@ public class BPMEngineRegistry
*/
public WorkflowComponent getWorkflowComponent(String engineId)
{
if(false == workflowAdminService.isEngineEnabled(engineId))
{
if(logger.isDebugEnabled())
{
logger.debug("Ignoring disabled WorkflowComponent: "+engineId);
}
return null;
}
return workflowComponents.get(engineId);
}
@@ -131,20 +133,10 @@ public class BPMEngineRegistry
{
throw new WorkflowException("Task Component already registered for engine id '" + engineId + "'");
}
if (workflowAdminService.isEngineEnabled(engineId))
{
taskComponents.put(engineId, engine);
if (logger.isDebugEnabled())
logger.debug("Registered Task Component '" + engineId + "' (" + engine.getClass() + ")");
}
else
{
if (logger.isWarnEnabled())
logger.warn("Ignoring Task Component '" + engineId + "' (" + engine.getClass() + ") as the engine is disabled");
}
}
/**
* Gets all registered Task Components
@@ -153,7 +145,19 @@ public class BPMEngineRegistry
*/
public String[] getTaskComponents()
{
return taskComponents.keySet().toArray(new String[taskComponents.keySet().size()]);
return getComponents(taskComponents.keySet());
}
private String[] getComponents(Set<String> components)
{
List<String> filtered = CollectionUtils.filter(components, new Filter<String>()
{
public Boolean apply(String engineId)
{
return workflowAdminService.isEngineEnabled(engineId);
}
});
return filtered.toArray(new String[filtered.size()]);
}
/**
@@ -164,6 +168,14 @@ public class BPMEngineRegistry
*/
public TaskComponent getTaskComponent(String engineId)
{
if(false == workflowAdminService.isEngineEnabled(engineId))
{
if(logger.isDebugEnabled())
{
logger.debug("Ignoring disabled TaskComponent: "+engineId);
}
return null;
}
return taskComponents.get(engineId);
}

View File

@@ -18,60 +18,126 @@
*/
package org.alfresco.repo.workflow;
import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.repo.workflow.jbpm.JBPMEngine;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.alfresco.service.cmr.workflow.WorkflowAdminService;
/**
* Default implementation of the workflow admin service.
*
* @author Gavin Cornwell
* @author Nick Smith
* @since 4.0
*/
public class WorkflowAdminServiceImpl implements WorkflowAdminService
{
public static final String NAME = "workflowAdminService";
public static final String ENGINE = "engineId";
public static final String ENABLED = "enabled";
public static final String VISIBLE = "visible";
private boolean activitiEngineEnabled = true;
private boolean jbpmEngineEnabled = true;
private boolean jbpmDefinitionsVisible = false;
private Set<String> enabledEngines = new HashSet<String>();
private Set<String> visibleEngines = new HashSet<String>();
public void setActivitiEngineEnabled(boolean activitiEngineEnabled)
{
this.activitiEngineEnabled = activitiEngineEnabled;
}
public void setJBPMEngineEnabled(boolean jbpmEngineEnabled)
{
this.jbpmEngineEnabled = jbpmEngineEnabled;
}
public void setJBPMWorkflowDefinitionsVisible(boolean jbpmDefinitionsVisible)
{
this.jbpmDefinitionsVisible = jbpmDefinitionsVisible;
}
@Override
public boolean isJBPMWorkflowDefinitionsVisible()
{
return this.jbpmDefinitionsVisible;
}
@Override
/**
* {@inheritDoc}
*/
public boolean isEngineEnabled(String engineId)
{
if (JBPMEngine.ENGINE_ID.equals(engineId))
{
return jbpmEngineEnabled;
return enabledEngines.contains(engineId);
}
else if (ActivitiConstants.ENGINE_ID.equals(engineId))
public void setEngineEnabled(String engineId, boolean isEnabled)
{
return activitiEngineEnabled;
if(isEnabled)
{
enabledEngines.add(engineId);
}
else
{
// if the engine id is not recognised it can't be enabled!
return false;
enabledEngines.remove(engineId);
}
}
public boolean isEngineVisible(String engineId)
{
return isEngineEnabled(engineId) && visibleEngines.contains(engineId);
}
public void setEngineVisibility(String engineId, boolean isVisible)
{
if(isVisible)
{
visibleEngines.add(engineId);
}
else
{
visibleEngines.remove(engineId);
}
}
/**
* Setter for Spring
* @param engines All engine Ids to enable.
*/
public void setEnabledEngines(Collection<String> engines)
{
if(false == enabledEngines.isEmpty())
{
enabledEngines.clear();
}
enabledEngines.addAll(engines);
}
/**
* @return the enabledEngines
*/
public Set<String> getEnabledEngines()
{
return new HashSet<String>(enabledEngines);
}
/**
* Setter for Spring.
* @param engines All engineIds to set visible.
*/
public void setVisibleEngines(Collection<String> engines)
{
if(false == visibleEngines.isEmpty())
{
visibleEngines.clear();
}
visibleEngines.addAll(engines);
}
/**
* @return the visibleEngines
*/
public Set<String> getVisibleEngines()
{
return new HashSet<String>(visibleEngines);
}
public void setWorkflowEngineConfigurations(List<Properties> props)
{
for (Properties prop : props)
{
String engineId = prop.getProperty(ENGINE);
String isEnabled = (String) prop.get(ENABLED);
if(isEnabled!=null)
{
setEngineEnabled(engineId, Boolean.valueOf(isEnabled));
}
String isVisible = (String) prop.get(VISIBLE);
if(isVisible!=null)
{
setEngineVisibility(engineId, Boolean.valueOf(isVisible));
}
}
}
}

View File

@@ -20,6 +20,7 @@
package org.alfresco.repo.workflow;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -118,6 +119,7 @@ public class WorkflowObjectFactory
WorkflowTaskDefinition startTaskDef)
{
checkDomain(defName);
String actualDefName = buildGlobalId(tenantService.getBaseName(defName));
String actualId = buildGlobalId(defId);
String actualVersion = Integer.toString(version);
@@ -126,7 +128,7 @@ public class WorkflowObjectFactory
String title = getLabel(displayId, TITLE_LABEL, defaultTitle);
String description = getLabel(displayId, DESC_LABEL, defaultDescription, title);
return new WorkflowDefinition(
actualId, buildGlobalId(defName), actualVersion, title, description, startTaskDef);
actualId, actualDefName, actualVersion, title, description, startTaskDef);
}
public String getWorkflowDefinitionName(String defName)
@@ -140,7 +142,6 @@ public class WorkflowObjectFactory
WorkflowDefinition definition, Map<String, Object> variables,
boolean isActive, Date startDate, Date endDate)
{
checkDomain(definition.getName());
String actualId = buildGlobalId(id);
String description = (String) getVariable(variables, WorkflowModel.PROP_WORKFLOW_DESCRIPTION);
@@ -209,13 +210,12 @@ public class WorkflowObjectFactory
Map<QName, Serializable> properties)
{
String defName = path.getInstance().getDefinition().getName();
checkDomain(defName);
String actualId = buildGlobalId(id);
String displayId = getProcessKey(defName) + ".task." + name;
String processKey = getProcessKey(defName) + ".task." + name;
TypeDefinition metadata = taskDef.getMetadata();
String title = getLabel(displayId, TITLE_LABEL, defaultTitle, metadata.getTitle(), name);
String description = getLabel(displayId, DESC_LABEL, defaultDescription, metadata.getDescription(), title);
String title = getLabel(processKey, TITLE_LABEL, defaultTitle, metadata.getTitle(), name);
String description = getLabel(processKey, DESC_LABEL, defaultDescription, metadata.getDescription(), title);
return new WorkflowTask(actualId,
taskDef, name, title, description,
state, path, properties);
@@ -238,6 +238,16 @@ public class WorkflowObjectFactory
return tenantService.getBaseName(processKey);
}
public String getDomainProcessKey(String defName)
{
String processKey = defName;
if (isGlobalId(defName))
{
processKey = getLocalEngineId(defName);
}
return tenantService.getName(processKey);
}
public String getTaskTitle(TypeDefinition typeDefinition, String defName, String defaultTitle, String name)
{
String displayId = getProcessKey(defName) + ".task." + name;
@@ -321,7 +331,7 @@ public class WorkflowObjectFactory
}
}
public <T extends Object> List<T> filterByDomain(List<T> values, final Function<T, String> processKeyGetter)
public <T extends Object> List<T> filterByDomain(Collection<T> values, final Function<T, String> processKeyGetter)
{
final boolean enabled = tenantService.isEnabled();
final String currentDomain = tenantService.getCurrentUserDomain();
@@ -331,15 +341,18 @@ public class WorkflowObjectFactory
{
String key = processKeyGetter.apply(value);
String domain = MultiTServiceImpl.getMultiTenantDomainName(key);
if(enabled && false == currentDomain.equals(domain))
if(enabled)
{
return false; // The domains do not match so ignore.
}
else if(domain!=null)
if(currentDomain.equals(domain))
{
return false; // Ignore domain-specific definitions
return true; // The domains match so include.
}
return true;
}
else if(domain==null)
{
return true; // In single-tenant mode only return items with no domain.
}
return false;
}
});
}

View File

@@ -43,6 +43,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowException;
@@ -79,6 +80,7 @@ public class WorkflowServiceImpl implements WorkflowService
private DictionaryService dictionaryService;
private NodeService protectedNodeService;
private ServiceRegistry services;
private WorkflowAdminService workflowAdminService;
/**
* Sets the Authority Service
@@ -100,6 +102,14 @@ public class WorkflowServiceImpl implements WorkflowService
this.registry = registry;
}
/**
* @param workflowAdminService the workflowAdminService to set
*/
public void setWorkflowAdminService(WorkflowAdminService workflowAdminService)
{
this.workflowAdminService = workflowAdminService;
}
/**
* Sets the Workflow Package Component
*
@@ -273,10 +283,13 @@ public class WorkflowServiceImpl implements WorkflowService
List<WorkflowDefinition> definitions = new ArrayList<WorkflowDefinition>(10);
String[] ids = registry.getWorkflowComponents();
for (String id : ids)
{
if(workflowAdminService.isEngineVisible(id))
{
WorkflowComponent component = registry.getWorkflowComponent(id);
definitions.addAll(component.getDefinitions());
}
}
return Collections.unmodifiableList(definitions);
}
@@ -290,10 +303,13 @@ public class WorkflowServiceImpl implements WorkflowService
List<WorkflowDefinition> definitions = new ArrayList<WorkflowDefinition>(10);
String[] ids = registry.getWorkflowComponents();
for (String id : ids)
{
if(workflowAdminService.isEngineVisible(id))
{
WorkflowComponent component = registry.getWorkflowComponent(id);
definitions.addAll(component.getAllDefinitions());
}
}
return Collections.unmodifiableList(definitions);
}

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;
import java.lang.reflect.Field;
import junit.framework.TestCase;
import org.alfresco.repo.workflow.jbpm.WorkflowTaskInstance;
import org.alfresco.util.ApplicationContextHelper;
public class WorkflowSuiteContextShutdownTest extends TestCase
{
public void testDummy() { /*Do Nothing */ }
@Override
protected void tearDown() throws Exception
{
System.err.println("Workflow test suite has completed, shutting down the ApplicationContext...");
closeContext();
System.err.println("Workflow test suite shutdown has finished");
}
public static void closeContext() throws NoSuchFieldException, IllegalAccessException, InterruptedException
{
ApplicationContextHelper.closeApplicationContext();
// Null out the static Workflow engine field
Field engineField = WorkflowTaskInstance.class.getDeclaredField("jbpmEngine");
engineField.setAccessible(true);
engineField.set(null, null);
Thread.yield();
Thread.sleep(25);
Thread.yield();
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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;
import java.util.Arrays;
import java.util.Set;
/**
* @author Nick Smith
* @since 4.0
*
*/
public class WorkflowTestHelper
{
private final WorkflowAdminServiceImpl workflowAdminService;
private final String engineId;
private final Set<String> enabledEngines;
private final Set<String> visibleEngines;
public WorkflowTestHelper(WorkflowAdminServiceImpl workflowAdminService, String engineId, boolean enableEngineOnly)
{
this.workflowAdminService = workflowAdminService;
this.engineId = engineId;
this.enabledEngines = workflowAdminService.getEnabledEngines();
this.visibleEngines = workflowAdminService.getVisibleEngines();
if(enableEngineOnly)
{
enableThisEngineOnly();
}
}
public void enableThisEngineOnly()
{
workflowAdminService.setEnabledEngines(Arrays.asList(engineId));
workflowAdminService.setVisibleEngines(Arrays.asList(engineId));
}
public void tearDown()
{
workflowAdminService.setEnabledEngines(enabledEngines);
workflowAdminService.setVisibleEngines(visibleEngines);
}
public void setVisible(boolean isVisible)
{
workflowAdminService.setEngineVisibility(engineId, isVisible);
}
public void setEnabled(boolean isEnabled)
{
workflowAdminService.setEngineEnabled(engineId, isEnabled);
}
}

View File

@@ -18,20 +18,19 @@
*/
package org.alfresco.repo.workflow;
import java.lang.reflect.Field;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.alfresco.repo.workflow.activiti.ActivitiMultitenantWorkflowTest;
import org.alfresco.repo.workflow.activiti.ActivitiSpringTransactionTest;
import org.alfresco.repo.workflow.activiti.ActivitiWorkflowServiceIntegrationTest;
import org.alfresco.repo.workflow.jbpm.AlfrescoJavaScriptIntegrationTest;
import org.alfresco.repo.workflow.jbpm.JBPMEngineTest;
import org.alfresco.repo.workflow.jbpm.JBPMSpringTest;
import org.alfresco.repo.workflow.jbpm.JbpmMultitenantWorkflowTest;
import org.alfresco.repo.workflow.jbpm.JbpmWorkflowServiceIntegrationTest;
import org.alfresco.repo.workflow.jbpm.ReviewAndApproveTest;
import org.alfresco.repo.workflow.jbpm.WorkflowTaskInstance;
import org.alfresco.util.ApplicationContextHelper;
/**
@@ -68,6 +67,10 @@ public class WorkflowTestSuite extends TestSuite
// periodic wierd build failures
suite.addTestSuite( WorkflowSuiteContextShutdownTest.class );
// These tests use a different Spring config.
suite.addTestSuite( ActivitiMultitenantWorkflowTest.class );
suite.addTestSuite( JbpmMultitenantWorkflowTest.class );
// Note the following workflow tests are not included in this sutie:
// ActivitiTaskComponentTest
// ActivitiWorkflowComponentTest
@@ -75,27 +78,4 @@ public class WorkflowTestSuite extends TestSuite
// JbpmWorkflowRestApiTest
return suite;
}
public static class WorkflowSuiteContextShutdownTest extends TestCase
{
public void testDummy() { /*Do Nothing */ }
@Override
protected void tearDown() throws Exception
{
System.err.println("Workflow test suite has completed, shutting down the ApplicationContext...");
ApplicationContextHelper.closeApplicationContext();
// Null out the static Workflow engine field
Field engineField = WorkflowTaskInstance.class.getDeclaredField("jbpmEngine");
engineField.setAccessible(true);
engineField.set(null, null);
Thread.yield();
Thread.sleep(25);
Thread.yield();
System.err.println("Workflow test suite shutdown has finished");
}
}
}

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,18 +533,18 @@ 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>()
{
@Override
public Pair<QName, Serializable> apply(Entry<String, Object> entry)
{
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)
@@ -554,9 +552,12 @@ public class ActivitiPropertyConverter
|| localVariables.containsKey(key))
{
Serializable value = convertPropertyValue(entry.getValue());
properties.put(qname, value);
return new Pair<QName, Serializable>(qname, value);
}
return null;
}
};
return CollectionUtils.transform(variables, transformer);
}
/**

View File

@@ -54,7 +54,6 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowException;
@@ -70,6 +69,8 @@ import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.collections.CollectionUtils;
import org.alfresco.util.collections.Function;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
@@ -127,7 +128,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
protected AuthorityDAO authorityDAO;
protected JbpmTemplate jbpmTemplate;
protected SearchService unprotectedSearchService;
protected WorkflowAdminService workflowAdminService;
// Company Home
protected StoreRef companyHomeStore;
@@ -283,16 +283,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
this.unprotectedSearchService = unprotectedSearchService;
}
/**
* Sets the Workflow Admin Service
*
* @param workflowAdminService
*/
public void setWorkflowAdminService(WorkflowAdminService workflowAdminService)
{
this.workflowAdminService = workflowAdminService;
}
//
// Workflow Definition...
//
@@ -355,9 +345,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
// retrieve process definition from Alfresco Repository
GraphSession graphSession = context.getGraphSession();
ProcessDefinition existingDefinition = graphSession
.findLatestProcessDefinition(processDefinition.def.getName());
return (existingDefinition == null) ? false : true;
String definitionName = processDefinition.def.getName();
ProcessDefinition existingDefinition = graphSession.findLatestProcessDefinition(definitionName);
return existingDefinition != null;
}
});
}
@@ -405,16 +395,11 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
}
/*
* (non-Javadoc)
*
* @see
* org.alfresco.repo.workflow.WorkflowDefinitionComponent#getDefinitions()
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public List<WorkflowDefinition> getDefinitions()
{
if (workflowAdminService.isJBPMWorkflowDefinitionsVisible())
{
try
{
@@ -424,27 +409,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
GraphSession graphSession = context.getGraphSession();
List<ProcessDefinition> processDefs = graphSession.findLatestProcessDefinitions();
List<WorkflowDefinition> workflowDefs = new ArrayList<WorkflowDefinition>(processDefs.size());
for (ProcessDefinition processDef : processDefs)
{
if (tenantService.isEnabled())
{
try
{
tenantService.checkDomain(processDef.getName());
}
catch (RuntimeException re)
{
// deliberately skip this one - due to domain
// mismatch
continue;
}
}
WorkflowDefinition workflowDef = createWorkflowDefinition(processDef);
workflowDefs.add(workflowDef);
}
return workflowDefs;
return getValidDefinitions(processDefs);
}
});
}
@@ -454,10 +419,28 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
throw new WorkflowException(msg, e);
}
}
else
private List<WorkflowDefinition> getValidDefinitions(Collection<ProcessDefinition> definitions)
{
return Collections.<WorkflowDefinition>emptyList();
List<ProcessDefinition> filteredDefs = factory.filterByDomain(definitions, new Function<ProcessDefinition, String>()
{
public String apply(ProcessDefinition definition)
{
return definition.getName();
}
});
return convertDefinitions(filteredDefs);
}
private List<WorkflowDefinition> convertDefinitions(Collection<ProcessDefinition> definitions)
{
return CollectionUtils.transform(definitions, new Function<ProcessDefinition, WorkflowDefinition>()
{
public WorkflowDefinition apply(ProcessDefinition value)
{
return createWorkflowDefinition(value);
}
});
}
/*
@@ -468,8 +451,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
*/
@SuppressWarnings("unchecked")
public List<WorkflowDefinition> getAllDefinitions()
{
if (workflowAdminService.isJBPMWorkflowDefinitionsVisible())
{
try
{
@@ -479,27 +460,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
GraphSession graphSession = context.getGraphSession();
List<ProcessDefinition> processDefs = graphSession.findAllProcessDefinitions();
List<WorkflowDefinition> workflowDefs = new ArrayList<WorkflowDefinition>(processDefs.size());
for (ProcessDefinition processDef : processDefs)
{
if (tenantService.isEnabled())
{
try
{
tenantService.checkDomain(processDef.getName());
}
catch (RuntimeException re)
{
// deliberately skip this one - due to domain
// mismatch
continue;
}
}
WorkflowDefinition workflowDef = createWorkflowDefinition(processDef);
workflowDefs.add(workflowDef);
}
return workflowDefs;
return getValidDefinitions(processDefs);
}
});
}
@@ -509,11 +470,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
throw new WorkflowException(msg, e);
}
}
else
{
return Collections.<WorkflowDefinition>emptyList();
}
}
/*
* (non-Javadoc)
@@ -533,7 +489,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
// retrieve process
GraphSession graphSession = context.getGraphSession();
ProcessDefinition processDefinition = getProcessDefinition(graphSession, workflowDefinitionId);
return processDefinition == null ? null : createWorkflowDefinition(processDefinition);
return createWorkflowDefinition(processDefinition);
}
});
}
@@ -557,12 +513,11 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
return (WorkflowDefinition)jbpmTemplate.execute(new JbpmCallback()
{
@SuppressWarnings("synthetic-access")
public Object doInJbpm(JbpmContext context)
{
GraphSession graphSession = context.getGraphSession();
ProcessDefinition processDef = graphSession.findLatestProcessDefinition(tenantService
.getName(createLocalId(workflowName)));
String definitionName = tenantService.getName(createLocalId(workflowName));
ProcessDefinition processDef = graphSession.findLatestProcessDefinition(definitionName);
return processDef == null ? null : createWorkflowDefinition(processDef);
}
});
@@ -592,15 +547,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
public Object doInJbpm(JbpmContext context)
{
GraphSession graphSession = context.getGraphSession();
List<ProcessDefinition> processDefs = graphSession.findAllProcessDefinitionVersions(tenantService
.getName(createLocalId(workflowName)));
List<WorkflowDefinition> workflowDefs = new ArrayList<WorkflowDefinition>(processDefs.size());
for (ProcessDefinition processDef : processDefs)
{
WorkflowDefinition workflowDef = createWorkflowDefinition(processDef);
workflowDefs.add(workflowDef);
}
return workflowDefs;
String definitionName = tenantService.getName(createLocalId(workflowName));
List<ProcessDefinition> processDefs = graphSession.findAllProcessDefinitionVersions(definitionName);
return convertDefinitions(processDefs);
}
});
}
@@ -1624,6 +1573,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
{
@SuppressWarnings("deprecation")
public List<WorkflowTask> doInJbpm(JbpmContext context)
{
Session session = context.getSession();
@@ -1632,12 +1582,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
{
query.setProcessName(tenantService.getName(query.getProcessName()));
}
if ((query.getWorkflowDefinitionName() != null) && (tenantService.isEnabled()))
{
query.setWorkflowDefinitionName(tenantService.getName(query.getWorkflowDefinitionName()));
}
Criteria criteria = createTaskQueryCriteria(session, query);
List<TaskInstance> tasks = criteria.list();
return getWorkflowTasks(tasks);
@@ -1932,42 +1876,22 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
process.add(Restrictions.eq("id", getJbpmId(query.getProcessId())));
}
// process name
if (query.getProcessName() != null)
// process definition name
String definitionName = query.getWorkflowDefinitionName();
if(definitionName!=null)
{
definitionName = createLocalId(definitionName);
}
if(definitionName == null)
{
QName qName = query.getProcessName();
definitionName= qName == null ? null : qName.toPrefixString(namespaceService);
}
if (definitionName != null)
{
process = (process == null) ? root.createCriteria("processInstance") : process;
Criteria processDef = process.createCriteria("processDefinition");
String processName = null;
if (tenantService.isEnabled())
{
QName baseProcessName = tenantService.getBaseName(query.getProcessName(), true);
processName = tenantService.getName(baseProcessName.toPrefixString(namespaceService));
}
else
{
processName = query.getProcessName().toPrefixString(namespaceService);
}
processDef.add(Restrictions.eq("name", processName));
}
// Process definition name
if (query.getWorkflowDefinitionName() != null)
{
process = (process == null) ? root.createCriteria("processInstance") : process;
Criteria processDef = process.createCriteria("processDefinition");
String processName = null;
if (tenantService.isEnabled())
{
String baseProcessName = tenantService.getBaseName(query.getWorkflowDefinitionName(), true);
processName = tenantService.getName(baseProcessName);
}
else
{
processName = query.getWorkflowDefinitionName();
}
String processName = tenantService.getName(definitionName);
processDef.add(Restrictions.eq("name", processName));
}

View File

@@ -32,13 +32,11 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.workflow.BPMEngineRegistry;
import org.alfresco.repo.workflow.TaskComponent;
import org.alfresco.repo.workflow.WorkflowAdminServiceImpl;
import org.alfresco.repo.workflow.WorkflowComponent;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.repo.workflow.WorkflowPackageComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowAdminService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowException;
@@ -70,7 +68,6 @@ public class JBPMEngineTest extends BaseAlfrescoSpringTest
private WorkflowPackageComponent packageComponent;
private PersonService personService;
private WorkflowDefinition testWorkflowDef;
private WorkflowAdminServiceImpl workflowAdminService;
private NodeRef person1;
private NodeRef person2;
private NodeRef person3;
@@ -91,10 +88,6 @@ public class JBPMEngineTest extends BaseAlfrescoSpringTest
taskComponent = registry.getTaskComponent(JBPMEngine.ENGINE_ID);
packageComponent = (WorkflowPackageComponent)applicationContext.getBean("workflowPackageImpl");
// for the purposes of the tests make sure JBPM workflow definitions are visible
this.workflowAdminService = (WorkflowAdminServiceImpl) applicationContext.getBean("workflowAdminService");
this.workflowAdminService.setJBPMWorkflowDefinitionsVisible(true);
// deploy test process messages
I18NUtil.registerResourceBundle("jbpmresources/test-messages");
@@ -573,25 +566,10 @@ public class JBPMEngineTest extends BaseAlfrescoSpringTest
List<WorkflowDefinition> defs = workflowComponent.getDefinitions();
List<WorkflowDefinition> allDefs = workflowComponent.getAllDefinitions();
// make sure both lists are populated (only if the JBPM engine is enabled)
if (workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID))
{
assertFalse(defs.isEmpty());
assertFalse(allDefs.isEmpty());
}
// turn off workflow definition visibility
this.workflowAdminService.setJBPMWorkflowDefinitionsVisible(false);
// retrieve workflow definitions again
defs = workflowComponent.getDefinitions();
allDefs = workflowComponent.getAllDefinitions();
// ensure the list of workflow definitions are empty
assertTrue(defs.isEmpty());
assertTrue(allDefs.isEmpty());
}
// public void testAssignTaskVariablesWithScript() throws Exception
// {
// WorkflowDefinition definition = workflowComponent.getDefinitionByName("jbpm$testwf:testTaskVarScriptAssign");

View File

@@ -0,0 +1,59 @@
/*
* 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.jbpm;
import org.alfresco.repo.workflow.AbstractMultitenantWorkflowTest;
/**
* @author Nick Smith
* @since 4.0
*
*/
public class JbpmMultitenantWorkflowTest extends AbstractMultitenantWorkflowTest
{
@Override
protected String getEngine()
{
return JBPMEngine.ENGINE_ID;
}
@Override
protected String getTestDefinitionPath()
{
return "jbpmresources/test_simple_processdefinition.xml";
}
@Override
protected String getTestDefinitionKey()
{
return "jbpm$test";
}
protected String getAdhocDefinitionPath()
{
return "alfresco/workflow/adhoc_processdefinition.xml";
}
@Override
protected String getAdhocDefinitionKey()
{
return "jbpm$wf:adhoc";
}
}

View File

@@ -33,7 +33,7 @@ public interface WorkflowAdminService
* @param engineId The id of a workflow engine
* @return true if the engine id is valid and is enabled
*/
public boolean isEngineEnabled(String engineId);
boolean isEngineEnabled(String engineId);
/**
* Determines whether the JBPM workflow definitions are visible
@@ -42,7 +42,8 @@ public interface WorkflowAdminService
* NOTE: Workflow definitions can always be retrieved directly
* i.e. via name or id
*
* @param engineId The id of a workflow engine
* @return true if the definitions are visible
*/
public boolean isJBPMWorkflowDefinitionsVisible();
boolean isEngineVisible(String engineId);
}

View File

@@ -197,12 +197,14 @@ public class WorkflowTaskQuery
}
/**
* Use {@link WorkflowTaskQuery#setWorkflowDefinitionName(String)} instead.
* Filters on the {@link WorkflowDefinition} name. When using Activiti,
* the method {@link #setWorkflowDefinitionName(String)} should be used
* instead of this method.
*
* @param processName
*/
@Deprecated
public void setProcessName(QName processName)
{
this.processName = processName;

View File

@@ -0,0 +1,39 @@
/*
* 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.util;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
/**
* Base JUnit 4 test that loads the full application context and runs tests transactionally with default rollback behaviour.
* @author Nick Smith
* @since 4.0
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:alfresco/application-context.xml"})
@TransactionConfiguration(defaultRollback=true, transactionManager="transactionManager")
public abstract class AlfrescoApplicationContextTest
{
// NOOP
}

View File

@@ -44,6 +44,8 @@
<constructor-arg value="org.alfresco.repo.workflow.BPMEngineRegistry" />
</bean>
<bean id="baseWorkflowEngineStatus" class="org.alfresco.repo.workflow.WorkflowEngineStatus" abstract="true" />
<!-- Authentication Util initialization -->
<bean id="authenticationUtil"
class="org.alfresco.repo.security.authentication.AuthenticationUtil">