package org.springmodules.workflow.jbpm30;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.jbpm.db.GraphSession;
import org.jbpm.db.JbpmSession;
import org.jbpm.db.JbpmSessionFactory;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springmodules.workflow.jbpm30.JbpmCallback;
import org.springmodules.workflow.jbpm30.JbpmSessionFactoryUtils;
import org.springmodules.workflow.jbpm30.JbpmTemplate;
/**
* @author Rob Harrop
*/
public class JbpmSessionFactoryUtilsTests extends AbstractDependencyInjectionSpringContextTests {
private static final Logger log = Logger.getLogger(JbpmSessionFactoryUtilsTests.class);
private JbpmSessionFactory jbpmSessionFactory;
private PlatformTransactionManager transactionManager;
private ProcessDefinition processDefinition;
/**
* @param processDefinition The processDefinition to set.
*/
public void setProcessDefinition(ProcessDefinition processDefinition) {
this.processDefinition = processDefinition;
}
public void setJbpmSessionFactory(JbpmSessionFactory jbpmSessionFactory) {
this.jbpmSessionFactory = jbpmSessionFactory;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void testGetSessionOutsideTransaction() {
log.info("getSessionOutsideTransaction");
JbpmSession firstJbpmSession = JbpmSessionFactoryUtils.getSession(this.jbpmSessionFactory);
assertNotNull(firstJbpmSession);
JbpmSession secondJbpmSession = JbpmSessionFactoryUtils.getSession(this.jbpmSessionFactory);
assertNotNull(secondJbpmSession);
assertNotSame(firstJbpmSession, secondJbpmSession);
// clean-up
JbpmSessionFactoryUtils.releaseSession(secondJbpmSession, this.jbpmSessionFactory);
JbpmSessionFactoryUtils.releaseSession(firstJbpmSession, this.jbpmSessionFactory);
}
public void testGetSessionInsideTransaction() {
log.info("getSessionInsideTransaction");
final Map sessionMap = new HashMap();
TransactionTemplate transactionTemplate = new TransactionTemplate(this.transactionManager);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
JbpmSession firstSession = JbpmSessionFactoryUtils.getSession(jbpmSessionFactory);
JbpmSession secondSession = JbpmSessionFactoryUtils.getSession(jbpmSessionFactory);
sessionMap.put("first", firstSession);
sessionMap.put("second", secondSession);
// try to close inside a transaction
JbpmSessionFactoryUtils.releaseSession(firstSession, jbpmSessionFactory);
assertTrue("Should not close session inside a transaction.",
firstSession.getSession().isOpen());
return null;
}
});
JbpmSession first = (JbpmSession) sessionMap.get("first");
JbpmSession second = (JbpmSession) sessionMap.get("second");
assertSame("Should've got the same session twice inside the transaction", first, second);
assertNull("Hibernate session should be closed", first.getSession());
assertNull("no current session", JbpmSession.getCurrentJbpmSession());
//assertFalse("Session not closed in synchronization", first.getSession().isOpen());
sessionMap.clear();
}
public void testReleaseOutsideTransaction() {
log.info("ReleaseOutsideTransaction");
JbpmSession jbpmSession = JbpmSessionFactoryUtils.getSession(this.jbpmSessionFactory);
JbpmSessionFactoryUtils.releaseSession(jbpmSession, this.jbpmSessionFactory);
assertNull("Session should be closed", jbpmSession.getSession());
}
/**
* Test the double session closing as reported here:
* http://opensource2.atlassian.com/projects/spring/browse/MOD-78
*
*/
public void testJbpmSessionSynchronization(){
log.info("jbpmSessionSynchronization");
TransactionTemplate transactionTemplate = new TransactionTemplate(this.transactionManager);
transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
JbpmTemplate jbpmTemplate = new JbpmTemplate(jbpmSessionFactory, processDefinition);
jbpmTemplate.execute(new JbpmCallback() {
public Object doInJbpm(JbpmSession session) {
session.getGraphSession().saveProcessDefinition(processDefinition);
return null;
}
});
return null;
}
});
}
/**
* Test IllegalArgumentException as reported here:
* http://opensource2.atlassian.com/projects/spring/browse/MOD-58
*
*/
public void testMultipleJBmpInvocations() {
log.info("multipleJbpmInvocation");
// Get Sessions
JbpmSession jbpmSession = JbpmSessionFactoryUtils.getSession(this.jbpmSessionFactory);
GraphSession graphSession = jbpmSession.getGraphSession();
graphSession.saveProcessDefinition(processDefinition);
// Get All Process Definitions
List l = graphSession.findLatestProcessDefinitions();
// Get the arbitrarily first Process Definition
ProcessDefinition pd = (ProcessDefinition) l.get(0);
// Load it again, individually
ProcessDefinition pd2 = graphSession.loadProcessDefinition(pd.getId());
// Create an instance of the Process Def with Task
ProcessInstance processInstance = new ProcessInstance(pd2);
TaskInstance jbpmTaskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
// Persist these changes
graphSession.saveProcessInstance(processInstance);
// Be polite, like the template is.
JbpmSessionFactoryUtils.releaseSession(jbpmSession, this.jbpmSessionFactory);
}
protected String[] getConfigLocations() {
return new String[] { "org/springmodules/workflow/jbpm30/applicationContext.xml" };
}
/**
* @see org.springframework.test.AbstractDependencyInjectionSpringContextTests#onSetUp()
*/
protected void onSetUp() throws Exception {
super.onSetUp();
if (JbpmSession.getCurrentJbpmSession() != null)
log.warn("*** current session not null!");
else
log.info("*** current session clean");
}
}