Skip to content
Browse files

BZ 820309: (test) overdue timers receive a null commandService when s…

…cheduled during ksession reloading (cherry picked from commit ac9a9cbe16fa398ad8175e70d0dba782d4808a67)
  • Loading branch information...
1 parent 88440fe commit 78d86be123fe45386dac8fe66621198e32b476fa @mrietveld mrietveld committed May 10, 2012
View
6 .gitignore
@@ -20,8 +20,4 @@ bin/
# Test info
/settings*.xml
/lib-jdbc/
-/jbpm-human-task/jbpm-human-task-core/target/
-/jbpm-human-task/jbpm-human-task-mina/target/
-/jbpm-human-task/jbpm-human-task-jms-hornetq/target/
-/jbpm-human-task/jbpm-human-task-jms/target/
-/jbpm-human-task/jbpm-human-task-hornetq/target/
+bitronix-default-config.properties
View
3 jbpm-bpmn2/.gitignore
@@ -13,4 +13,5 @@
/META-INF
# test files
-/JPADroolsFlow.*.db
+/*.db
+/btm*log
View
212 jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/persistence/UnmarshallingOverdueTimersTest.java
@@ -0,0 +1,212 @@
+package org.jbpm.bpmn2.persistence;
+import static junit.framework.Assert.*;
+import static org.drools.runtime.EnvironmentName.*;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.base.MapGlobalResolver;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.impl.EnvironmentFactory;
+import org.drools.io.ResourceFactory;
+import org.drools.persistence.jpa.JPAKnowledgeService;
+import org.drools.runtime.Environment;
+import org.drools.runtime.KnowledgeSessionConfiguration;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.process.ProcessInstance;
+import org.jbpm.bpmn2.concurrency.MultipleProcessesPerThreadTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import bitronix.tm.BitronixTransactionManager;
+import bitronix.tm.TransactionManagerServices;
+import bitronix.tm.resource.jdbc.PoolingDataSource;
+
+public class UnmarshallingOverdueTimersTest {
+
+ private static Logger logger = LoggerFactory.getLogger(MultipleProcessesPerThreadTest.class);
+
+ private static EntityManagerFactory emf;
+ private static PoolingDataSource pds;
+
+ @Before
+ public void setup() {
+ pds = new PoolingDataSource();
+
+ // The name must match what's in the persistence.xml!
+ pds.setUniqueName("jdbc/testDS1");
+
+ pds.setMaxPoolSize(16);
+ pds.setAllowLocalTransactions(true);
+
+ pds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
+ pds.getDriverProperties().put("user", "sa");
+ pds.getDriverProperties().put("password", "sasa");
+ pds.getDriverProperties().put("url", "jdbc:h2:file:jbpm-test");
+ pds.getDriverProperties().put("driverClassName", "org.h2.Driver" );
+
+ pds.init();
+
+ emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");
+ assertNotNull("EntityManagerFactory is null.", emf);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ BitronixTransactionManager txm = TransactionManagerServices.getTransactionManager();
+ if (txm != null) {
+ txm.shutdown();
+ }
+
+ try {
+ emf.close();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ try {
+ pds.close();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ }
+
+ private static KnowledgeBase loadKnowledgeBase(String bpmn2FileName) {
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add(ResourceFactory.newClassPathResource(bpmn2FileName, UnmarshallingOverdueTimersTest.class), ResourceType.BPMN2);
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
+ return kbase;
+ }
+
+ private static Environment createEnvironment() {
+ Environment env = EnvironmentFactory.newEnvironment();
+
+ env.set(ENTITY_MANAGER_FACTORY, emf);
+ env.set(TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
+ env.set(GLOBALS, new MapGlobalResolver());
+
+ return env;
+ }
+
+ private static StatefulKnowledgeSession createStatefulKnowledgeSession(KnowledgeBase kbase) {
+ Environment env = createEnvironment();
+ return JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
+ }
+
+ private static int knowledgeSessionDispose(StatefulKnowledgeSession ksession) {
+ int ksessionId = ksession.getId();
+ logger.debug("disposing of ksesssion");
+ ksession.dispose();
+ return ksessionId;
+ }
+
+ private static StatefulKnowledgeSession reloadStatefulKnowledgeSession(String bpmn2FileName, int ksessionId) {
+ KnowledgeBase kbase = loadKnowledgeBase(bpmn2FileName);
+
+ logger.debug(". reloading ksession " + ksessionId);
+ Environment env = null;
+ env = createEnvironment();
+
+ return JPAKnowledgeService.loadStatefulKnowledgeSession(ksessionId, kbase, null, env);
+ }
+
+ private static long seconds = 10;
+ private static String timeUnit = "s";
+ private static String bpmn2FileName = "BPMN2-TimerInterrupted.bpmn2";
+
+ private static boolean debug = true;
+
+ @Test
+ public void startDisposeAndReloadTimerProcess() throws Exception {
+ if( debug ) {
+ String shellVar = "TEST";
+ String shellVarVal = System.getenv(shellVar);
+ if( shellVarVal != null ) {
+ debug = false;
+ }
+ }
+
+ String sessionPropName = "KSESSION_ID";
+ String sessionPropVal = System.getenv(sessionPropName);
+ String processPropName = "PROCESS_ID";
+ String processPropVal = System.getenv(sessionPropName);
+
+ if (sessionPropVal == null || debug ) {
+ KnowledgeBase kbase = loadKnowledgeBase(bpmn2FileName);
+ StatefulKnowledgeSession ksession = createStatefulKnowledgeSession(kbase);
+
+ // setup parameters
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("time", seconds + timeUnit);
+
+ // note process start time
+ Calendar cal = GregorianCalendar.getInstance();
+
+ // start process
+ ProcessInstance processInstance = ksession.startProcess("interruptedTimer", params);
+ long processId = processInstance.getId();
+ // print info for next test
+ if( debug ) {
+ processPropVal = Long.toString(processId);
+ }
+ else {
+ logger.info("export " + processPropName + "=" + processId );
+ }
+
+ // dispose of session
+ KnowledgeSessionConfiguration config = ksession.getSessionConfiguration();
+ int ksessionId = knowledgeSessionDispose(ksession);
+
+ // print info for next test
+ if( debug ) {
+ sessionPropVal = Integer.toString(ksessionId);
+ }
+ else {
+ logger.info("export " + sessionPropName + "=" + ksessionId );
+
+ }
+
+ if( !debug ) {
+ cal.add(Calendar.SECOND, (int) seconds);
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
+ logger.info("\nPlease wait at least " + seconds + timeUnit + " [" + sdf.format(cal.getTime()) + "]\n" );
+ }
+ }
+
+ if( debug ) {
+ long wait = (long) ((double) seconds * 1000d * 1.1);
+ logger.debug("sleeping " + wait + " seconds" );
+ Thread.sleep(seconds * 1000 );
+ }
+
+ if( sessionPropVal != null || debug ) {
+ // reload session
+ int ksessionId = Integer.parseInt(sessionPropVal);
+ StatefulKnowledgeSession ksession = reloadStatefulKnowledgeSession(bpmn2FileName, ksessionId);
+ long processInstanceId = Integer.parseInt(processPropVal);
+
+ logger.debug("! waiting 5 seconds for timer to fire");
+ Thread.sleep(5 * 1000);
+
+ ProcessInstance processInstance = ksession.getProcessInstance(processInstanceId);
+ if( processInstance != null ) {
+ assertTrue("Process has not terminated.", processInstance.getState() == ProcessInstance.STATE_COMPLETED );
+ }
+ }
+ }
+}
View
94 jbpm-bpmn2/src/test/resources/BPMN2-TimerInterrupted.bpmn2
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.omg.org/bpmn20"
+ xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:drools="http://www.jboss.org/drools"
+ id="_df_GEJnmEeG1YvOsUtyHvw"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
+ targetNamespace="http://www.omg.org/bpmn20">
+
+ <bpmn2:itemDefinition id="_timeItem" structureRef="String"/>
+
+ <bpmn2:process id="interruptedTimer" isExecutable="true">
+
+ <bpmn2:property id="time" itemSubjectRef="_timeItem"/>
+
+ <bpmn2:startEvent id="_1" drools:bgcolor="#ffffff" name="">
+ <bpmn2:outgoing>_1-2</bpmn2:outgoing>
+ </bpmn2:startEvent>
+
+ <bpmn2:scriptTask id="_2" name="start" scriptFormat="http://www.java.com/java">
+ <bpmn2:incoming>_1-2</bpmn2:incoming>
+ <bpmn2:outgoing>_2-3</bpmn2:outgoing>
+ <bpmn2:script><![CDATA[System.out.println("- process start");]]></bpmn2:script>
+ </bpmn2:scriptTask>
+
+ <bpmn2:sequenceFlow id="_1-2" sourceRef="_1" targetRef="_2"/>
+
+ <bpmn2:sequenceFlow id="_2-3" sourceRef="_2" targetRef="_3"/>
+
+ <bpmn2:intermediateCatchEvent id="_3" drools:bgcolor="#ffffff" drools:boundaryca="false" name="">
+ <bpmn2:incoming>_2-3</bpmn2:incoming>
+ <bpmn2:outgoing>_3-4</bpmn2:outgoing>
+ <bpmn2:timerEventDefinition id="_6">
+ <bpmn2:timeCycle xsi:type="bpmn2:tFormalExpression" id="_7">#{time}</bpmn2:timeCycle>
+ </bpmn2:timerEventDefinition>
+ </bpmn2:intermediateCatchEvent>
+
+ <bpmn2:scriptTask id="_4" name="end" scriptFormat="http://www.java.com/java">
+ <bpmn2:incoming>_3-4</bpmn2:incoming>
+ <bpmn2:outgoing>_4-5</bpmn2:outgoing>
+ <bpmn2:script><![CDATA[System.out.println("- process end");]]></bpmn2:script>
+ </bpmn2:scriptTask>
+
+ <bpmn2:sequenceFlow id="_3-4" sourceRef="_3" targetRef="_4"/>
+
+ <bpmn2:endEvent id="_5" drools:bgcolor="#ffffff" name="">
+ <bpmn2:incoming>_4-5</bpmn2:incoming>
+ </bpmn2:endEvent>
+
+ <bpmn2:sequenceFlow id="_4-5" sourceRef="_4" targetRef="_5"/>
+
+ </bpmn2:process>
+
+ <bpmndi:BPMNDiagram id="_df_tIpnmEeG1YvOsUtyHvw">
+ <bpmndi:BPMNPlane id="_df_tI5nmEeG1YvOsUtyHvw" bpmnElement="defaultPackage.TimerProcess">
+ <bpmndi:BPMNShape id="_df_tJJnmEeG1YvOsUtyHvw" bpmnElement="_1">
+ <dc:Bounds height="30.0" width="30.0" x="49.0" y="121.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_df_tJZnmEeG1YvOsUtyHvw" bpmnElement="_2">
+ <dc:Bounds height="80.0" width="100.0" x="124.0" y="96.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="_df_tJpnmEeG1YvOsUtyHvw" bpmnElement="_1-2">
+ <di:waypoint xsi:type="dc:Point" x="64.0" y="136.0"/>
+ <di:waypoint xsi:type="dc:Point" x="174.0" y="136.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge id="_df_tJ5nmEeG1YvOsUtyHvw" bpmnElement="_2-3">
+ <di:waypoint xsi:type="dc:Point" x="174.0" y="136.0"/>
+ <di:waypoint xsi:type="dc:Point" x="284.0" y="136.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_df_tKJnmEeG1YvOsUtyHvw" bpmnElement="_3">
+ <dc:Bounds height="30.0" width="30.0" x="269.0" y="121.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_df_tKZnmEeG1YvOsUtyHvw" bpmnElement="_4">
+ <dc:Bounds height="80.0" width="100.0" x="344.0" y="96.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="_df_tKpnmEeG1YvOsUtyHvw" bpmnElement="_3-4">
+ <di:waypoint xsi:type="dc:Point" x="284.0" y="136.0"/>
+ <di:waypoint xsi:type="dc:Point" x="394.0" y="136.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNShape id="_df_tK5nmEeG1YvOsUtyHvw" bpmnElement="_5">
+ <dc:Bounds height="28.0" width="28.0" x="484.0" y="117.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge id="_df_tLJnmEeG1YvOsUtyHvw" bpmnElement="_4-5">
+ <di:waypoint xsi:type="dc:Point" x="394.0" y="136.0"/>
+ <di:waypoint xsi:type="dc:Point" x="498.0" y="131.0"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+
+</bpmn2:definitions>

0 comments on commit 78d86be

Please sign in to comment.
Something went wrong with that request. Please try again.