Nick S: Created a JBPMEngineUnitTest which uses much less of the Spring context and is much faster to run.

Also created a OneToManyMap and a OneToManyBiMap to help mock up the NamespaceService.

*** IMPORTANT!!! ***
The test requires a new database schema. The schema has the same name as the original schema but has _test after it, i.e. ${db.name}_test


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15746 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
N Smith
2009-08-14 10:58:14 +00:00
parent abafb8f4e5
commit 1dfbefe4d5
15 changed files with 916 additions and 124 deletions

View File

@@ -0,0 +1,83 @@
<jbpm-configuration>
<jbpm-context>
<service name="persistence"
factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
<service name="scheduler"
factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
<service name="logging"
factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication"
factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
</jbpm-context>
<!--
configuration resource files pointing to default configuration
files in jbpm-{version}.jar
-->
<string name="resource.business.calendar"
value="org/jbpm/calendar/jbpm.business.calendar.properties" />
<string name="resource.default.modules"
value="org/jbpm/graph/def/jbpm.default.modules.properties" />
<string name='resource.converter'
value='org/alfresco/repo/workflow/jbpm/jbpm.converter.properties' />
<string name="resource.action.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.action.types.xml" />
<string name="resource.node.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml" />
<string name="resource.parsers"
value="org/alfresco/repo/workflow/jbpm/jbpm.parsers.xml" />
<string name="resource.varmapping"
value="org/alfresco/repo/workflow/jbpm/jbpm.varmapping.xml" />
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
<int name="jbpm.byte.block.size" value="1024" singleton="true" />
<string name="jbpm.mail.smtp.host" value="localhost" />
<bean name="jbpm.task.instance.factory"
class="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstanceFactory"
singleton="true">
<field name="jbpmEngineName">
<string value="test_jbpm_engine" />
</field>
</bean>
<bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver"
singleton="true" />
<bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver"
singleton="true" />
<bean name="jbpm.job.executor" class="org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutor">
<field name="jbpmConfiguration">
<ref bean="jbpmConfiguration" />
</field>
<field name="name">
<string value="AlfrescoJbpmJobExector" />
</field>
<field name="nbrOfThreads">
<int value="1" />
</field>
<!-- overridden for WCM unit tests to 5 secs (was 1.5 mins) -->
<field name="idleInterval">
<int value="5000" />
</field>
<field name="maxIdleInterval">
<int value="3600000" />
</field> <!-- 1 hour -->
<field name="historyMaxSize">
<int value="20" />
</field>
<field name="maxLockTime">
<int value="600000" />
</field> <!-- 10 minutes -->
<field name="lockMonitorInterval">
<int value="60000" />
</field> <!-- 1 minute -->
<field name="lockBufferTime">
<int value="5000" />
</field> <!-- 5 seconds -->
</bean>
</jbpm-configuration>

View File

