Activiti BPM Tutorial – Spring Configuration

Activiti Spring Configuration
1. Activiti Configuration using XML
1.1 Activiti Configuration XML Test
2. Activiti Configuration using Annotations
2.1 Activiti Configuration Annotation Test

1. Activiti Configuration using XML

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans    
                           http://www.springframework.org/schema/beans/spring-beans.xsd 
                           http://www.springframework.org/schema/context  
                           http://www.springframework.org/schema/context/spring-context-2.5.xsd 
                           http://www.springframework.org/schema/tx       
                           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
			<property name="driverClass" value="org.h2.Driver" />
			<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
			<property name="username" value="sa" />
			<property name="password" value="" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
		<property name="databaseType" value="h2" />
		<property name="dataSource" ref="dataSource" />
		<property name="transactionManager" ref="transactionManager" />
		<property name="databaseSchemaUpdate" value="true" />
		<property name="deploymentResources"
			value="classpath*:diagrams/underwriting_queue.bpmn" />
		<property name="history" value="audit" />
		<property name="jobExecutorActivate" value="false" />
	</bean>

	<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
		<property name="processEngineConfiguration" ref="processEngineConfiguration" />
	</bean>

	<bean id="repositoryService" factory-bean="processEngine"
		factory-method="getRepositoryService" />
	<bean id="runtimeService" factory-bean="processEngine"
		factory-method="getRuntimeService" />
	<bean id="taskService" factory-bean="processEngine"
		factory-method="getTaskService" />
	<bean id="historyService" factory-bean="processEngine"
		factory-method="getHistoryService" />
	<bean id="managementService" factory-bean="processEngine"
		factory-method="getManagementService" />
</beans>

1.1 Activiti Configuration XML Test

package com.nuke.activiti.spring;

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.nuke.activiti.common.AbstractTest;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-test-application-context.xml")
public class SpringTest extends AbstractTest {

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	private TaskService taskService;

	@Test
	public void simpleProcessTest() {
		Map<String, Object> variableMap = new HashMap<String, Object>();
		variableMap.put("LoanId", 123456789);
		runtimeService.startProcessInstanceByKey("underwritingQueue", variableMap);
		Task task = taskService.createTaskQuery().singleResult();
		assertEquals("Unassigned Loan", task.getName());
		taskService.complete(task.getId());
		assertEquals(1, runtimeService.createProcessInstanceQuery().count());
	}
}

2. Activiti Configuration using Annotations

package com.nuke.config;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.impl.HistoryServiceImpl;
import org.activiti.engine.impl.ManagementServiceImpl;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.TaskServiceImpl;
import org.activiti.engine.impl.history.HistoryLevel;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.annotations.AbstractActivitiConfigurer;
import org.activiti.spring.annotations.EnableActiviti;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.nuke.ldap.LDAPConnectionParams;
import com.nuke.ldap.LDAPGroupManagerFactory;
import com.nuke.ldap.LDAPUserManagerFactory;

@Configuration
@EnableActiviti
@EnableTransactionManagement(proxyTargetClass = true)
//@PropertySource("file:conf/lc-merged.properties")
public class ActivitConfiguration {
 
