public Job build() { Job mockJob = mock(Job.class); when(mockJob.getId()).thenReturn(id); when(mockJob.getDuedate()).thenReturn(dueDate); when(mockJob.getExceptionMessage()).thenReturn(exceptionMessage); when(mockJob.getExecutionId()).thenReturn(executionId); when(mockJob.getProcessInstanceId()).thenReturn(processInstanceId); when(mockJob.getProcessDefinitionId()).thenReturn(processDefinitionId); when(mockJob.getProcessDefinitionKey()).thenReturn(processDefinitionKey); when(mockJob.getRetries()).thenReturn(retries); when(mockJob.isSuspended()).thenReturn(suspended); when(mockJob.getPriority()).thenReturn(priority); when(mockJob.getJobDefinitionId()).thenReturn(jobDefinitionId); when(mockJob.getTenantId()).thenReturn(tenantId); when(mockJob.getCreateTime()).thenReturn(createTime); return mockJob; }
private void verifyFailedJob(JobQuery query, ProcessInstance processInstance) { verifyQueryResults(query, 1); Job failedJob = query.singleResult(); assertNotNull(failedJob); assertEquals(processInstance.getId(), failedJob.getProcessInstanceId()); assertNotNull(failedJob.getExceptionMessage()); assertThat(failedJob.getExceptionMessage(), containsString(EXCEPTION_MESSAGE)); }
public static JobDto fromJob(Job job) { JobDto dto = new JobDto(); dto.id = job.getId(); dto.jobDefinitionId = job.getJobDefinitionId(); dto.processInstanceId = job.getProcessInstanceId(); dto.processDefinitionId = job.getProcessDefinitionId(); dto.processDefinitionKey = job.getProcessDefinitionKey(); dto.executionId = job.getExecutionId(); dto.exceptionMessage = job.getExceptionMessage(); dto.retries = job.getRetries(); dto.dueDate = job.getDuedate(); dto.suspended = job.isSuspended(); dto.priority = job.getPriority(); dto.tenantId = job.getTenantId(); dto.createTime = job.getCreateTime(); return dto; }
@Test public void testBatchExecutionFailureWithMissingProcessInstance() { Batch batch = helper.migrateProcessInstancesAsync(2); helper.executeSeedJob(batch); List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery().list(); String deletedProcessInstanceId = processInstances.get(0).getId(); // when runtimeService.deleteProcessInstance(deletedProcessInstanceId, "test"); helper.executeJobs(batch); // then the remaining process instance was migrated assertEquals(0, helper.countSourceProcessInstances()); assertEquals(1, helper.countTargetProcessInstances()); // and one batch job failed and has 2 retries left List<Job> migrationJobs = helper.getExecutionJobs(batch); assertEquals(1, migrationJobs.size()); Job failedJob = migrationJobs.get(0); assertEquals(2, failedJob.getRetries()); assertThat(failedJob.getExceptionMessage(), startsWith("ENGINE-23003")); assertThat(failedJob.getExceptionMessage(), containsString("Process instance '" + deletedProcessInstanceId + "' cannot be migrated")); }
public static JobDto fromJob(Job job) { JobDto dto = new JobDto(); dto.id = job.getId(); dto.jobDefinitionId = job.getJobDefinitionId(); dto.processInstanceId = job.getProcessInstanceId(); dto.processDefinitionId = job.getProcessDefinitionId(); dto.processDefinitionKey = job.getProcessDefinitionKey(); dto.executionId = job.getExecutionId(); dto.exceptionMessage = job.getExceptionMessage(); dto.retries = job.getRetries(); dto.dueDate = job.getDuedate(); dto.suspended = job.isSuspended(); dto.priority = job.getPriority(); dto.tenantId = job.getTenantId(); dto.createTime = job.getCreateTime(); return dto; }
assertThat(failedJob.getExceptionMessage(), startsWith("ENGINE-13036")); assertThat(failedJob.getExceptionMessage(), containsString("Process instance '" + deletedProcessInstanceId + "' cannot be modified"));
@Test @Deployment public void testCompetingJobExecutionDefaultRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); assertEquals(currentJobs.get(1).getRetries(), remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is no lock expiration time due to the default retry strategy assertNull(jobEntity.getLockExpirationTime()); }
@Test public void testTransactionRollbackInServiceTask() throws Exception { runtimeService.startProcessInstanceByKey("txRollbackServiceTask"); waitForJobExecutorToProcessAllJobs(10000); Job job = managementService.createJobQuery().singleResult(); assertNotNull(job); assertEquals(0, job.getRetries()); assertNotNull(job.getExceptionMessage()); assertNotNull(managementService.getJobExceptionStacktrace(job.getId())); }
@Test @Deployment public void testCompetingJobExecutionFoxRetryStrategy() { // given an MI subprocess with two instances runtimeService.startProcessInstanceByKey("miParallelSubprocess"); List<Job> currentJobs = managementService.createJobQuery().list(); assertEquals(2, currentJobs.size()); // when the jobs are executed in parallel JobExecutionThread threadOne = new JobExecutionThread(currentJobs.get(0).getId()); threadOne.startAndWaitUntilControlIsReturned(); JobExecutionThread threadTwo = new JobExecutionThread(currentJobs.get(1).getId()); threadTwo.startAndWaitUntilControlIsReturned(); // then the first committing thread succeeds LOG.debug("test thread notifies thread 1"); threadOne.proceedAndWaitTillDone(); assertNull(threadOne.exception); // then the second committing thread fails with an OptimisticLockingException // and the job retries have not been decremented LOG.debug("test thread notifies thread 2"); threadTwo.proceedAndWaitTillDone(); assertNotNull(threadTwo.exception); Job remainingJob = managementService.createJobQuery().singleResult(); // retries are configured as R5/PT5M, so no decrement means 5 retries left assertEquals(5, remainingJob.getRetries()); assertNotNull(remainingJob.getExceptionMessage()); JobEntity jobEntity = (JobEntity) remainingJob; assertNull(jobEntity.getLockOwner()); // and there is a custom lock expiration time assertNotNull(jobEntity.getLockExpirationTime()); }
@Test public void testFailingTransactionListener() throws Exception { runtimeService.startProcessInstanceByKey("failingTransactionListener"); waitForJobExecutorToProcessAllJobs(10000); Job job = managementService.createJobQuery().singleResult(); assertNotNull(job); assertEquals(0, job.getRetries()); assertNotNull(job.getExceptionMessage()); assertNotNull(managementService.getJobExceptionStacktrace(job.getId())); }
@Test public void testTransactionRollbackInServiceTaskWithCustomRetryCycle() throws Exception { runtimeService.startProcessInstanceByKey("txRollbackServiceTaskWithCustomRetryCycle"); waitForJobExecutorToProcessAllJobs(10000); Job job = managementService.createJobQuery().singleResult(); assertNotNull(job); assertEquals(0, job.getRetries()); assertNotNull(job.getExceptionMessage()); assertNotNull(managementService.getJobExceptionStacktrace(job.getId())); }
@Test public void cannotMigrateInstanceWithoutTenantIdToDifferentTenant() { // given ProcessDefinition sourceDefinition = defaultTestRule.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS); ProcessDefinition targetDefinition = defaultTestRule.deployForTenantAndGetDefinition(TENANT_ONE, ProcessModels.ONE_TASK_PROCESS); ProcessInstance processInstance = defaultEngineRule.getRuntimeService().startProcessInstanceById(sourceDefinition.getId()); MigrationPlan migrationPlan = defaultEngineRule.getRuntimeService().createMigrationPlan(sourceDefinition.getId(), targetDefinition.getId()) .mapEqualActivities() .build(); Batch batch = defaultEngineRule.getRuntimeService() .newMigration(migrationPlan) .processInstanceIds(Arrays.asList(processInstance.getId())) .executeAsync(); batchHelper.executeSeedJob(batch); // when batchHelper.executeJobs(batch); // then Job migrationJob = batchHelper.getExecutionJobs(batch).get(0); Assert.assertThat(migrationJob.getExceptionMessage(), CoreMatchers.containsString("Cannot migrate process instance '" + processInstance.getId() + "' without tenant to a process definition with a tenant ('tenant1')")); }
@Test @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"}) public void testQueryByExceptionMessage() { JobQuery query = managementService.createJobQuery().exceptionMessage(EXCEPTION_MESSAGE); verifyQueryResults(query, 0); ProcessInstance processInstance = startProcessInstanceWithFailingJob(); Job job = managementService.createJobQuery().processInstanceId(processInstance.getId()).singleResult(); query = managementService.createJobQuery().exceptionMessage(job.getExceptionMessage()); verifyFailedJob(query, processInstance); }
@Deployment public void testGetJobExceptionStacktrace() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution"); // The execution is waiting in the first usertask. This contains a boundry // timer event which we will execute manual for testing purposes. Job timerJob = managementService.createJobQuery() .processInstanceId(processInstance.getId()) .singleResult(); assertNotNull("No job found for process instance", timerJob); try { managementService.executeJob(timerJob.getId()); fail("RuntimeException from within the script task expected"); } catch (RuntimeException re) { assertTextPresent("This is an exception thrown from scriptTask", re.getMessage()); } // Fetch the task to see that the exception that occurred is persisted timerJob = managementService.createJobQuery() .processInstanceId(processInstance.getId()) .singleResult(); Assert.assertNotNull(timerJob); Assert.assertNotNull(timerJob.getExceptionMessage()); assertTextPresent("This is an exception thrown from scriptTask", timerJob.getExceptionMessage()); // Get the full stacktrace using the managementService String exceptionStack = managementService.getJobExceptionStacktrace(timerJob.getId()); Assert.assertNotNull(exceptionStack); assertTextPresent("This is an exception thrown from scriptTask", exceptionStack); }
public void testFailingTransactionListener() { deployment(Bpmn.createExecutableProcess("testProcess") .startEvent() .serviceTask() .camundaClass(FailingTransactionListenerDelegate.class.getName()) .camundaAsyncBefore() .endEvent() .done()); runtimeService.startProcessInstanceByKey("testProcess"); // there should be 1 job created: Job job = managementService.createJobQuery().singleResult(); assertNotNull(job); // with 3 retries assertEquals(3, job.getRetries()); // if we execute the job waitForJobExecutorToProcessAllJobs(6000); // the job is still present job = managementService.createJobQuery().singleResult(); assertNotNull(job); // but has no more retires assertEquals(0, job.getRetries()); assertEquals("exception in transaction listener", job.getExceptionMessage()); String stacktrace = managementService.getJobExceptionStacktrace(job.getId()); assertNotNull(stacktrace); assertTrue("unexpected stacktrace, was <" + stacktrace + ">", stacktrace.contains("java.lang.RuntimeException: exception in transaction listener")); }
@Deployment(resources = { "org/camunda/bpm/engine/test/bpmn/event/signal/SignalEventTest.signalStartEvent.bpmn20.xml", "org/camunda/bpm/engine/test/bpmn/event/signal/SignalEventTests.throwAlertSignalAsync.bpmn20.xml"}) @Test public void testAsyncSignalStartEventJobPropertiesDueDateSet() { Date testTime = new Date(1457326800000L); ClockUtil.setCurrentTime(testTime); processEngineConfiguration.setEnsureJobDueDateNotNull(true); ProcessDefinition catchingProcessDefinition = repositoryService .createProcessDefinitionQuery() .processDefinitionKey("startBySignal") .singleResult(); // given a process instance that throws a signal asynchronously runtimeService.startProcessInstanceByKey("throwSignalAsync"); // where the throwing instance ends immediately // then there is not yet a catching process instance assertEquals(0, runtimeService.createProcessInstanceQuery().count()); // but there is a job for the asynchronous continuation Job asyncJob = managementService.createJobQuery().singleResult(); assertEquals(catchingProcessDefinition.getId(), asyncJob.getProcessDefinitionId()); assertEquals(catchingProcessDefinition.getKey(), asyncJob.getProcessDefinitionKey()); assertNull(asyncJob.getExceptionMessage()); assertNull(asyncJob.getExecutionId()); assertNull(asyncJob.getJobDefinitionId()); assertEquals(0, asyncJob.getPriority()); assertNull(asyncJob.getProcessInstanceId()); assertEquals(3, asyncJob.getRetries()); assertEquals(testTime, asyncJob.getDuedate()); assertNull(asyncJob.getDeploymentId()); }
@Deployment(resources = { "org/camunda/bpm/engine/test/bpmn/event/signal/SignalEventTest.signalStartEvent.bpmn20.xml", "org/camunda/bpm/engine/test/bpmn/event/signal/SignalEventTests.throwAlertSignalAsync.bpmn20.xml"}) @Test public void testAsyncSignalStartEventJobProperties() { processEngineConfiguration.setEnsureJobDueDateNotNull(false); ProcessDefinition catchingProcessDefinition = repositoryService .createProcessDefinitionQuery() .processDefinitionKey("startBySignal") .singleResult(); // given a process instance that throws a signal asynchronously runtimeService.startProcessInstanceByKey("throwSignalAsync"); // where the throwing instance ends immediately // then there is not yet a catching process instance assertEquals(0, runtimeService.createProcessInstanceQuery().count()); // but there is a job for the asynchronous continuation Job asyncJob = managementService.createJobQuery().singleResult(); assertEquals(catchingProcessDefinition.getId(), asyncJob.getProcessDefinitionId()); assertEquals(catchingProcessDefinition.getKey(), asyncJob.getProcessDefinitionKey()); assertNull(asyncJob.getExceptionMessage()); assertNull(asyncJob.getExecutionId()); assertNull(asyncJob.getJobDefinitionId()); assertEquals(0, asyncJob.getPriority()); assertNull(asyncJob.getProcessInstanceId()); assertEquals(3, asyncJob.getRetries()); assertNull(asyncJob.getDuedate()); assertNull(asyncJob.getDeploymentId()); }
private void verifyFailedJob(JobQuery query, ProcessInstance processInstance) { verifyQueryResults(query, 1); Job failedJob = query.singleResult(); assertNotNull(failedJob); assertEquals(processInstance.getId(), failedJob.getProcessInstanceId()); assertNotNull(failedJob.getExceptionMessage()); assertTextPresent(EXCEPTION_MESSAGE, failedJob.getExceptionMessage()); }
public static JobDto fromJob(Job job) { JobDto dto = new JobDto(); dto.id = job.getId(); dto.jobDefinitionId = job.getJobDefinitionId(); dto.processInstanceId = job.getProcessInstanceId(); dto.processDefinitionId = job.getProcessDefinitionId(); dto.processDefinitionKey = job.getProcessDefinitionKey(); dto.executionId = job.getExecutionId(); dto.exceptionMessage = job.getExceptionMessage(); dto.retries = job.getRetries(); dto.dueDate = job.getDuedate(); dto.suspended = job.isSuspended(); dto.priority = job.getPriority(); dto.tenantId = job.getTenantId(); dto.createTime = job.getCreateTime(); return dto; }
@Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"}) public void testQueryByExceptionMessage() { JobQuery query = managementService.createJobQuery().exceptionMessage(EXCEPTION_MESSAGE); verifyQueryResults(query, 0); ProcessInstance processInstance = startProcessInstanceWithFailingJob(); Job job = managementService.createJobQuery().processInstanceId(processInstance.getId()).singleResult(); query = managementService.createJobQuery().exceptionMessage(job.getExceptionMessage()); verifyFailedJob(query, processInstance); }