@@ -0,0 +1,24 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Overriding test properties to point to custom properties -->
<bean id="test-properties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
<property name="locations">
<list>
<value>classpath:alfresco/repository.properties</value>
<value>classpath:alfresco/version.properties</value>
<value>classpath:alfresco/domain/transaction.properties</value>
<value>classpath:alfresco/alfresco-shared.properties</value>
<value>file:D:\workspaces/projects/head/data/repository.properties</value> <!-- override core properties -->
<value>classpath:test/alfresco/test.properties</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,219 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<import resource="classpath:test/alfresco/test-context.xml" />
<!-- load hibernate configuration properties -->
<bean id="testHibernateConfigProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<!-- Load in hibernate defaults -->
<property name="locations">
<list>
<value>classpath:test/alfresco/test-hibernate-cfg.properties</value>
</list>
</property>
<property name="localOverride">
<value>true</value>
</property>
</bean>
<!-- Datasource bean -->
<bean id="testDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${db.driver}</value>
</property>
<property name="url">
<value>${db.testurl}</value>
</property>
<property name="username">
<value>${db.username}</value>
</property>
<property name="password">
<value>${db.password}</value>
</property>
<property name="initialSize">
<value>${db.pool.initial}</value>
</property>
<property name="maxActive">
<value>${db.pool.max}</value>
</property>
<property name="minIdle">
<value>${db.pool.min}</value>
</property>
<property name="maxIdle">
<value>${db.pool.idle}</value>
</property>
<property name="defaultAutoCommit">
<value>false</value>
</property>
<property name="defaultTransactionIsolation">
<value>${db.txn.isolation}</value>
</property>
<property name="maxWait">
<value>${db.pool.wait.max}</value>
</property>
<property name="validationQuery">
<value>${db.pool.validate.query}</value>
</property>
<property name="timeBetweenEvictionRunsMillis">
<value>${db.pool.evict.interval}</value>
</property>
<property name="minEvictableIdleTimeMillis">
<value>${db.pool.evict.idle.min}</value>
</property>
<property name="testOnBorrow">
<value>${db.pool.validate.borrow}</value>
</property>
<property name="testOnReturn">
<value>${db.pool.validate.return}</value>
</property>
<property name="testWhileIdle">
<value>${db.pool.evict.validate}</value>
</property>
<property name="removeAbandoned">
<value>${db.pool.abandoned.detect}</value>
</property>
<property name="removeAbandonedTimeout">
<value>${db.pool.abandoned.time}</value>
</property>
<property name="poolPreparedStatements">
<value>${db.pool.statements.enable}</value>
</property>
<property name="maxOpenPreparedStatements">
<value>${db.pool.statements.max}</value>
</property>
</bean>
<!-- Hibernate session factory -->
<bean id="testSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="testDataSource" />
</property>
<property name="schemaUpdate">
<value>true</value>
</property>
<!--
<property name="eventListeners" > <map> <entry key="load">
<list> <ref bean="defaltOnLoadListsner" /> <ref
bean="clearCGLibThreadLocal" /> </list> </entry> </map>
</property>
-->
<property name="mappingResources">
<list>
<!-- -->
<!-- JBoss jBPM Workflow Engine -->
<!-- -->
<!--
TODO: Determine if it's possible to inject the following
mappings
-->
<!-- from elsewhere -->
<!-- -->
<value>org/jbpm/graph/action/Script.hbm.xml</value>
<value>org/jbpm/db/hibernate.queries.hbm.xml</value>
<value>org/jbpm/graph/def/ProcessDefinition.hbm.xml</value>
<value>org/jbpm/graph/def/Node.hbm.xml</value>
<value>org/jbpm/graph/def/Transition.hbm.xml</value>
<value>org/jbpm/graph/def/Event.hbm.xml</value>
<value>org/jbpm/graph/def/Action.hbm.xml</value>
<value>org/jbpm/graph/def/SuperState.hbm.xml</value>
<value>org/jbpm/graph/def/ExceptionHandler.hbm.xml</value>
<value>org/jbpm/instantiation/Delegation.hbm.xml</value>
<value>org/jbpm/graph/node/StartState.hbm.xml</value>
<value>org/jbpm/graph/node/EndState.hbm.xml</value>
<value>org/jbpm/graph/node/ProcessState.hbm.xml</value>
<value>org/jbpm/graph/node/Decision.hbm.xml</value>
<value>org/jbpm/graph/node/Fork.hbm.xml</value>
<value>org/alfresco/repo/workflow/jbpm/jbpm.Join.hbm.xml</value>
<value>org/jbpm/graph/node/State.hbm.xml</value>
<value>org/jbpm/graph/node/TaskNode.hbm.xml</value>
<value>org/jbpm/context/def/ContextDefinition.hbm.xml</value>
<value>org/jbpm/context/def/VariableAccess.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/TaskMgmtDefinition.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/Swimlane.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/Task.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/TaskController.hbm.xml</value>
<value>org/jbpm/module/def/ModuleDefinition.hbm.xml</value>
<value>org/jbpm/bytes/ByteArray.hbm.xml</value>
<value>org/jbpm/file/def/FileDefinition.hbm.xml</value>
<value>org/alfresco/repo/workflow/jbpm/jbpm.CreateTimerAction.hbm.xml</value>
<value>org/jbpm/scheduler/def/CancelTimerAction.hbm.xml</value>
<value>org/jbpm/graph/exe/Comment.hbm.xml</value>
<value>org/jbpm/graph/exe/ProcessInstance.hbm.xml</value>
<value>org/jbpm/graph/exe/Token.hbm.xml</value>
<value>org/jbpm/graph/exe/RuntimeAction.hbm.xml</value>
<value>org/jbpm/module/exe/ModuleInstance.hbm.xml</value>
<value>org/jbpm/context/exe/ContextInstance.hbm.xml</value>
<value>org/jbpm/context/exe/TokenVariableMap.hbm.xml</value>
<value>org/jbpm/context/exe/VariableInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/ByteArrayInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/DateInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/DoubleInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/HibernateLongInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/HibernateStringInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/LongInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/NullInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/StringInstance.hbm.xml</value>
<value>org/jbpm/job/Job.hbm.xml</value>
<value>org/jbpm/job/Timer.hbm.xml</value>
<value>org/alfresco/repo/workflow/jbpm/jbpm.Timer.hbm.xml</value>
<value>org/jbpm/job/ExecuteNodeJob.hbm.xml</value>
<value>org/jbpm/job/ExecuteActionJob.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/TaskMgmtInstance.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/TaskInstance.hbm.xml</value>
<value>org/alfresco/repo/workflow/jbpm/WorkflowTaskInstance.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/PooledActor.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/SwimlaneInstance.hbm.xml</value>
<value>org/jbpm/logging/log/ProcessLog.hbm.xml</value>
<value>org/jbpm/logging/log/MessageLog.hbm.xml</value>
<value>org/jbpm/logging/log/CompositeLog.hbm.xml</value>
<value>org/jbpm/graph/log/ActionLog.hbm.xml</value>
<value>org/jbpm/graph/log/NodeLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessInstanceCreateLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessInstanceEndLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessStateLog.hbm.xml</value>
<value>org/jbpm/graph/log/SignalLog.hbm.xml</value>
<value>org/jbpm/graph/log/TokenCreateLog.hbm.xml</value>
<value>org/jbpm/graph/log/TokenEndLog.hbm.xml</value>
<value>org/jbpm/graph/log/TransitionLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableCreateLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableDeleteLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/ByteArrayUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/DateUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/DoubleUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/HibernateLongUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/HibernateStringUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/LongUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/StringUpdateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskCreateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskAssignLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskEndLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml</value>
<value>org/jbpm/job/CleanUpProcessJob.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties" ref="testHibernateConfigProperties" />
</bean>
<!-- create a transaction manager -->
<bean id="testTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="transactionSynchronizationName">
<value>SYNCHRONIZATION_ALWAYS</value>
</property>
<property name="sessionFactory">
<ref bean="testSessionFactory" />
</property>
</bean>
</beans>

