private void when_all_jobs_within_X_days_are_executed(int days) { Date date = DateTime.now().plus(Days.days(days)).toDate(); Job job = managementService.createJobQuery().duedateLowerThan(date).singleResult(); assertThat(job, notNullValue()); managementService.executeJob(job.getId()); }
@Deployment public void testExpression() { // Set the clock fixed HashMap<String, Object> variables1 = new HashMap<String, Object>(); variables1.put("dueDate", new Date()); HashMap<String, Object> variables2 = new HashMap<String, Object>(); variables2.put("dueDate", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date())); // After process start, there should be timer created ProcessInstance pi1 = runtimeService.startProcessInstanceByKey("intermediateTimerEventExample", variables1); ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("intermediateTimerEventExample", variables2); assertEquals(1, managementService.createJobQuery().processInstanceId(pi1.getId()).count()); assertEquals(1, managementService.createJobQuery().processInstanceId(pi2.getId()).count()); // After setting the clock to one second in the future the timers should fire List<Job> jobs = managementService.createJobQuery().executable().list(); assertEquals(2, jobs.size()); for (Job job : jobs) { managementService.executeJob(job.getId()); } assertEquals(0, managementService.createJobQuery().processInstanceId(pi1.getId()).count()); assertEquals(0, managementService.createJobQuery().processInstanceId(pi2.getId()).count()); assertProcessEnded(pi1.getProcessInstanceId()); assertProcessEnded(pi2.getProcessInstanceId()); }
@Deployment( resources = { "org/activiti/examples/bpmn/event/timer/BoundaryTimerEventTest.testInterruptingTimerDuration.bpmn" }) @Test public void testInterruptingTimerDuration() { // Start process instance RuntimeService runtimeService = activitiRule.getRuntimeService(); ProcessInstance pi = runtimeService.startProcessInstanceByKey("escalationExample"); // There should be one task, with a timer : first line support TaskService taskService = activitiRule.getTaskService(); Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult(); assertEquals("First line support", task.getName()); // Manually execute the job ManagementService managementService = activitiRule.getManagementService(); Job timer = managementService.createJobQuery().singleResult(); managementService.executeJob(timer.getId()); // The timer has fired, and the second task (secondlinesupport) now exists task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult(); assertEquals("Second line support", task.getName()); }
protected void removeObsoleteTimers(ProcessDefinitionEntity processDefinition) { List<Job> jobsToDelete = null; if (processDefinition.getTenantId() != null && !ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())) { jobsToDelete = Context.getCommandContext() .getJobEntityManager() .findJobsByTypeAndProcessDefinitionKeyAndTenantId( TimerStartEventJobHandler.TYPE, processDefinition.getKey(), processDefinition.getTenantId()); } else { jobsToDelete = Context.getCommandContext() .getJobEntityManager() .findJobsByTypeAndProcessDefinitionKeyNoTenantId( TimerStartEventJobHandler.TYPE, processDefinition.getKey()); } if (jobsToDelete != null) { for (Job job : jobsToDelete) { new CancelJobsCmd(job.getId()).execute(Context.getCommandContext()); } } }
/** Test create, update and delete events of jobs entities. */ @Deployment public void testJobEntityEvents() throws Exception { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testJobEvents"); Job theJob = managementService .createJobQuery() .processInstanceId(processInstance.getId()) .singleResult(); assertNotNull(theJob); // Check if create-event has been dispatched assertEquals(1, listener.getEventsReceived().size()); ActivitiEvent event = listener.getEventsReceived().get(0); assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType()); checkEventContext(event, theJob, false); listener.clearEventsReceived(); // Update the job-entity. Check if update event is dispatched with update job entity managementService.setJobRetries(theJob.getId(), 5); assertEquals(1, listener.getEventsReceived().size()); event = listener.getEventsReceived().get(0); assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType()); Job updatedJob = (Job) ((ActivityEntityEvent) event).getEntity(); assertEquals(5, updatedJob.getRetries()); checkEventContext(event, theJob, true); listener.clearEventsReceived(); // Force timer to fire Calendar tomorrow = Calendar.getInstance(); tomorrow.add(Calendar.DAY_OF_YEAR, 1); ClockUtil.setCurrentTime(tomorrow.getTime()); waitForJobExecutorToProcessAllJobs(2000, 100); // Check delete-event has been dispatched assertEquals(3, listener.getEventsReceived().size()); // First, a timer fired event has been dispatched event = listener.getEventsReceived().get(0); assertEquals(ActivitiEventType.TIMER_FIRED, event.getType()); checkEventContext(event, theJob, true); // Next, a delete event has been dispatched event = listener.getEventsReceived().get(1); assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType()); checkEventContext(event, theJob, true); // Finally, a complete event has been dispatched event = listener.getEventsReceived().get(2); assertEquals(ActivitiEventType.JOB_EXECUTION_SUCCESS, event.getType()); checkEventContext(event, theJob, true); }
@Deployment public void testLoopWithCycle() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testLoop"); // After looping 3 times, the process should end. Cycle should NOT repeat itself for (int i = 0; i < 3; i++) { Job timer = managementService.createJobQuery().singleResult(); managementService.executeJob(timer.getId()); } assertProcessEnded(processInstance.getId()); }
public void testSignalStartEventFromProcesAsync() { // Deploy test processes repositoryService .createDeployment() .addClasspathResource( "org/activiti/engine/test/bpmn/event/signal/SignalEventTest.testSignalStartEventAsync.bpmn20.xml") .deploy(); // Starting the process that fires the signal should start 1 process instance that are listening // on that signal, the others are done async runtimeService.startProcessInstanceByKey("processWithSignalThrow"); // Verify assertEquals(0, runtimeService.createProcessInstanceQuery().count()); assertEquals(0, taskService.createTaskQuery().count()); assertEquals(3, managementService.createJobQuery().count()); for (Job job : managementService.createJobQuery().list()) { managementService.executeJob(job.getId()); } assertEquals(3, runtimeService.createProcessInstanceQuery().count()); assertEquals(3, taskService.createTaskQuery().count()); List<Task> tasks = taskService.createTaskQuery().orderByTaskName().asc().list(); List<String> names = Arrays.asList("A", "B", "C"); for (int i = 0; i < tasks.size(); i++) { assertEquals("Task in process " + names.get(i), tasks.get(i).getName()); } // Start a process with a signal boundary event runtimeService.startProcessInstanceByKey("processWithSignalCatch"); assertEquals(4, runtimeService.createProcessInstanceQuery().count()); assertEquals(4, taskService.createTaskQuery().count()); assertEquals(1, taskService.createTaskQuery().taskName("Task in process D").count()); // Firing again runtimeService.startProcessInstanceByKey("processWithSignalThrow"); assertEquals(4, managementService.createJobQuery().count()); for (Job job : managementService.createJobQuery().list()) { managementService.executeJob(job.getId()); } assertEquals(7, runtimeService.createProcessInstanceQuery().count()); assertEquals(7, taskService.createTaskQuery().count()); assertEquals(1, taskService.createTaskQuery().taskName("Task after signal").count()); // Cleanup for (org.activiti.engine.repository.Deployment deployment : repositoryService.createDeploymentQuery().list()) { repositoryService.deleteDeployment(deployment.getId(), true); } }
protected void checkEventContext( ActivitiEvent event, Job entity, boolean scopeExecutionExpected) { assertEquals(entity.getProcessInstanceId(), event.getProcessInstanceId()); assertEquals(entity.getProcessDefinitionId(), event.getProcessDefinitionId()); if (scopeExecutionExpected) { assertEquals(entity.getExecutionId(), event.getExecutionId()); } else { assertEquals(entity.getProcessInstanceId(), event.getExecutionId()); } assertTrue(event instanceof ActivityEntityEvent); ActivityEntityEvent entityEvent = (ActivityEntityEvent) event; assertTrue(entityEvent.getEntity() instanceof Job); assertEquals(entity.getId(), ((Job) entityEvent.getEntity()).getId()); }
/** Test create, update and delete events of jobs entities. */ @Deployment public void testJobEntityEventsException() throws Exception { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testJobEvents"); Job theJob = managementService .createJobQuery() .processInstanceId(processInstance.getId()) .singleResult(); assertNotNull(theJob); // Set retries to 1, to prevent multiple chains of events being thrown managementService.setJobRetries(theJob.getId(), 1); listener.clearEventsReceived(); // Force timer to fire Calendar tomorrow = Calendar.getInstance(); tomorrow.add(Calendar.DAY_OF_YEAR, 1); ClockUtil.setCurrentTime(tomorrow.getTime()); waitForJobExecutorToProcessAllJobs(2000, 100); // Check delete-event has been dispatched assertEquals(4, listener.getEventsReceived().size()); // First, the job-entity was deleted, as the job was executed ActivitiEvent event = listener.getEventsReceived().get(0); assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType()); checkEventContext(event, theJob, true); // Next, a job failed event is dispatched event = listener.getEventsReceived().get(1); assertEquals(ActivitiEventType.JOB_EXECUTION_FAILURE, event.getType()); checkEventContext(event, theJob, true); // Finally, an update-event is received and the job count is decremented event = listener.getEventsReceived().get(2); assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType()); checkEventContext(event, theJob, true); event = listener.getEventsReceived().get(3); assertEquals(ActivitiEventType.JOB_RETRIES_DECREMENTED, event.getType()); assertEquals(0, ((Job) ((ActivityEntityEvent) event).getEntity()).getRetries()); checkEventContext(event, theJob, true); }
public LegacyJobResponse(Job job) { setId(job.getId()); setExecutionId(job.getExecutionId()); setProcessInstanceId(job.getProcessInstanceId()); setDueDate(RequestUtil.dateToString(job.getDuedate())); setRetries(job.getRetries()); setExceptionMessage(job.getExceptionMessage()); }
@Deployment( resources = { "org/activiti/rest/api/management/JobCollectionResourceTest.testTimerProcess.bpmn20.xml" }) public void testGetJobs() throws Exception { Calendar hourAgo = Calendar.getInstance(); hourAgo.add(Calendar.HOUR, -1); Calendar inAnHour = Calendar.getInstance(); inAnHour.add(Calendar.HOUR, 1); // Start process, forcing error on job-execution ProcessInstance processInstance = runtimeService.startProcessInstanceByKey( "timerProcess", Collections.singletonMap("error", (Object) Boolean.TRUE)); Job timerJob = managementService .createJobQuery() .processInstanceId(processInstance.getId()) .timers() .singleResult(); assertNotNull(timerJob); for (int i = 0; i < timerJob.getRetries(); i++) { // Force execution of job until retries are exhausted try { managementService.executeJob(timerJob.getId()); fail(); } catch (ActivitiException expected) { // Ignore, we expect the exception } } timerJob = managementService .createJobQuery() .processInstanceId(processInstance.getId()) .timers() .singleResult(); assertEquals(0, timerJob.getRetries()); // Fetch the async-job (which has retries left) Job asyncJob = managementService .createJobQuery() .processInstanceId(processInstance.getId()) .withRetriesLeft() .singleResult(); // Test fetching all jobs String url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION); assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId()); // Fetch using job-id url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?id=" + asyncJob.getId(); assertResultsPresentInDataResponse(url, asyncJob.getId()); // Fetch using processInstanceId url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?processInstanceId=" + processInstance.getId(); assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId()); url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?processInstanceId=unexisting"; assertResultsPresentInDataResponse(url); // Fetch using executionId url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?executionId=" + asyncJob.getExecutionId(); assertResultsPresentInDataResponse(url, asyncJob.getId()); url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?executionId=" + timerJob.getExecutionId(); assertResultsPresentInDataResponse(url, timerJob.getId()); // Fetch using processDefinitionId url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?processDefinitionId=" + processInstance.getProcessDefinitionId(); assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId()); url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?processDefinitionId=unexisting"; assertResultsPresentInDataResponse(url); // Fetch using withRetriesLeft url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?withRetriesLeft=true"; assertResultsPresentInDataResponse(url, asyncJob.getId()); // Fetch using executable url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?executable=true"; assertResultsPresentInDataResponse(url, asyncJob.getId()); // Fetch using timers only url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?timersOnly=true"; assertResultsPresentInDataResponse(url, timerJob.getId()); // Combining messagesOnly with timersOnly should result in exception ClientResource client = getAuthenticatedClient( RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?timersOnly=true&messagesOnly=true"); try { client.get(); fail("Exception expected"); } catch (ResourceException expected) { assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus()); assertEquals( "Only one of 'timersOnly' or 'messagesOnly' can be provided.", expected.getStatus().getDescription()); } // Fetch using dueBefore url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?dueBefore=" + getISODateString(inAnHour.getTime()); assertResultsPresentInDataResponse(url, timerJob.getId()); url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?dueBefore=" + getISODateString(hourAgo.getTime()); assertResultsPresentInDataResponse(url); // Fetch using dueAfter url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?dueAfter=" + getISODateString(hourAgo.getTime()); assertResultsPresentInDataResponse(url, timerJob.getId()); url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?dueAfter=" + getISODateString(inAnHour.getTime()); assertResultsPresentInDataResponse(url); // Fetch using withException url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?withException=true"; assertResultsPresentInDataResponse(url, timerJob.getId()); // Fetch with exceptionMessage url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?exceptionMessage=" + timerJob.getExceptionMessage(); assertResultsPresentInDataResponse(url, timerJob.getId()); // Fetch with empty exceptionMessage url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?exceptionMessage="; assertResultsPresentInDataResponse(url); }