diff --git a/config/alfresco/activiti-context.xml b/config/alfresco/activiti-context.xml index 221c74a8ad..291600c5ce 100644 --- a/config/alfresco/activiti-context.xml +++ b/config/alfresco/activiti-context.xml @@ -2,10 +2,9 @@ @@ -34,7 +33,7 @@ - + @@ -47,12 +46,13 @@ - + - - - + + + @@ -65,48 +65,49 @@ - + - - - - - + + + + + - - - - - - - - - - - - - - + class="org.alfresco.repo.workflow.activiti.ActivitiWorkflowManagerFactory"> + + + + + + + + + + + + + + - + - + - + @@ -114,7 +115,7 @@ - + @@ -125,8 +126,7 @@ + depends-on="activitiWorkflowManager" abstract="true"> @@ -150,7 +150,7 @@ + parent="activitiPropertyHandler"> @@ -159,14 +159,14 @@ - + - @@ -179,8 +179,9 @@ - - + + @@ -194,7 +195,8 @@ factory-method="getHistoryService" /> - + diff --git a/config/alfresco/jbpm-context.xml b/config/alfresco/jbpm-context.xml index 950fbf23b1..96287e2982 100644 --- a/config/alfresco/jbpm-context.xml +++ b/config/alfresco/jbpm-context.xml @@ -25,7 +25,6 @@ - diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index 2bde7abfe0..76e335528d 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -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 diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml index a468c0454e..8c49278fbf 100644 --- a/config/alfresco/workflow-context.xml +++ b/config/alfresco/workflow-context.xml @@ -30,6 +30,7 @@ + @@ -66,17 +67,30 @@ - - - - ${system.workflow.engine.activiti.enabled} - - - ${system.workflow.engine.jbpm.enabled} - - - ${system.workflow.jbpm.definitions.visible} - + + + + + + jbpm + ${system.workflow.engine.jbpm.enabled} + ${system.workflow.engine.jbpm.definitions.visible} + + + + activiti + ${system.workflow.engine.activiti.enabled} + ${system.workflow.engine.activiti.definitions.visible} + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java b/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java index b7d8b90eed..c1cb8f7d4d 100644 --- a/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java +++ b/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java @@ -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; @@ -82,7 +81,9 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri public final static String USER_ONE_LASTNAME = "Test"; public final static String USER_ONE_EMAIL = USER_ONE + "@alfrescotesting.com"; public final static String USER_TWO_EMAIL = USER_TWO + "@alfrescotesting.com"; - + + private Collection enabledEngines; + private Collection 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); diff --git a/source/java/org/alfresco/repo/invitation/ActivitiInvitationServiceImplTests.java b/source/java/org/alfresco/repo/invitation/ActivitiInvitationServiceImplTests.java index 1b3da836c5..fd16a799a8 100644 --- a/source/java/org/alfresco/repo/invitation/ActivitiInvitationServiceImplTests.java +++ b/source/java/org/alfresco/repo/invitation/ActivitiInvitationServiceImplTests.java @@ -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 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 paths = workflowService.getWorkflowPaths(instanceId); + assertEquals(1, paths.size()); + WorkflowPath path = paths.get(0); + List 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)); } } diff --git a/source/java/org/alfresco/repo/invitation/JbpmInvitationServiceImplTests.java b/source/java/org/alfresco/repo/invitation/JbpmInvitationServiceImplTests.java index ea5eab3b13..a2b7cabe5e 100644 --- a/source/java/org/alfresco/repo/invitation/JbpmInvitationServiceImplTests.java +++ b/source/java/org/alfresco/repo/invitation/JbpmInvitationServiceImplTests.java @@ -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)); } } diff --git a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java index 3169f149e3..cbfb869b4b 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java +++ b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java @@ -138,6 +138,7 @@ public class MultiTDemoTest extends TestCase public MultiTDemoTest() { + super(); } diff --git a/source/java/org/alfresco/repo/workflow/AbstractMultitenantWorkflowTest.java b/source/java/org/alfresco/repo/workflow/AbstractMultitenantWorkflowTest.java new file mode 100644 index 0000000000..64f3875b8e --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/AbstractMultitenantWorkflowTest.java @@ -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 . + */ + +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 allDefs = workflowService.getAllDefinitions(); + int allDefsSize = allDefs.size(); + List 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 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 parameters1 = new HashMap(); + 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 parameters2 = new HashMap(); + 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() + { + 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(); + +} diff --git a/source/java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java b/source/java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java index 7b45c20f00..528effb387 100644 --- a/source/java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java +++ b/source/java/org/alfresco/repo/workflow/AbstractWorkflowServiceIntegrationTest.java @@ -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(); diff --git a/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java b/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java index 49f6fa29f2..ab1ab9c40c 100644 --- a/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java +++ b/source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java @@ -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,19 +87,9 @@ 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"); - } + workflowComponents.put(engineId, engine); + if (logger.isDebugEnabled()) + logger.debug("Registered Workflow Component '" + engineId + "' (" + engine.getClass() + ")"); } /** @@ -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,19 +133,9 @@ 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"); - } + taskComponents.put(engineId, engine); + if (logger.isDebugEnabled()) + logger.debug("Registered Task Component '" + engineId + "' (" + engine.getClass() + ")"); } /** @@ -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 components) + { + List filtered = CollectionUtils.filter(components, new Filter() + { + 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); } diff --git a/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java b/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java index 0154981531..f1d0159529 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowAdminServiceImpl.java @@ -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; - - public void setActivitiEngineEnabled(boolean activitiEngineEnabled) + private Set enabledEngines = new HashSet(); + private Set visibleEngines = new HashSet(); + + /** + * {@inheritDoc} + */ + public boolean isEngineEnabled(String engineId) + { + return enabledEngines.contains(engineId); + } + + public void setEngineEnabled(String engineId, boolean isEnabled) + { + if(isEnabled) + { + enabledEngines.add(engineId); + } + else + { + 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 engines) + { + if(false == enabledEngines.isEmpty()) + { + enabledEngines.clear(); + } + enabledEngines.addAll(engines); + } + + /** + * @return the enabledEngines + */ + public Set getEnabledEngines() { - this.activitiEngineEnabled = activitiEngineEnabled; + return new HashSet(enabledEngines); } - public void setJBPMEngineEnabled(boolean jbpmEngineEnabled) + /** + * Setter for Spring. + * @param engines All engineIds to set visible. + */ + public void setVisibleEngines(Collection engines) + { + if(false == visibleEngines.isEmpty()) + { + visibleEngines.clear(); + } + visibleEngines.addAll(engines); + } + + /** + * @return the visibleEngines + */ + public Set getVisibleEngines() { - this.jbpmEngineEnabled = jbpmEngineEnabled; - } - - public void setJBPMWorkflowDefinitionsVisible(boolean jbpmDefinitionsVisible) - { - this.jbpmDefinitionsVisible = jbpmDefinitionsVisible; + return new HashSet(visibleEngines); } - @Override - public boolean isJBPMWorkflowDefinitionsVisible() + public void setWorkflowEngineConfigurations(List props) { - return this.jbpmDefinitionsVisible; - } - - @Override - public boolean isEngineEnabled(String engineId) - { - if (JBPMEngine.ENGINE_ID.equals(engineId)) + for (Properties prop : props) { - return jbpmEngineEnabled; - } - else if (ActivitiConstants.ENGINE_ID.equals(engineId)) - { - return activitiEngineEnabled; - } - else - { - // if the engine id is not recognised it can't be enabled! - return false; + 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)); + } } } } diff --git a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java index ae6e8701a5..dcd89a9702 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java @@ -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 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 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 List filterByDomain(List values, final Function processKeyGetter) + public List filterByDomain(Collection values, final Function 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. + if(currentDomain.equals(domain)) + { + return true; // The domains match so include. + } } - else if(domain!=null) + else if(domain==null) { - return false; // Ignore domain-specific definitions + return true; // In single-tenant mode only return items with no domain. } - return true; + return false; } }); } diff --git a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java index dd2df6ef5f..f61319e378 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java @@ -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,7 +80,8 @@ 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 * @@ -274,8 +284,11 @@ public class WorkflowServiceImpl implements WorkflowService String[] ids = registry.getWorkflowComponents(); for (String id : ids) { - WorkflowComponent component = registry.getWorkflowComponent(id); - definitions.addAll(component.getDefinitions()); + if(workflowAdminService.isEngineVisible(id)) + { + WorkflowComponent component = registry.getWorkflowComponent(id); + definitions.addAll(component.getDefinitions()); + } } return Collections.unmodifiableList(definitions); } @@ -291,8 +304,11 @@ public class WorkflowServiceImpl implements WorkflowService String[] ids = registry.getWorkflowComponents(); for (String id : ids) { - WorkflowComponent component = registry.getWorkflowComponent(id); - definitions.addAll(component.getAllDefinitions()); + if(workflowAdminService.isEngineVisible(id)) + { + WorkflowComponent component = registry.getWorkflowComponent(id); + definitions.addAll(component.getAllDefinitions()); + } } return Collections.unmodifiableList(definitions); } diff --git a/source/java/org/alfresco/repo/workflow/WorkflowSuiteContextShutdownTest.java b/source/java/org/alfresco/repo/workflow/WorkflowSuiteContextShutdownTest.java new file mode 100644 index 0000000000..5404904520 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/WorkflowSuiteContextShutdownTest.java @@ -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 . + */ + +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(); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/workflow/WorkflowTestHelper.java b/source/java/org/alfresco/repo/workflow/WorkflowTestHelper.java new file mode 100644 index 0000000000..23e3af33d0 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/WorkflowTestHelper.java @@ -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 . + */ + +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 enabledEngines; + private final Set 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); + } + +} diff --git a/source/java/org/alfresco/repo/workflow/WorkflowTestSuite.java b/source/java/org/alfresco/repo/workflow/WorkflowTestSuite.java index 8037125af3..89cae5a23b 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowTestSuite.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowTestSuite.java @@ -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"); - } - } } diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiMultitenantWorkflowTest.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiMultitenantWorkflowTest.java new file mode 100644 index 0000000000..c7b9cb0e31 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiMultitenantWorkflowTest.java @@ -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 . + */ + +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"; + } + +} diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java index 1ff1174111..b6932811bf 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java @@ -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) diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java index 65b1f68550..3fb4d4fd5b 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java @@ -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 { diff --git a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java index 22ec73c611..be3b892c74 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java +++ b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java @@ -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 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 diff --git a/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java b/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java index fe8e6f3a94..906979453e 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java +++ b/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java @@ -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 taskProperties = taskDef.getProperties(); Map taskAssociations = taskDef.getAssociations(); - Map properties = new HashMap(); TaskService taskService = activitiUtil.getTaskService(); // Get all task variables including execution vars. Map variables = taskService.getVariables(task.getId()); + Map localVariables = taskService.getVariablesLocal(task.getId()); // Map the arbitrary properties - Map localVariables = taskService.getVariablesLocal(task.getId()); - mapArbitraryProperties(variables, properties, localVariables, taskProperties, taskAssociations); + Map 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 taskProperties = typeDefinition.getProperties(); Map taskAssociations = typeDefinition.getAssociations(); - Map properties = new HashMap(); - // Get the local task variables Map localVariables = task.getVariablesLocal(); Map 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 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 getTaskProperties(HistoricTaskInstance historicTask, Map variables) + public Map getTaskProperties(HistoricTaskInstance historicTask, Map 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 taskProperties = taskDef.getProperties(); Map taskAssociations = taskDef.getAssociations(); - Map properties = new HashMap(); + Map allVariables = getHistoricProcessVariables(historicTask.getProcessInstanceId()); + allVariables.putAll(localVariables); // Map the arbitrary properties - mapArbitraryProperties(variables, properties, variables, taskProperties, taskAssociations); + Map 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 pooledActors = new ArrayList(); - List pooledActorRefIds = (List) variables.get(ActivitiConstants.PROP_POOLED_ACTORS_HISTORY); + List pooledActorRefIds = (List) localVariables.get(ActivitiConstants.PROP_POOLED_ACTORS_HISTORY); if(pooledActorRefIds != null) { for(String nodeId : pooledActorRefIds) @@ -406,8 +406,6 @@ public class ActivitiPropertyConverter public Map getStartTaskProperties(HistoricProcessInstance historicProcessInstance, String taskDefId, boolean completed) { - Map properties = new HashMap(); - TypeDefinition taskDef = typeManager.getStartTaskDefinition(taskDefId); Map taskProperties = taskDef.getProperties(); Map taskAssociations = taskDef.getAssociations(); @@ -415,7 +413,7 @@ public class ActivitiPropertyConverter Map variables = getStartVariables(historicProcessInstance); // Map all the properties - mapArbitraryProperties(variables, properties, variables, taskProperties, taskAssociations); + Map 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 variables, - Map properties, - Map localVariables, - Map taskProperties, - Map taskAssociations) + private Map mapArbitraryProperties(Map variables, + final Map localVariables, + final Map taskProperties, + final Map taskAssociations) { - // Map arbitrary task variables - for (Entry entry : variables.entrySet()) + EntryTransformer transformer = new EntryTransformer() { - 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 apply(Entry 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, value); + } + return null; } - } + }; + return CollectionUtils.transform(variables, transformer); } /** diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java index 46ebc78416..d84950c926 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java @@ -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,61 +395,54 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine } } - /* - * (non-Javadoc) - * - * @see - * org.alfresco.repo.workflow.WorkflowDefinitionComponent#getDefinitions() + /** + * {@inheritDoc} */ @SuppressWarnings("unchecked") public List getDefinitions() { - if (workflowAdminService.isJBPMWorkflowDefinitionsVisible()) + try { - try + return (List) jbpmTemplate.execute(new JbpmCallback() { - return (List)jbpmTemplate.execute(new JbpmCallback() + public Object doInJbpm(JbpmContext context) { - public Object doInJbpm(JbpmContext context) - { - GraphSession graphSession = context.getGraphSession(); - List processDefs = graphSession.findLatestProcessDefinitions(); - List workflowDefs = new ArrayList(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; - } - }); - } - catch (JbpmException e) - { - String msg = messageService.getMessage(ERR_GET_WORKFLOW_DEF); - throw new WorkflowException(msg, e); - } + GraphSession graphSession = context.getGraphSession(); + List processDefs = graphSession.findLatestProcessDefinitions(); + return getValidDefinitions(processDefs); + } + }); } - else + catch (JbpmException e) { - return Collections.emptyList(); + String msg = messageService.getMessage(ERR_GET_WORKFLOW_DEF); + throw new WorkflowException(msg, e); } } + private List getValidDefinitions(Collection definitions) + { + List filteredDefs = factory.filterByDomain(definitions, new Function() + { + public String apply(ProcessDefinition definition) + { + return definition.getName(); + } + }); + return convertDefinitions(filteredDefs); + } + + private List convertDefinitions(Collection definitions) + { + return CollectionUtils.transform(definitions, new Function() + { + public WorkflowDefinition apply(ProcessDefinition value) + { + return createWorkflowDefinition(value); + } + }); + } + /* * (non-Javadoc) * @@ -469,49 +452,22 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine @SuppressWarnings("unchecked") public List getAllDefinitions() { - if (workflowAdminService.isJBPMWorkflowDefinitionsVisible()) + try { - try + return (List) jbpmTemplate.execute(new JbpmCallback() { - return (List)jbpmTemplate.execute(new JbpmCallback() + public Object doInJbpm(JbpmContext context) { - public Object doInJbpm(JbpmContext context) - { - GraphSession graphSession = context.getGraphSession(); - List processDefs = graphSession.findAllProcessDefinitions(); - List workflowDefs = new ArrayList(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; - } - }); - } - catch (JbpmException e) - { - String msg = messageService.getMessage(ERR_GET_WORKFLOW_DEF); - throw new WorkflowException(msg, e); - } + GraphSession graphSession = context.getGraphSession(); + List processDefs = graphSession.findAllProcessDefinitions(); + return getValidDefinitions(processDefs); + } + }); } - else + catch (JbpmException e) { - return Collections.emptyList(); + String msg = messageService.getMessage(ERR_GET_WORKFLOW_DEF); + throw new WorkflowException(msg, e); } } @@ -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 processDefs = graphSession.findAllProcessDefinitionVersions(tenantService - .getName(createLocalId(workflowName))); - List workflowDefs = new ArrayList(processDefs.size()); - for (ProcessDefinition processDef : processDefs) - { - WorkflowDefinition workflowDef = createWorkflowDefinition(processDef); - workflowDefs.add(workflowDef); - } - return workflowDefs; + String definitionName = tenantService.getName(createLocalId(workflowName)); + List processDefs = graphSession.findAllProcessDefinitionVersions(definitionName); + return convertDefinitions(processDefs); } }); } @@ -1624,6 +1573,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine { return (List) jbpmTemplate.execute(new JbpmCallback() { + @SuppressWarnings("deprecation") public List 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 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) { - 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)); + definitionName = createLocalId(definitionName); } - - // Process definition name - if (query.getWorkflowDefinitionName() != null) + 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()) - { - 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)); } diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java index 18675ea3a2..cf6e26503c 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java @@ -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,23 +566,8 @@ public class JBPMEngineTest extends BaseAlfrescoSpringTest List defs = workflowComponent.getDefinitions(); List 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()); + assertFalse(defs.isEmpty()); + assertFalse(allDefs.isEmpty()); } // public void testAssignTaskVariablesWithScript() throws Exception diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JbpmMultitenantWorkflowTest.java b/source/java/org/alfresco/repo/workflow/jbpm/JbpmMultitenantWorkflowTest.java new file mode 100644 index 0000000000..5c4d10d81b --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/JbpmMultitenantWorkflowTest.java @@ -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 . + */ + +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"; + } +} diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowAdminService.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowAdminService.java index 96a5f67fdd..afd81b457a 100644 --- a/source/java/org/alfresco/service/cmr/workflow/WorkflowAdminService.java +++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowAdminService.java @@ -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); } diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowTaskQuery.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowTaskQuery.java index f952bc749d..f81ea26154 100644 --- a/source/java/org/alfresco/service/cmr/workflow/WorkflowTaskQuery.java +++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowTaskQuery.java @@ -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; diff --git a/source/java/org/alfresco/util/AlfrescoApplicationContextTest.java b/source/java/org/alfresco/util/AlfrescoApplicationContextTest.java new file mode 100644 index 0000000000..637ce4ab9c --- /dev/null +++ b/source/java/org/alfresco/util/AlfrescoApplicationContextTest.java @@ -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 . + */ + +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 +} diff --git a/source/test-resources/activiti/test-activiti-component-context.xml b/source/test-resources/activiti/test-activiti-component-context.xml index c437e06041..74740dbd2e 100644 --- a/source/test-resources/activiti/test-activiti-component-context.xml +++ b/source/test-resources/activiti/test-activiti-component-context.xml @@ -44,6 +44,8 @@ + +