View File

@@ -0,0 +1,28 @@
#
# Hibernate configuration
#
# The Hibernate Dialect:
# As of V3.1, the dialect is automatically detected.
# It is still possible to set the dialect explicitly, for example:
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.hbm2ddl.auto=update
hibernate.jdbc.use_streams_for_binary=true
hibernate.show_sql=false
hibernate.cache.use_query_cache=true
hibernate.max_fetch_depth=10
hibernate.cache.provider_class=org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean
hibernate.cache.use_second_level_cache=true
hibernate.default_batch_fetch_size=1
hibernate.jdbc.batch_size=32
hibernate.connection.release_mode=auto
hibernate.connection.isolation=2
#hibernate.query.substitutions=
#hibernate.jdbc.use_get_generated_keys=false
# Oracle Schema Distinction:
# See https://issues.alfresco.com/jira/browse/ETHREEOH-680
# Metadata queries to Oracle have to be limited by schema name
# when multiple instances of Alfresco are installed on an Oracle server.
#hibernate.default_schema=

View File

@@ -0,0 +1,33 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- -->
<!-- Alfresco BPM Registry -->
<!-- -->
<bean id="test_bpm_engineRegistry" class="org.alfresco.repo.workflow.BPMEngineRegistry" />
<bean id="test_bpm_engine" class="org.alfresco.repo.workflow.BPMEngine"
abstract="true">
<property name="BPMEngineRegistry" ref="test_bpm_engineRegistry" />
</bean>
<!-- -->
<!-- jBPM Implementation -->
<!-- -->
<bean id="test_jbpm_configuration"
class="org.alfresco.repo.workflow.jbpm.AlfrescoJbpmConfigurationFactoryBean">
<property name="sessionFactory" ref="testSessionFactory" />
<property name="configuration"
value="classpath:test/alfresco/jbpm.cfg.xml" />
</bean>
<bean id="test_jbpm_template"
class="org.alfresco.repo.workflow.jbpm.JBPMTransactionTemplate">
<constructor-arg index="0" ref="test_jbpm_configuration" />
</bean>
</beans>

View File

