/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jbpm.bpmn2.persistence;
import static org.jbpm.persistence.util.PersistenceUtil.JBPM_PERSISTENCE_UNIT_NAME;
import static org.jbpm.persistence.util.PersistenceUtil.cleanUp;
import static org.jbpm.persistence.util.PersistenceUtil.createEnvironment;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.jbpm.bpmn2.concurrency.MultipleProcessesPerThreadTest;
import org.jbpm.persistence.util.PersistenceUtil;
import org.jbpm.test.util.AbstractBaseTest;
import org.jbpm.test.util.CountDownProcessEventListener;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.persistence.jpa.JPAKnowledgeService;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UnmarshallingOverdueTimersTest extends AbstractBaseTest {
private static final Logger logger = LoggerFactory.getLogger(MultipleProcessesPerThreadTest.class);
private HashMap<String, Object> context;
@Before
public void setup() {
context = PersistenceUtil.setupWithPoolingDataSource(JBPM_PERSISTENCE_UNIT_NAME);
}
@After
public void tearDown() throws Exception {
cleanUp(context);
}
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 StatefulKnowledgeSession createStatefulKnowledgeSession(KnowledgeBase kbase) {
Environment env = createEnvironment(context);
return JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);
}
private static long knowledgeSessionDispose(StatefulKnowledgeSession ksession) {
long ksessionId = ksession.getIdentifier();
logger.debug("disposing of ksesssion");
ksession.dispose();
return ksessionId;
}
private StatefulKnowledgeSession reloadStatefulKnowledgeSession(String bpmn2FileName, int ksessionId) {
KnowledgeBase kbase = loadKnowledgeBase(bpmn2FileName);
logger.debug("reloading ksession {}", ksessionId);
Environment env = null;
env = createEnvironment(context);
return JPAKnowledgeService.loadStatefulKnowledgeSession(ksessionId, kbase, null, env);
}
private static long seconds = 2;
private static String timeUnit = "s";
private static String bpmn2FileName = "BPMN2-TimerInterrupted.bpmn2";
private static boolean debug = true;
@Test(timeout=10000)
public void startDisposeAndReloadTimerProcess() throws Exception {
CountDownProcessEventListener countDownListener = new CountDownProcessEventListener("timer", 1);
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);
ksession.addEventListener(countDownListener);
// 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
KieSessionConfiguration config = ksession.getSessionConfiguration();
long ksessionId = knowledgeSessionDispose(ksession);
// print info for next test
if( debug ) {
sessionPropVal = Long.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("Please wait at least {} [{}]", (seconds + timeUnit), sdf.format(cal.getTime()));
}
}
if( sessionPropVal != null || debug ) {
// reload session
int ksessionId = Integer.parseInt(sessionPropVal);
StatefulKnowledgeSession ksession = reloadStatefulKnowledgeSession(bpmn2FileName, ksessionId);
ksession.addEventListener(countDownListener);
long processInstanceId = Integer.parseInt(processPropVal);
logger.debug("! waiting 5 seconds for timer to fire");
countDownListener.waitTillCompleted();
ProcessInstance processInstance = ksession.getProcessInstance(processInstanceId);
if( processInstance != null ) {
assertTrue("Process has not terminated.", processInstance.getState() == ProcessInstance.STATE_COMPLETED );
}
}
}
}