/* * Copyright 2013 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. * You may obtain a copy of the License at * * 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.kie.spring.timer; import static org.junit.Assert.*; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import org.drools.core.base.MapGlobalResolver; import org.kie.api.KieBase; import org.kie.api.persistence.jpa.KieStoreServices; import org.kie.api.runtime.Environment; import org.kie.api.runtime.EnvironmentName; import org.kie.api.runtime.KieSession; import org.kie.internal.KnowledgeBaseFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.orm.jpa.JpaTransactionManager; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; public class MyDroolsBean { private static AtomicInteger timerTriggerCount = new AtomicInteger(); private static long sessionId; private static Logger logger = LoggerFactory.getLogger(MyDroolsBean.class); private EntityManagerFactory emf; private KieBase kbase; private KieStoreServices kstore; private JpaTransactionManager txm; private TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2); public void initStartDisposeAndLoadSession() { try { EntityManager em = txm.getEntityManagerFactory().createEntityManager(); // create new ksession with kstore KieSession ksession = kstore.newKieSession(kbase, null, getEnvironment()); sessionId = ksession.getIdentifier(); logger.debug("\n\tSession id: " + sessionId + "\n"); ksession.getWorkItemManager().registerWorkItemHandler("testWorkItemHandler", workItemHandler); ksession.startProcess("timer-flow", null); // wait for process to start and for first timer to finish waitForOtherThread(); ksession.dispose(); } catch (Exception ex) { throw new IllegalStateException("The endTheProcess method has been interrupted", ex); } } public static void waitForOtherThread() { try { cyclicBarrier.await(); } catch( InterruptedException ie ) { // do nothing } catch( BrokenBarrierException bbe ) { logger.error("cyclic barrier has a broken state!", bbe ); } } public static void incrementTimerTriggerCount() { timerTriggerCount.incrementAndGet(); } public static int getTimerTriggerCount() { return timerTriggerCount.get(); } public void endTheProcess() { try { KieSession ksession = kstore.loadKieSession(sessionId, kbase, null, getEnvironment()); //Sleep to check if the timer continues executing. logger.debug("\n\nSleeping to check that the timer is still running"); // wait for a possible timer to run try { cyclicBarrier.await(3, TimeUnit.SECONDS); } catch( BrokenBarrierException e1 ) { // do nothing } catch( TimeoutException e1 ) { // do nothing } ksession.getWorkItemManager().completeWorkItem(TestWorkItemHandler.getWorkItem().getId(), null); logger.debug("\n\nSleeping to check that the timer is no longer running"); boolean waitFailed = false; try { cyclicBarrier.await(3, TimeUnit.SECONDS); fail( "The timer should not have been running!" ); } catch( BrokenBarrierException bbe ) { fail( "The barrier should not be broken: " + bbe.getMessage()); } catch( TimeoutException e ) { waitFailed = true; } assertTrue( waitFailed ); logger.debug("Ok"); ksession.dispose(); } catch (InterruptedException ex) { throw new IllegalStateException("The endTheProcess method has been interrupted", ex); } } private Environment getEnvironment() { Environment environment = KnowledgeBaseFactory.newEnvironment(); environment.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); environment.set(EnvironmentName.TRANSACTION_MANAGER, txm); environment.set(EnvironmentName.GLOBALS, new MapGlobalResolver()); return environment; } public void setEmf(EntityManagerFactory emf) { this.emf = emf; } public void setKbase(KieBase kbase) { this.kbase = kbase; } public void setKstore(KieStoreServices kstore) { this.kstore = kstore; } public void setTxm(JpaTransactionManager txm) { this.txm = txm; } }