@@ -0,0 +1,2 @@
#DB url for tests.
db.testurl=${db.url}_test

View File

@@ -2667,7 +2667,7 @@ public class JBPMEngine extends BPMEngine
} }
catch (RuntimeException re) catch (RuntimeException re)
{ {
throw new IllegalStateException("Invalid company home path: " + companyHomePath + ": " + re.getMessage()); throw new IllegalStateException("Invalid company home path: " + companyHomePath + ": " + re.getMessage(), re);
} }
} }
else else

View File

@@ -74,7 +74,6 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition testWorkflowDef; WorkflowDefinition testWorkflowDef;
NodeRef testNodeRef; NodeRef testNodeRef;
@Override @Override
protected void onSetUpInTransaction() throws Exception protected void onSetUpInTransaction() throws Exception
{ {

View File

@@ -0,0 +1,225 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.workflow.jbpm;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.transaction.TransactionDefinition.*;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import junit.framework.TestCase;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.i18n.MessageService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.transaction.SpringAwareUserTransaction;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springmodules.workflow.jbpm31.JbpmTemplate;
/**
* JBPMEngine Unit Tests.
*
* @author Nick Smith
*/
public class JBPMEngineUnitTest extends TestCase
{
private static final NodeRef companyHome = new NodeRef("for://test/home");
private static final ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] { "classpath:test/alfresco/test-database-context.xml",
"classpath:test/alfresco/test-workflow-context.xml", });
private JBPMEngine engine = new JBPMEngine();
private WorkflowDefinition testWorkflowDef;
private SpringAwareUserTransaction transaction;
public void testStartWorkflowWithoutPackage() throws Exception
{
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
engine.startWorkflow(testWorkflowDef.getId(), params);
}
@Override
protected void setUp() throws Exception
{
super.setUp();
// Mock up various services.
NodeService nodeService = mock(NodeService.class);
TenantService tenantService = makeTenantService();
NamespaceService namespaceService = makeNamespaceService();
DictionaryService dictionaryService = makeDictionaryService();
// Add services to ServiceRegistry
ServiceRegistry serviceRegistry = mock(ServiceRegistry.class);
when(serviceRegistry.getNodeService()).thenReturn(nodeService);
when(serviceRegistry.getNamespaceService()).thenReturn(namespaceService);
when(serviceRegistry.getDictionaryService()).thenReturn(dictionaryService);
JbpmTemplate jbpmTemplate = (JbpmTemplate) ctx.getBean("test_jbpm_template");
// Set up the JBPMEngine.
engine.setJBPMTemplate(jbpmTemplate);
engine.setTenantService(tenantService);
engine.setNodeService(nodeService);
engine.setServiceRegistry(serviceRegistry);
engine.setNamespaceService(namespaceService);
engine.setMessageService(mock(MessageService.class));
engine.setDictionaryService(dictionaryService);
engine.setEngineId("jbpm_test");
// Need to register JBPMEngine with bean factory so WorflowTaskInstance
// can load it.
ctx.getBeanFactory().registerSingleton("test_jbpm_engine", engine);
// Deploy test workflow process definition to JBPM.
startTransaction();
deployTestDefinition();
}
@SuppressWarnings("unchecked")
private DictionaryService makeDictionaryService()
{
DictionaryService service = mock(DictionaryService.class);
// DictionaryService.getType(QName) always returns a mock
// TypeDefinition.
TypeDefinition typeDef = mock(TypeDefinition.class);
when(service.getType((QName) any())).thenReturn(typeDef);
// DictionaryService.getAnonymousType(QName, Collection<QName>)
// always returns a mock TypeDefinition
when(service.getAnonymousType((QName) any(),//
(Collection<QName>) any()))//
.thenReturn(typeDef);
return service;
}
private void startTransaction() throws NotSupportedException, SystemException
{
PlatformTransactionManager transactionManager = (PlatformTransactionManager) ctx
.getBean("testTransactionManager");
transaction = new SpringAwareUserTransaction(transactionManager, false, ISOLATION_DEFAULT,
PROPAGATION_REQUIRED, 1000);
transaction.begin();
}
// deploy test process definition
private void deployTestDefinition() throws IOException
{
ClassPathResource processDef = new ClassPathResource(
"jbpmresources/test_processdefinition.xml");
assertFalse(engine.isDefinitionDeployed(processDef.getInputStream(),
MimetypeMap.MIMETYPE_XML));
WorkflowDeployment deployment = engine.deployDefinition(processDef.getInputStream(),
MimetypeMap.MIMETYPE_XML);
testWorkflowDef = deployment.definition;
assertNotNull(testWorkflowDef);
assertEquals("jbpm_test$test", testWorkflowDef.name);
assertEquals("1", testWorkflowDef.version);
assertTrue(engine.isDefinitionDeployed(processDef.getInputStream(),
MimetypeMap.MIMETYPE_XML));
}
private NamespaceService makeNamespaceService()
{
NamespaceServiceMemoryImpl namespace = new NamespaceServiceMemoryImpl();
namespace.registerNamespace(NamespaceService.DEFAULT_PREFIX, NamespaceService.DEFAULT_URI);
namespace.registerNamespace("wf", "http://www.alfresco.org/model/bpm/1.0");
return namespace;
}
private TenantService makeTenantService()
{
TenantService tenantService = mock(TenantService.class);
// Tenant Service.isEnabled() returns true.
when(tenantService.isEnabled()).thenReturn(true);
// TenantService.getRootNode always returns companyHome.
when(tenantService.getRootNode((NodeService) any(),//
(SearchService) any(),//
(NamespaceService) any(),//
anyString(),//
(NodeRef) any()))//
.thenReturn(companyHome);
// Tenant Service.getName(String) will return the input param.
when(tenantService.getName(anyString())).thenAnswer(new Answer<String>()
{
public String answer(InvocationOnMock invocation) throws Throwable
{
return (String) invocation.getArguments()[0];
}
});
when(tenantService.getBaseName(anyString())).thenAnswer(new Answer<String>()
{
public String answer(InvocationOnMock invocation) throws Throwable
{
return (String) invocation.getArguments()[0];
}
});
return tenantService;
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
try
{
transaction.rollback();
}
// To prevent rollback exceptions hiding other exceptions int he unit
// test.
catch (Throwable t)
{
System.out.println(t.getStackTrace());
}
}
}

