To integrate Spring with the Runtime Manager API, include the following factory beans:
org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean
org.kie.spring.factorybeans.RuntimeManagerFactoryBean
org.kie.spring.factorybeans.TaskServiceFactoryBean
TaskServiceFactoryBean is required only for shared task service.
RuntimeEnvironmentFactoryBean
RuntimeEnvironmentFactoryBean produces RuntimeEnvironment instances consumed by RuntimeManager.
You can create the following types of RuntimeEnvironment instances:
DEFAULT: The default type.
EMPTY: An empty environment.
DEFAULT_IN_MEMORY: Same as DEFAULT with no persistence of the runtime engine.
DEFAULT_KJAR: Same as DEFAULT with knowledge assets taken from kJAR and identified by releaseID or GAV (Group, Artifact, Version).
DEFAULT_KJAR_CL: Built from class path that consists of a kmodule.xml descriptor.
Knowledge information is required for all the RuntimeEnvironment types. Provide one or more of the following:
knowledgeBase
assets
releaseId
groupId, artifactId, version
For the DEFAULT, DEFAULT_KJAR, DEFAULT_KJAR_CL types, configure persistence using entity manager factory or transaction manager.
RuntimeManagerFactoryBean
RuntimeManagerFactoryBean creates RuntimeManager instances based on runtimeEnvironment. You can create the following runtimeEnvironment instances:
SINGLETON (default)
PER_REQUEST
PER_PROCESS_INSTANCE
Every RuntimeManager instance must have a unique ID. You can dispose of any RuntimeManager instance created by RuntimeManagerFactoryBean by calling the close() method.
TaskServiceFactoryBean
TaskServiceFactoryBean creates TaskService instance based on the given properties. Creates a single instance only.
Properties required:
entity manager factory
transaction manager
When using the TaskServiceFactoryBean, provide the Spring transaction manager. When using a shared entity manager from Spring, you can also provide EntityManager instance instead of entity manager factory.
Optional properties:
userGroupCallback: MVELUserGroupCallbackImpl by default.
userInfo: DefaultUserInfo by default.
listener: List of TaskLifeCycleEventListener instances.
Sample RuntimeManager Configuration with Spring
To create a single runtime manager Spring configuration:
Configure the entity manager factory and the transaction manager, for example:
<bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"></bean>
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
<bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"></bean>
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
<bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
This configuration provides:
JTA transaction manager, backed by Bitronix for unit tests or servlet containers.
The org.jbpm.persistence.spring.jta entity manager factory for persistence unit.
Configure resources you use, for example a business process:
<bean id="process" factory-method="newclass pathResource" class="org.kie.internal.io.ResourceFactory">
<constructor-arg>
<value>jbpm/processes/sample.bpmn</value>
</constructor-arg>
</bean>
<bean id="process" factory-method="newclass pathResource" class="org.kie.internal.io.ResourceFactory">
<constructor-arg>
<value>jbpm/processes/sample.bpmn</value>
</constructor-arg>
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
The sample.bpmn process is included from the class path.
Configure RuntimeEnvironment using your entity manager, transaction manager, and resources:
<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
<property name="type" value="DEFAULT"/>
<property name="entityManagerFactory" ref="jbpmEMF"/>
<property name="transactionManager" ref="jbpmTxManager"/>
<property name="assets">
<map>
<entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
</map>
</property>
</bean>
<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
<property name="type" value="DEFAULT"/>
<property name="entityManagerFactory" ref="jbpmEMF"/>
<property name="transactionManager" ref="jbpmTxManager"/>
<property name="assets">
<map>
<entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
</map>
</property>
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Create RuntimeManager:
<bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close">
<property name="identifier" value="spring-rm"/>
<property name="runtimeEnvironment" ref="runtimeEnvironment"/>
</bean>
<bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close">
<property name="identifier" value="spring-rm"/>
<property name="runtimeEnvironment" ref="runtimeEnvironment"/>
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
An example of complete configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<import resource="classpath:jbpm/configuration-template/assets.xml" />
<bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
<property name="persistenceXmlLocation" value="classpath:jbpm/persistence-jta.xml"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"/>
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
<bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
<property name="type" value="DEFAULT"/>
<property name="entityManagerFactory" ref="jbpmEMF"/>
<property name="transactionManager" ref="jbpmTxManager"/>
<property name="assets" ref="assets"/>
</bean>
<bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService" depends-on="runtimeEnvironment">
<constructor-arg value="#{runtimeEnvironment.environment}" />
<constructor-arg value="STANDALONE_JTA" />
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<import resource="classpath:jbpm/configuration-template/assets.xml" />
<bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
<property name="persistenceXmlLocation" value="classpath:jbpm/persistence-jta.xml"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"/>
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
<bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
<property name="type" value="DEFAULT"/>
<property name="entityManagerFactory" ref="jbpmEMF"/>
<property name="transactionManager" ref="jbpmTxManager"/>
<property name="assets" ref="assets"/>
</bean>
<bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService" depends-on="runtimeEnvironment">
<constructor-arg value="#{runtimeEnvironment.environment}" />
<constructor-arg value="STANDALONE_JTA" />
</bean>
</beans>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
If you require multiple runtime managers, you can use jBPM services directly in your application. Due to the dynamic nature of jBPM services, processes and other assets can be added and removed without restarting your application.
To configure jBPM services, implement the IdentityProvider interface:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.kie.internal.identity.IdentityProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
public class SpringSecurityIdentityProvider implements IdentityProvider {
public String getName() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
return auth.getName();
}
return "system";
}
public List<String> getRoles() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
List<String> roles = new ArrayList<String>();
for (GrantedAuthority ga : auth.getAuthorities()) {
roles.add(ga.getAuthority());
}
return roles;
}
return Collections.emptyList();
}
public boolean hasRole(String role) {
return false;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.kie.internal.identity.IdentityProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
public class SpringSecurityIdentityProvider implements IdentityProvider {
public String getName() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
return auth.getName();
}
return "system";
}
public List<String> getRoles() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
List<String> roles = new ArrayList<String>();
for (GrantedAuthority ga : auth.getAuthorities()) {
roles.add(ga.getAuthority());
}
return roles;
}
return Collections.emptyList();
}
public boolean hasRole(String role) {
return false;
}
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
To configure jBPM services in a Spring application:
Configure the transaction manager:
<context:annotation-config />
<tx:annotation-driven />
<tx:jta-transaction-manager />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
<context:annotation-config />
<tx:annotation-driven />
<tx:jta-transaction-manager />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Configure JPA and persistence:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="transactionManager">
<property name="persistenceXmlLocation" value="classpath:/META-INF/jbpm-persistence.xml" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="transactionManager">
<property name="persistenceXmlLocation" value="classpath:/META-INF/jbpm-persistence.xml" />
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Configure security providers:
<util:properties id="roleProperties" location="classpath:/roles.properties" />
<bean id="userGroupCallback" class="org.jbpm.services.task.identity.JBossUserGroupCallbackImpl">
<constructor-arg name="userGroups" ref="roleProperties"></constructor-arg>
</bean>
<bean id="identityProvider" class="org.jbpm.spring.SpringSecurityIdentityProvider"/>
<util:properties id="roleProperties" location="classpath:/roles.properties" />
<bean id="userGroupCallback" class="org.jbpm.services.task.identity.JBossUserGroupCallbackImpl">
<constructor-arg name="userGroups" ref="roleProperties"></constructor-arg>
</bean>
<bean id="identityProvider" class="org.jbpm.spring.SpringSecurityIdentityProvider"/>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
Configure the runtime manager factory:
<bean id="runtimeManagerFactory" class="org.kie.spring.manager.SpringRuntimeManagerFactoryImpl">
<property name="transactionManager" ref="transactionManager"/>
<property name="userGroupCallback" ref="userGroupCallback"/>
</bean>
<bean id="transactionCmdService" class="org.jbpm.shared.services.impl.TransactionalCommandService">
<constructor-arg name="emf" ref="entityManagerFactory"></constructor-arg>
</bean>
<bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="userGroupCallback" ref="userGroupCallback"/>
<property name="listeners">
<list>
<bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener">
<constructor-arg value="true"/>
</bean>
</list>
</property>
</bean>
<bean id="runtimeManagerFactory" class="org.kie.spring.manager.SpringRuntimeManagerFactoryImpl">
<property name="transactionManager" ref="transactionManager"/>
<property name="userGroupCallback" ref="userGroupCallback"/>
</bean>
<bean id="transactionCmdService" class="org.jbpm.shared.services.impl.TransactionalCommandService">
<constructor-arg name="emf" ref="entityManagerFactory"></constructor-arg>
</bean>
<bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="userGroupCallback" ref="userGroupCallback"/>
<property name="listeners">
<list>
<bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener">
<constructor-arg value="true"/>
</bean>
</list>
</property>
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
The runtime manager factory is Spring context aware and can interact with Spring containers.
Configure jBPM services as Spring beans:
<!-- definition service -->
<bean id="definitionService" class="org.jbpm.kie.services.impl.bpmn2.BPMN2DataServiceImpl"/>
<!-- runtime data service -->
<bean id="runtimeDataService" class="org.jbpm.kie.services.impl.RuntimeDataServiceImpl">
<property name="commandService" ref="transactionCmdService"/>
<property name="identityProvider" ref="identityProvider"/>
<property name="taskService" ref="taskService"/>
</bean>
<!-- -- deployment service -->
<bean id="deploymentService" class="org.jbpm.kie.services.impl.KModuleDeploymentService" depends-on="entityManagerFactory" init-method="onInit">
<property name="bpmn2Service" ref="definitionService"/>
<property name="emf" ref="entityManagerFactory"/>
<property name="managerFactory" ref="runtimeManagerFactory"/>
<property name="identityProvider" ref="identityProvider"/>
<property name="runtimeDataService" ref="runtimeDataService"/>
</bean>
<!-- process service -->
<bean id="processService" class="org.jbpm.kie.services.impl.ProcessServiceImpl" depends-on="deploymentService">
<property name="dataService" ref="runtimeDataService"/>
<property name="deploymentService" ref="deploymentService"/>
</bean>
<!-- user task service -->
<bean id="userTaskService" class="org.jbpm.kie.services.impl.UserTaskServiceImpl" depends-on="deploymentService">
<property name="dataService" ref="runtimeDataService"/>
<property name="deploymentService" ref="deploymentService"/>
</bean>
<!-- register runtime data service as listener on deployment service so it can receive notification about deployed and undeployed units -->
<bean id="data" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="deploymentService">
<property name="targetObject" ref="deploymentService"></property>
<property name="targetMethod"><value>addListener</value></property>
<property name="arguments">
<list>
<ref bean="runtimeDataService"/>
</list>
</property>
</bean>
<!-- definition service -->
<bean id="definitionService" class="org.jbpm.kie.services.impl.bpmn2.BPMN2DataServiceImpl"/>
<!-- runtime data service -->
<bean id="runtimeDataService" class="org.jbpm.kie.services.impl.RuntimeDataServiceImpl">
<property name="commandService" ref="transactionCmdService"/>
<property name="identityProvider" ref="identityProvider"/>
<property name="taskService" ref="taskService"/>
</bean>
<!-- -- deployment service -->
<bean id="deploymentService" class="org.jbpm.kie.services.impl.KModuleDeploymentService" depends-on="entityManagerFactory" init-method="onInit">
<property name="bpmn2Service" ref="definitionService"/>
<property name="emf" ref="entityManagerFactory"/>
<property name="managerFactory" ref="runtimeManagerFactory"/>
<property name="identityProvider" ref="identityProvider"/>
<property name="runtimeDataService" ref="runtimeDataService"/>
</bean>
<!-- process service -->
<bean id="processService" class="org.jbpm.kie.services.impl.ProcessServiceImpl" depends-on="deploymentService">
<property name="dataService" ref="runtimeDataService"/>
<property name="deploymentService" ref="deploymentService"/>
</bean>
<!-- user task service -->
<bean id="userTaskService" class="org.jbpm.kie.services.impl.UserTaskServiceImpl" depends-on="deploymentService">
<property name="dataService" ref="runtimeDataService"/>
<property name="deploymentService" ref="deploymentService"/>
</bean>
<!-- register runtime data service as listener on deployment service so it can receive notification about deployed and undeployed units -->
<bean id="data" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="deploymentService">
<property name="targetObject" ref="deploymentService"></property>
<property name="targetMethod"><value>addListener</value></property>
<property name="arguments">
<list>
<ref bean="runtimeDataService"/>
</list>
</property>
</bean>
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow