package org.activiti.engine.test.db; import java.util.Calendar; import java.util.Date; import java.util.List; import org.activiti.engine.impl.Page; import org.activiti.engine.impl.cmd.AcquireJobsCmd; import org.activiti.engine.impl.interceptor.Command; import org.activiti.engine.impl.interceptor.CommandContext; import org.activiti.engine.impl.interceptor.CommandExecutor; import org.activiti.engine.impl.jobexecutor.AcquiredJobs; import org.activiti.engine.impl.jobexecutor.GetUnlockedTimersByDuedateCmd; import org.activiti.engine.impl.persistence.entity.TimerEntity; import org.activiti.engine.impl.test.PluggableActivitiTestCase; import org.activiti.engine.impl.util.ClockUtil; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.Job; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.test.Deployment; /** * * @author Daniel Meyer */ public class ProcessInstanceSuspensionTest extends PluggableActivitiTestCase { @Deployment(resources={"org/activiti/engine/test/db/oneJobProcess.bpmn20.xml"}) public void testJobsNotVisisbleToAcquisitionIfInstanceSuspended() { ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().singleResult(); ProcessInstance pi = runtimeService.startProcessInstanceByKey(pd.getKey()); // now there is one job: // now there is one job: Job job = managementService.createJobQuery() .singleResult(); assertNotNull(job); makeSureJobDue(job); // the acquirejobs command sees the job: AcquiredJobs acquiredJobs = executeAcquireJobsCommand(); assertEquals(1, acquiredJobs.size()); // suspend the process instance: runtimeService.suspendProcessInstanceById(pi.getId()); // now, the acquirejobs command does not see the job: acquiredJobs = executeAcquireJobsCommand(); assertEquals(0, acquiredJobs.size()); } @Deployment(resources={"org/activiti/engine/test/db/oneJobProcess.bpmn20.xml"}) public void testJobsNotVisisbleToAcquisitionIfDefinitionSuspended() { ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().singleResult(); runtimeService.startProcessInstanceByKey(pd.getKey()); // now there is one job: Job job = managementService.createJobQuery() .singleResult(); assertNotNull(job); makeSureJobDue(job); // the acquirejobs command sees the job: AcquiredJobs acquiredJobs = executeAcquireJobsCommand(); assertEquals(1, acquiredJobs.size()); // suspend the process instance: repositoryService.suspendProcessDefinitionById(pd.getId()); // now, the acquirejobs command does not see the job: acquiredJobs = executeAcquireJobsCommand(); assertEquals(0, acquiredJobs.size()); } @Deployment public void testSuspendedProcessTimerExecution() throws Exception { // Process with boundary timer-event that fires in 1 hour ProcessInstance procInst = runtimeService.startProcessInstanceByKey("suspendProcess"); assertNotNull(procInst); assertEquals(1, managementService.createJobQuery().processInstanceId(procInst.getId()).count()); // Shutdown the job-executor so timer's won't be executed boolean wasJobExecutorActive = processEngineConfiguration.getJobExecutor().isActive(); if(wasJobExecutorActive) { processEngineConfiguration.getJobExecutor().shutdown(); } // Roll time ahead to be sure timer is due to fire Calendar tomorrow = Calendar.getInstance(); tomorrow.add(Calendar.DAY_OF_YEAR, 1); ClockUtil.setCurrentTime(tomorrow.getTime()); // Check if timer is eligable to be executed, when process in not yet suspended CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired(); List<TimerEntity> jobs = commandExecutor.execute(new GetUnlockedTimersByDuedateCmd(ClockUtil.getCurrentTime(), new Page(0, 1))); assertEquals(1, jobs.size()); // Suspend process instancd runtimeService.suspendProcessInstanceById(procInst.getId()); // Check if the timer is NOT aquired, even though the duedate is reached jobs = commandExecutor.execute(new GetUnlockedTimersByDuedateCmd(ClockUtil.getCurrentTime(), new Page(0, 1))); assertEquals(0, jobs.size()); // Start job-executor again, if needed if(wasJobExecutorActive) { processEngineConfiguration.getJobExecutor().start(); } } protected void makeSureJobDue(final Job job) { processEngineConfiguration.getCommandExecutorTxRequired() .execute(new Command<Void>() { public Void execute(CommandContext commandContext) { Date currentTime = ClockUtil.getCurrentTime(); commandContext.getJobManager() .findJobById(job.getId()) .setDuedate(new Date(currentTime.getTime() - 10000)); return null; } }); } private AcquiredJobs executeAcquireJobsCommand() { return processEngineConfiguration.getCommandExecutorTxRequired() .execute(new AcquireJobsCmd(processEngineConfiguration.getJobExecutor())); } }