public Object execute(CommandContext commandContext) { ensureNotNull("jobId", jobId); JobEntity job = commandContext.getJobManager().findJobById(jobId); ensureNotNull("No job found with id '" + jobId + "'", "job", job); for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateJob(job); } // We need to check if the job was locked, ie acquired by the job acquisition thread // This happens if the the job was already acquired, but not yet executed. // In that case, we can't allow to delete the job. if (job.getLockOwner() != null || job.getLockExpirationTime() != null) { throw new ProcessEngineException("Cannot delete job when the job is being executed. Try again later."); } job.delete(); return null; }
protected boolean isFirstJobExecution(JobEntity job) { // check if this is jobs' first execution (recognize // this because no exception is set. Only the first // execution can be without exception - because if // no exception occurred the job would have been completed) // see https://app.camunda.com/jira/browse/CAM-1039 return job.getExceptionByteArrayId() == null && job.getExceptionMessage() == null; }
protected void setJobRetriesByJobId(String jobId, int retries, CommandContext commandContext) { JobEntity job = commandContext .getJobManager() .findJobById(jobId); if (job != null) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateRetriesJob(job); } if (job.isInInconsistentLockState()) { job.resetLock(); } int oldRetries = job.getRetries(); job.setRetries(retries); PropertyChange propertyChange = new PropertyChange(RETRIES, oldRetries, job.getRetries()); commandContext.getOperationLogManager().logJobOperation(getLogEntryOperation(), job.getId(), job.getJobDefinitionId(), job.getProcessInstanceId(), job.getProcessDefinitionId(), job.getProcessDefinitionKey(), propertyChange); } else { throw new ProcessEngineException("No job found with id '" + jobId + "'."); } }
protected void createOpLogEntry(CommandContext commandContext, long previousPriority, JobEntity job) { PropertyChange propertyChange = new PropertyChange(JOB_PRIORITY_PROPERTY, previousPriority, job.getPriority()); commandContext .getOperationLogManager() .logJobOperation( UserOperationLogEntry.OPERATION_TYPE_SET_PRIORITY, job.getId(), job.getJobDefinitionId(), job.getProcessInstanceId(), job.getProcessDefinitionId(), job.getProcessDefinitionKey(), propertyChange); } }
protected void initializeRetries(JobEntity job, int retries) { LOG.debugInitiallyAppyingRetryCycleForJob(job.getId(), retries); job.setRetries(retries); }
evt.setJobId(jobEntity.getId()); evt.setJobDueDate(jobEntity.getDuedate()); evt.setJobRetries(jobEntity.getRetries()); evt.setJobPriority(jobEntity.getPriority()); JobDefinition jobDefinition = jobEntity.getJobDefinition(); if (jobDefinition != null) { evt.setJobDefinitionId(jobDefinition.getId()); evt.setJobDefinitionType(jobEntity.getJobHandlerType()); evt.setActivityId(jobEntity.getActivityId()); evt.setExecutionId(jobEntity.getExecutionId()); evt.setProcessInstanceId(jobEntity.getProcessInstanceId()); evt.setProcessDefinitionId(jobEntity.getProcessDefinitionId()); evt.setProcessDefinitionKey(jobEntity.getProcessDefinitionKey()); evt.setDeploymentId(jobEntity.getDeploymentId()); evt.setTenantId(jobEntity.getTenantId()); ExecutionEntity execution = jobEntity.getExecution(); if (execution != null) { evt.setRootProcessInstanceId(execution.getRootProcessInstanceId());
public UserOperationLogContextEntryBuilder inContextOf(JobEntity job) { entry.setJobDefinitionId(job.getJobDefinitionId()); entry.setProcessInstanceId(job.getProcessInstanceId()); entry.setProcessDefinitionId(job.getProcessDefinitionId()); entry.setProcessDefinitionKey(job.getProcessDefinitionKey()); entry.setDeploymentId(job.getDeploymentId()); ExecutionEntity execution = job.getExecution(); if (execution != null) { entry.setRootProcessInstanceId(execution.getRootProcessInstanceId()); } return this; }
@Test @org.camunda.bpm.engine.test.Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/IncidentTest.testShouldCreateOneIncident.bpmn"}) public void testFailedJobListenerRetries() { //given runtimeService.startProcessInstanceByKey("failingProcess"); //when the job is run several times till the incident creation Job job = getJob(); while (job.getRetries() > 0 && ((JobEntity)job).getLockOwner() == null ) { try { lockTheJob(job.getId()); engineRule.getManagementService().executeJob(job.getId()); } catch (Exception ex) { } job = getJob(); } //then JobEntity jobFinalState = (JobEntity)engineRule.getManagementService().createJobQuery().jobId(job.getId()).list().get(0); assertEquals(jobRetries, jobFinalState.getRetries()); if (jobLocked) { assertNotNull(jobFinalState.getLockOwner()); assertNotNull(jobFinalState.getLockExpirationTime()); } else { assertNull(jobFinalState.getLockOwner()); assertNull(jobFinalState.getLockExpirationTime()); } }
managementService.setJobRetries(job.getId(), 3); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); managementService.setJobRetries(job.getId(), 3); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); managementService.setJobRetries(job.getId(), 3); assertNotNull(job.getLockOwner()); assertNotNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries());
@Test public void testHistoryCleanupJobResolveIncident() { //given String jobId = historyService.cleanUpHistoryAsync(true).getId(); imitateFailedJob(jobId); assertEquals(5, processEngineConfiguration.getDefaultNumberOfRetries()); //when //call to cleanup history means that incident was resolved jobId = historyService.cleanUpHistoryAsync(true).getId(); //then JobEntity jobEntity = getJobEntity(jobId); assertEquals(5, jobEntity.getRetries()); assertEquals(null, jobEntity.getExceptionByteArrayId()); assertEquals(null, jobEntity.getExceptionMessage()); }
for(Job job : lockedJobList) { JobEntity jobEntity = (JobEntity)job; Assert.assertNotNull(jobEntity.getLockOwner()); Assert.assertTrue(lockedJobList.get(1).getId().equals(jobEntity.getId()) || lockedJobList.get(0).getId().equals(jobEntity.getId())); Assert.assertNull(jobEntity.getLockOwner()); Assert.assertNull(jobEntity.getLockExpirationTime());
@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()); }
@Override public void checkUpdateRetriesJob(JobEntity job) { if (job.getProcessDefinitionKey() == null) { // "standalone" job: nothing to do! return; } CompositePermissionCheck retryJobPermission = new PermissionCheckBuilder() .disjunctive() .atomicCheckForResourceId(PROCESS_INSTANCE, job.getProcessInstanceId(), ProcessInstancePermissions.RETRY_JOB) .atomicCheckForResourceId(PROCESS_DEFINITION, job.getProcessDefinitionKey(), ProcessDefinitionPermissions.RETRY_JOB) .atomicCheckForResourceId(PROCESS_INSTANCE, job.getProcessInstanceId(), UPDATE) .atomicCheckForResourceId(PROCESS_DEFINITION, job.getProcessDefinitionKey(), UPDATE_INSTANCE) .build(); getAuthorizationManager().checkAuthorization(retryJobPermission); }
@Override public void checkUpdateJob(JobEntity job) { if (job != null && !getTenantManager().isAuthenticatedTenant(job.getTenantId())) { throw LOG.exceptionCommandWithUnauthorizedTenant("update the job '"+ job.getId() + "'"); } }
@Test @Deployment(resources = "org/camunda/bpm/engine/test/jobexecutor/simpleAsyncProcess.bpmn20.xml") public void testJobDueDateValue() { // when runtimeService.startProcessInstanceByKey("simpleAsyncProcess"); List<JobEntity> jobList = findAcquirableJobs(); // then assertEquals(1, jobList.size()); assertEquals(currentTime, jobList.get(0).getDuedate()); } }
protected ActivityImpl getCurrentActivity(CommandContext commandContext, JobEntity job) { String type = job.getJobHandlerType(); ActivityImpl activity = null; if (SUPPORTED_TYPES.contains(type)) { DeploymentCache deploymentCache = Context.getProcessEngineConfiguration().getDeploymentCache(); ProcessDefinitionEntity processDefinitionEntity = deploymentCache.findDeployedProcessDefinitionById(job.getProcessDefinitionId()); activity = processDefinitionEntity.findActivity(job.getActivityId()); } else { // noop, because activity type is not supported } return activity; }
public Void execute(CommandContext commandContext) { ((JobEntity) job).delete(); return null; } });
protected static boolean isAsyncContinuation(JobEntity job) { return job != null && AsyncContinuationJobHandler.TYPE.equals(job.getJobHandlerType()); }
public Void execute(CommandContext commandContext) { EnsureUtil.ensureNotNull("job id must not be null", "jobId", jobId); JobEntity job = commandContext.getJobManager().findJobById(jobId); EnsureUtil.ensureNotNull(NotFoundException.class, "No job found with id '" + jobId + "'", "job", job); for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { checker.checkUpdateJob(job); } long currentPriority = job.getPriority(); job.setPriority(priority); createOpLogEntry(commandContext, currentPriority, job); return null; }
public void testJobExceptionMessageCutoff() { JobEntity threeByteJobEntity = new MessageEntity(); String message = repeatCharacter("a", JobEntity.MAX_EXCEPTION_MESSAGE_LENGTH * 2); threeByteJobEntity.setExceptionMessage(message); assertEquals(JobEntity.MAX_EXCEPTION_MESSAGE_LENGTH, threeByteJobEntity.getExceptionMessage().length()); }