/* * 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.persistence.session; import static org.jbpm.persistence.util.PersistenceUtil.*; import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import javax.naming.InitialContext; import javax.transaction.UserTransaction; import org.jbpm.persistence.processinstance.JPAProcessInstanceManager; import org.jbpm.test.util.AbstractBaseTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.kie.api.io.ResourceType; import org.kie.api.runtime.Environment; import org.kie.internal.KnowledgeBase; 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; /** * This test looks at the behavior of the {@link JPAProcessInstanceManager} * with regards to created (but not started) process instances * and whether the process instances are available or not after creation. */ @RunWith(Parameterized.class) public class GetProcessInstancesTest extends AbstractBaseTest { private HashMap<String, Object> context; private Environment env; private KnowledgeBase kbase; private long sessionId; public GetProcessInstancesTest(boolean locking) { this.useLocking = locking; } @Parameters public static Collection<Object[]> persistence() { Object[][] data = new Object[][] { { false }, { true } }; return Arrays.asList(data); }; @Before public void setUp() throws Exception { context = setupWithPoolingDataSource(JBPM_PERSISTENCE_UNIT_NAME); env = createEnvironment(context); kbase = createBase(); StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env); sessionId = ksession.getIdentifier(); ksession.dispose(); } @After public void tearDown() throws Exception { cleanUp(context); } @Test public void getEmptyProcessInstances() throws Exception { StatefulKnowledgeSession ksession = reloadKnowledgeSession(); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); } @Test public void create2ProcessInstances() throws Exception { long[] processId = new long[2]; StatefulKnowledgeSession ksession = reloadKnowledgeSession(); processId[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); processId[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); ksession.dispose(); assertProcessInstancesExist(processId); } @Test public void create2ProcessInstancesInsideTransaction() throws Exception { long[] processId = new long[2]; UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" ); ut.begin(); StatefulKnowledgeSession ksession = reloadKnowledgeSession(); processId[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); processId[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); assertEquals(2, ksession.getProcessInstances().size()); // process instance manager cache flushed on tx ut.commit(); assertEquals(0, ksession.getProcessInstances().size()); ksession = reloadKnowledgeSession(ksession); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); assertProcessInstancesExist(processId); } @Test public void noProcessInstancesLeftAfterRollback() throws Exception { long[] notProcess = new long[2]; UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" ); ut.begin(); StatefulKnowledgeSession ksession = reloadKnowledgeSession(); notProcess[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); notProcess[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); assertEquals(2, ksession.getProcessInstances().size()); ut.rollback(); // Validate that proc inst mgr cache is also flushed on rollback assertEquals(0, ksession.getProcessInstances().size()); ksession = reloadKnowledgeSession(ksession); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); assertProcessInstancesNotExist(notProcess); } @Test public void noProcessInstancesLeftWithPreTxKSessionAndRollback() throws Exception { long[] notProcess = new long[4]; StatefulKnowledgeSession ksession = reloadKnowledgeSession(); UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" ); ut.begin(); notProcess[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); notProcess[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); ut.rollback(); // Validate that proc inst mgr cache is also flushed on rollback assertEquals(0, ksession.getProcessInstances().size()); ksession = reloadKnowledgeSession(ksession); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); assertProcessInstancesNotExist(notProcess); } /** * Helper functions */ private void assertProcessInstancesExist(long[] processId) { StatefulKnowledgeSession ksession = reloadKnowledgeSession(); for (long id : processId) { assertNotNull("Process instance " + id + " should not exist!", ksession.getProcessInstance(id)); } } private void assertProcessInstancesNotExist(long[] processId) { StatefulKnowledgeSession ksession = reloadKnowledgeSession(); for (long id : processId) { assertNull(ksession.getProcessInstance(id)); } } private KnowledgeBase createBase() { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource("processinstance/HelloWorld.rf"), ResourceType.DRF); assertFalse(kbuilder.getErrors().toString(), kbuilder.hasErrors()); return kbuilder.newKnowledgeBase(); } private StatefulKnowledgeSession reloadKnowledgeSession() { return JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, env); } private StatefulKnowledgeSession reloadKnowledgeSession(StatefulKnowledgeSession ksession) { ksession.dispose(); return reloadKnowledgeSession(); } }