View File

@@ -6,8 +6,10 @@
<hibernate-mapping default-access="field"> <hibernate-mapping default-access="field">
<subclass name="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstance" <subclass name="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstance"
extends="org.jbpm.taskmgmt.exe.TaskInstance" extends="org.jbpm.taskmgmt.exe.TaskInstance" discriminator-value="W">
discriminator-value="W"/> <property name="jbpmEngineName" type="string" length="50"
column="JBPM_ENGINE_NAME" />
</subclass>
</hibernate-mapping> </hibernate-mapping>

View File

@@ -22,6 +22,7 @@
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
package org.alfresco.repo.workflow.jbpm; package org.alfresco.repo.workflow.jbpm;
import java.io.Serializable; import java.io.Serializable;
@@ -39,7 +40,6 @@ import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference; import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springmodules.workflow.jbpm31.JbpmFactoryLocator; import org.springmodules.workflow.jbpm31.JbpmFactoryLocator;
/** /**
* Alfresco specific implementation of a jBPM task instance * Alfresco specific implementation of a jBPM task instance
* *
@@ -49,29 +49,11 @@ public class WorkflowTaskInstance extends TaskInstance
{ {
private static final long serialVersionUID = 6824116036569411964L; private static final long serialVersionUID = 6824116036569411964L;
private String jbpmEngineName = null;
/** Alfresco JBPM Engine */ /** Alfresco JBPM Engine */
private static JBPMEngine jbpmEngine = null; private static JBPMEngine jbpmEngine = null;
/**
* Gets the JBPM Engine instance
*
* @return JBPM Engine
*/
private JBPMEngine getJBPMEngine()
{
if (jbpmEngine == null)
{
BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
jbpmEngine = (JBPMEngine)factory.getFactory().getBean("jbpm_engine");
if (jbpmEngine == null)
{
throw new WorkflowException("Failed to retrieve JBPMEngine component");
}
}
return jbpmEngine;
}
/** /**
* Construct * Construct
*/ */
@@ -92,13 +74,33 @@ public class WorkflowTaskInstance extends TaskInstance
} }
/** /**
* Construct * Sets jbpmEngineName which is used to get the JBPMEngine instance from a
* BeanFactory
* *
* @param taskName * @param jbpmEngineName the jbpmEngineName to set
*/ */
public WorkflowTaskInstance(String taskName) public void setJbpmEngineName(String jbpmEngineName)
{ {
super(taskName); this.jbpmEngineName = jbpmEngineName;
}
/**
* Gets the JBPM Engine instance
*
* @return JBPM Engine
*/
private JBPMEngine getJBPMEngine()
{
if (jbpmEngine == null)
{
BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
if (jbpmEngineName == null) jbpmEngineName = "jbpm_engine";
jbpmEngine = (JBPMEngine) factory.getFactory().getBean(jbpmEngineName);
if (jbpmEngine == null) { throw new WorkflowException(
"Failed to retrieve JBPMEngine component"); }
}
return jbpmEngine;
} }
@Override @Override
@@ -111,17 +113,20 @@ public class WorkflowTaskInstance extends TaskInstance
@Override @Override
public void end(Transition transition) public void end(Transition transition)
{ {
// Force assignment of task if transition is taken, but no owner has yet been assigned // Force assignment of task if transition is taken, but no owner has yet
// been assigned
if (actorId == null) if (actorId == null)
{ {
actorId = AuthenticationUtil.getFullyAuthenticatedUser(); actorId = AuthenticationUtil.getFullyAuthenticatedUser();
} }
// Set task properties on completion of task // Set task properties on completion of task
// NOTE: Set properties first, so they're available during the submission of // NOTE: Set properties first, so they're available during the
// task variables to the process context // submission of
// task variables to the process context
Map<QName, Serializable> taskProperties = new HashMap<QName, Serializable>(); Map<QName, Serializable> taskProperties = new HashMap<QName, Serializable>();
Transition outcome = (transition == null) ? token.getNode().getDefaultLeavingTransition() : transition; Transition outcome = (transition == null) ? token.getNode().getDefaultLeavingTransition()
: transition;
if (outcome != null) if (outcome != null)
{ {
taskProperties.put(WorkflowModel.PROP_OUTCOME, outcome.getName()); taskProperties.put(WorkflowModel.PROP_OUTCOME, outcome.getName());
@@ -134,7 +139,8 @@ public class WorkflowTaskInstance extends TaskInstance
if (getTask().getStartState() != null) if (getTask().getStartState() != null)
{ {
// if ending a start task, push start task properties to process context, if not // if ending a start task, push start task properties to process
// context, if not
// already done // already done
getJBPMEngine().setDefaultWorkflowProperties(this); getJBPMEngine().setDefaultWorkflowProperties(this);

View File

@@ -22,13 +22,13 @@
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
package org.alfresco.repo.workflow.jbpm; package org.alfresco.repo.workflow.jbpm;
import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.taskmgmt.TaskInstanceFactory; import org.jbpm.taskmgmt.TaskInstanceFactory;
import org.jbpm.taskmgmt.exe.TaskInstance; import org.jbpm.taskmgmt.exe.TaskInstance;
/** /**
* jBPM factory for creating Alfresco derived Task Instances * jBPM factory for creating Alfresco derived Task Instances
* *
@@ -38,12 +38,26 @@ public class WorkflowTaskInstanceFactory implements TaskInstanceFactory
{ {
private static final long serialVersionUID = -8097108150047415711L; private static final long serialVersionUID = -8097108150047415711L;
private String jbpmEngineName;
/* (non-Javadoc) /**
* @see org.jbpm.taskmgmt.TaskInstanceFactory#createTaskInstance(org.jbpm.graph.exe.ExecutionContext) * @param jbpmEngine the jbpmEngine to set
*/
public void setJbpmEngine(String jbpmEngine)
{
this.jbpmEngineName = jbpmEngine;
}
/*
* (non-Javadoc)
* @see
* org.jbpm.taskmgmt.TaskInstanceFactory#createTaskInstance(org.jbpm.graph
* .exe.ExecutionContext)
*/ */
public TaskInstance createTaskInstance(ExecutionContext executionContext) public TaskInstance createTaskInstance(ExecutionContext executionContext)
{ {
return new WorkflowTaskInstance(); WorkflowTaskInstance taskInstance = new WorkflowTaskInstance();
taskInstance.setJbpmEngineName(jbpmEngineName);
return taskInstance;
} }
} }

View File

@@ -1,47 +1,91 @@
<jbpm-configuration>
<jbpm-context> <jbpm-configuration>
<service name="persistence">
<factory>
<bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="isCurrentSessionEnabled"><true/></field>
<field name="isTransactionEnabled"><false/></field>
</bean>
</factory>
</service>
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
<service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
<service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
</jbpm-context>
<!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar --> <jbpm-context>
<string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" /> <service name="persistence">
<string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" /> <factory>
<string name='resource.converter' value='org/alfresco/repo/workflow/jbpm/jbpm.converter.properties' /> <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<string name="resource.action.types" value="org/alfresco/repo/workflow/jbpm/jbpm.action.types.xml" /> <field name="isCurrentSessionEnabled">
<string name="resource.node.types" value="org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml" /> <true />
<string name="resource.parsers" value="org/alfresco/repo/workflow/jbpm/jbpm.parsers.xml" /> </field>
<string name="resource.varmapping" value="org/alfresco/repo/workflow/jbpm/jbpm.varmapping.xml" /> <field name="isTransactionEnabled">
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" /> <false />
</field>
</bean>
</factory>
</service>
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
<service name="scheduler"
factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
<service name="logging"
factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication"
factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
</jbpm-context>
<int name="jbpm.byte.block.size" value="1024" singleton="true" /> <!--
<string name="jbpm.mail.smtp.host" value="localhost" /> configuration resource files pointing to default configuration
<bean name="jbpm.task.instance.factory" class="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstanceFactory" singleton="true" /> files in jbpm-{version}.jar
<bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" /> -->
<bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" /> <string name="resource.business.calendar"
value="org/jbpm/calendar/jbpm.business.calendar.properties" />
<string name="resource.default.modules"
value="org/jbpm/graph/def/jbpm.default.modules.properties" />
<string name='resource.converter'
value='org/alfresco/repo/workflow/jbpm/jbpm.converter.properties' />
<string name="resource.action.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.action.types.xml" />
<string name="resource.node.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml" />
<string name="resource.parsers"
value="org/alfresco/repo/workflow/jbpm/jbpm.parsers.xml" />
<string name="resource.varmapping"
value="org/alfresco/repo/workflow/jbpm/jbpm.varmapping.xml" />
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
<bean name="jbpm.job.executor" class="org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutor"> <int name="jbpm.byte.block.size" value="1024" singleton="true" />
<field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field> <string name="jbpm.mail.smtp.host" value="localhost" />
<field name="name"><string value="AlfrescoJbpmJobExecutor" /></field> <bean name="jbpm.task.instance.factory"
<field name="nbrOfThreads"><int value="1" /></field> class="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstanceFactory"
<field name="idleInterval"><int value="90000" /></field> <!-- 15 minutes --> singleton="true">
<field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour --> <field name="jbpmEngineName">
<field name="historyMaxSize"><int value="20" /></field> <string value="test_jbpm_engine" />
<field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes --> </field>
<field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute --> </bean>
<field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds --> <bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver"
</bean> singleton="true" />
<bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver"
singleton="true" />
<bean name="jbpm.job.executor" class="org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutor">
<field name="jbpmConfiguration">
<ref bean="jbpmConfiguration" />
</field>
<field name="name">
<string value="AlfrescoJbpmJobExecutor" />
</field>
<field name="nbrOfThreads">
<int value="1" />
</field>
<field name="idleInterval">
<int value="90000" />
</field> <!-- 15 minutes -->
<field name="maxIdleInterval">
<int value="3600000" />
</field> <!-- 1 hour -->
<field name="historyMaxSize">
<int value="20" />
</field>
<field name="maxLockTime">
<int value="600000" />
</field> <!-- 10 minutes -->
<field name="lockMonitorInterval">
<int value="60000" />
</field> <!-- 1 minute -->
<field name="lockBufferTime">
<int value="5000" />
</field> <!-- 5 seconds -->
</bean>
</jbpm-configuration> </jbpm-configuration>

View File

@@ -0,0 +1,73 @@
/* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.namespace;
import java.util.Collection;
import org.alfresco.util.OneToManyHashBiMap;
/**
* A basic implementation of the NamespaceService interface intended for use in
* unit tests. This implementation does not persist any changes beyond the
* lifetime of the object.
*
* @author Nick Smith
*/
public class NamespaceServiceMemoryImpl implements NamespaceService
{
// URI to Prefix map.
private final OneToManyHashBiMap<String, String> map = new OneToManyHashBiMap<String, String>();
public void registerNamespace(String prefix, String uri)
{
map.putSingleValue(uri, prefix);
}
public void unregisterNamespace(String prefix)
{
map.removeValue(prefix);
}
public String getNamespaceURI(String prefix) throws NamespaceException
{
return map.getKey(prefix);
}
public Collection<String> getPrefixes(String namespaceURI) throws NamespaceException
{
return map.get(namespaceURI);
}
public Collection<String> getPrefixes()
{
return map.flatValues();
}
public Collection<String> getURIs()
{
return map.keySet();
}
}

View File

@@ -1,43 +1,83 @@
<jbpm-configuration> <jbpm-configuration>
<jbpm-context> <jbpm-context>
<service name="persistence" factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" /> <service name="persistence"
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" /> factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" /> <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" /> <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
<service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" /> <service name="scheduler"
<service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" /> factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
</jbpm-context> <service name="logging"
factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication"
factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
</jbpm-context>
<!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar --> <!--
<string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" /> configuration resource files pointing to default configuration
<string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" /> files in jbpm-{version}.jar
<string name='resource.converter' value='org/alfresco/repo/workflow/jbpm/jbpm.converter.properties' /> -->
<string name="resource.action.types" value="org/alfresco/repo/workflow/jbpm/jbpm.action.types.xml" /> <string name="resource.business.calendar"
<string name="resource.node.types" value="org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml" /> value="org/jbpm/calendar/jbpm.business.calendar.properties" />
<string name="resource.parsers" value="org/alfresco/repo/workflow/jbpm/jbpm.parsers.xml" /> <string name="resource.default.modules"
<string name="resource.varmapping" value="org/alfresco/repo/workflow/jbpm/jbpm.varmapping.xml" /> value="org/jbpm/graph/def/jbpm.default.modules.properties" />
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" /> <string name='resource.converter'
value='org/alfresco/repo/workflow/jbpm/jbpm.converter.properties' />
<string name="resource.action.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.action.types.xml" />
<string name="resource.node.types"
value="org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml" />
<string name="resource.parsers"
value="org/alfresco/repo/workflow/jbpm/jbpm.parsers.xml" />
<string name="resource.varmapping"
value="org/alfresco/repo/workflow/jbpm/jbpm.varmapping.xml" />
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
<int name="jbpm.byte.block.size" value="1024" singleton="true" /> <int name="jbpm.byte.block.size" value="1024" singleton="true" />
<string name="jbpm.mail.smtp.host" value="localhost" /> <string name="jbpm.mail.smtp.host" value="localhost" />
<bean name="jbpm.task.instance.factory" class="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstanceFactory" singleton="true" /> <bean name="jbpm.task.instance.factory"
<bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" /> class="org.alfresco.repo.workflow.jbpm.WorkflowTaskInstanceFactory"
<bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" /> singleton="true">
<field name="jbpmEngineName">
<string value="test_jbpm_engine" />
</field>
</bean>
<bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver"
singleton="true" />
<bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver"
singleton="true" />
<bean name="jbpm.job.executor" class="org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutor"> <bean name="jbpm.job.executor" class="org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutor">
<field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field> <field name="jbpmConfiguration">
<field name="name"><string value="AlfrescoJbpmJobExector" /></field> <ref bean="jbpmConfiguration" />
<field name="nbrOfThreads"><int value="1" /></field> </field>
<field name="name">
<string value="AlfrescoJbpmJobExector" />
</field>
<field name="nbrOfThreads">
<int value="1" />
</field>
<!-- overridden for WCM unit tests to 5 secs (was 1.5 mins) --> <!-- overridden for WCM unit tests to 5 secs (was 1.5 mins) -->
<field name="idleInterval"><int value="5000" /></field> <field name="idleInterval">
<int value="5000" />
</field>
<field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour --> <field name="maxIdleInterval">
<field name="historyMaxSize"><int value="20" /></field> <int value="3600000" />
<field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes --> </field> <!-- 1 hour -->
<field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute --> <field name="historyMaxSize">
<field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds --> <int value="20" />
</bean> </field>
<field name="maxLockTime">
<int value="600000" />
</field> <!-- 10 minutes -->
<field name="lockMonitorInterval">
<int value="60000" />
</field> <!-- 1 minute -->
<field name="lockBufferTime">
<int value="5000" />
</field> <!-- 5 seconds -->
</bean>
</jbpm-configuration> </jbpm-configuration>