    @Bean
    public DataSource inMemoryDataSource() {
        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setUsername("sa");
        basicDataSource.setUrl("jdbc:h2:mem:activiti");
        basicDataSource.setDefaultAutoCommit(false);
        basicDataSource.setDriverClassName(org.h2.Driver.class.getName());
        basicDataSource.setPassword("");
        return basicDataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource inMemoryDataSource) {
	  LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
      localContainerEntityManagerFactoryBean.setDataSource(inMemoryDataSource);
      localContainerEntityManagerFactoryBean.setPackagesToScan(new String[]{"com.nuke.model"});
      localContainerEntityManagerFactoryBean.setPersistenceUnitName("nuke");
      HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
      
      jpaVendorAdapter.setGenerateDdl(false);
      jpaVendorAdapter.setShowSql(false);
      jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
      localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
      return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager jpaTransactionManager(EntityManagerFactory entityManagerFactoryBean) {
        return new JpaTransactionManager(entityManagerFactoryBean);
    } 
    
    @Value("${LC_NUKE_LDAP_URL:localhost}")
	private String ldapServer;
	@Value("${LC_NUKE_LDAP_PORT}")
	private String ldapPort;
	@Value("${LC_NUKE_LDAP_USERNAME:uid=admin,ou=system}")
	private String ldapUser;
	@Value("${LC_NUKE_LDAP_PASSWORD:secret}")
	private String ldapPassword;
	
	@Bean
	public LDAPConnectionParams ldapConnection(){
		LDAPConnectionParams ldapConnection = new LDAPConnectionParams();
		ldapConnection.setLdapServer(ldapServer);
		ldapConnection.setLdapPort(10389);
		ldapConnection.setLdapUser(ldapUser);
		ldapConnection.setLdapPassword(ldapPassword);
		return ldapConnection;
	}
    
    
	@Value("${LC_NUKE_MAIL_HOST}")
	private String mailHost;
	@Value("${LC_NUKE_MAIL_USERNAME}")
	private String mailUsername;
	@Value("${LC_NUKE_MAIL_PASSWORD}")
	private String mailServerPassword;
	
    @Bean
    public AbstractActivitiConfigurer abstractActivitiConfigurer(final EntityManagerFactory entityManagerFactoryBean, final PlatformTransactionManager jpaTransactionManager) {
        return new AbstractActivitiConfigurer() {
            @Override
            public void postProcessSpringProcessEngineConfiguration(SpringProcessEngineConfiguration engine) {
            	engine.setDatabaseType("h2");
            	engine.setDataSource(inMemoryDataSource());
                engine.setTransactionManager(jpaTransactionManager);
                engine.setJpaEntityManagerFactory(entityManagerFactoryBean);
                engine.setJpaHandleTransaction(true);
                engine.setJobExecutorActivate(true);
                engine.setJpaCloseEntityManager(false);
                engine.setMailServerDefaultFrom("nucleus@lc.com");
                engine.setMailServerHost(mailHost);
                engine.setMailServerPort(587);
                engine.setMailServerUsername(mailUsername);
                engine.setMailServerPassword(mailServerPassword);
                engine.setMailServerUseSSL(true);
                engine.setMailServerUseTLS(true);
                engine.setRepositoryService(repositoryService());
                engine.setTaskService(taskService());
                engine.setManagementService(managementService());
                engine.setRuntimeService(runtimeService());
                engine.setHistoryService(historyService());
                engine.setHistoryLevel(HistoryLevel.AUDIT);
                Resource[] processResources = new Resource[1] ;
                Resource underwritingQueueProcess = new ClassPathResource("diagrams/underwriting_queue.bpmn");
                processResources[0]=underwritingQueueProcess;
                engine.setDeploymentResources(processResources);
                List<SessionFactory> customSessionFactories = new ArrayList<SessionFactory>();
                customSessionFactories.add(new LDAPGroupManagerFactory(ldapConnection()));
                customSessionFactories.add(new LDAPUserManagerFactory(ldapConnection()));
        		engine.setCustomSessionFactories(customSessionFactories);
                
                engine.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
            }
        };
    }
    
    @Bean
    public RepositoryServiceImpl repositoryService(){
    	RepositoryServiceImpl repositoryService = new RepositoryServiceImpl();
    	return repositoryService;
    }
    
    @Bean
    public TaskServiceImpl taskService(){
    	TaskServiceImpl taskService = new TaskServiceImpl();
    	return taskService;
    }
    
    @Bean
    public ManagementServiceImpl managementService(){
    	ManagementServiceImpl managementService = new ManagementServiceImpl();
    	return managementService;
    }
    
    @Bean
    public RuntimeServiceImpl runtimeService(){
    	RuntimeServiceImpl runtimeService = new RuntimeServiceImpl();
    	return runtimeService;
    }
    
    @Bean
    public HistoryServiceImpl historyService(){
    	HistoryServiceImpl historyService = new HistoryServiceImpl();
    	return historyService;
    }    
}

2.1 Activiti Configuration Annotation Test

package com.nuke.activiti.spring;

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.nuke.config.ActivitConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=ActivitConfiguration.class)
public class SpringWithAnnotations {

	@Autowired
	private RuntimeService runtimeService;
	
	@Autowired
	private TaskService taskService;

	@Test
	public void simpleProcessTest() {
		Map<String, Object> variableMap = new HashMap<String, Object>();
		variableMap.put("LoanId", 123456789);
		runtimeService.startProcessInstanceByKey("underwritingQueue", variableMap);
		Task task = taskService.createTaskQuery().singleResult();
		assertEquals("Unassigned Loan", task.getName());
		taskService.complete(task.getId());
		assertEquals(1, runtimeService.createProcessInstanceQuery().count());
	}
}

1 Comment

  1. Mark Jochum says:

    I liked the post, but it seems that Activiti dropped support for annotation based config in 5.16.4. I was looking around for how to implement a Spring java config approach to creating Activiti beans and landed here. It’s a shame that there isn’t more documentation on the Activiti-Spring maven artifact and the intended use of the API.

    see post: http://forums.activiti.org/content/enableactiviti-5164

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s