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; }
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()); }
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()); return this; }
/** * Note: This does not test a message with 4-byte Unicode supplementary characters for two * reasons: - MySQL 5.1 does not support 4-byte supplementary characters (support from 5.5.3 * onwards) - {@link String#length()} counts these characters twice (since they are represented by * two chars), so essentially the cutoff would be half the actual cutoff for such a string */ public void testInsertJobWithExceptionMessage() { String fittingThreeByteMessage = repeatCharacter("\u9faf", JobEntity.MAX_EXCEPTION_MESSAGE_LENGTH); JobEntity threeByteJobEntity = new MessageEntity(); threeByteJobEntity.setExceptionMessage(fittingThreeByteMessage); // should not fail insertJob(threeByteJobEntity); deleteJob(threeByteJobEntity); }
protected void initializeRetries( JobEntity job, String failedJobRetryTimeCycle, DurationHelper durationHelper) { log.fine( "Applying JobRetryStrategy '" + failedJobRetryTimeCycle + "' the first time for job " + job.getId() + " with " + durationHelper.getTimes() + " retries"); job.setRetries(durationHelper.getTimes()); }
protected void executeCustomStrategy( CommandContext commandContext, JobEntity job, ActivityImpl activity) throws Exception { String failedJobRetryTimeCycle = getFailedJobRetryTimeCycle(activity); if (failedJobRetryTimeCycle == null) { executeStandardStrategy(commandContext); } else { DurationHelper durationHelper = getDurationHelper(failedJobRetryTimeCycle); setLockExpirationTime(job, failedJobRetryTimeCycle, durationHelper); if (isFirstJobExecution(job)) { // then change default retries to the ones configured initializeRetries(job, failedJobRetryTimeCycle, durationHelper); } else { log.fine( "Decrementing retries of JobRetryStrategy '" + failedJobRetryTimeCycle + "' for job " + job.getId()); } logException(job); decrementRetries(job); notifyAcquisition(commandContext); } }
protected void checkAuthorization(CommandContext commandContext) { AuthorizationManager authorizationManager = commandContext.getAuthorizationManager(); if (jobId != null) { JobManager jobManager = commandContext.getJobManager(); JobEntity job = jobManager.findJobById(jobId); if (job != null) { String processInstanceId = job.getProcessInstanceId(); if (processInstanceId != null) { authorizationManager.checkUpdateProcessInstanceById(processInstanceId); } else { // start timer job is not assigned to a specific process // instance, that's why we have to check whether there // exists a UPDATE_INSTANCES permission on process definition or // a UPDATE permission on any process instance String processDefinitionKey = job.getProcessDefinitionKey(); if (processDefinitionKey != null) { authorizationManager.checkUpdateProcessInstanceByProcessDefinitionKey( processDefinitionKey); } } // if (processInstanceId == null && processDefinitionKey == null): // job is not assigned to any process instance nor process definition // then it is always possible to activate/suspend the corresponding job // -> no authorization check necessary } } else if (jobDefinitionId != null) { JobDefinitionManager jobDefinitionManager = commandContext.getJobDefinitionManager(); JobDefinitionEntity jobDefinition = jobDefinitionManager.findById(jobDefinitionId); if (jobDefinition != null) { String processDefinitionKey = jobDefinition.getProcessDefinitionKey(); authorizationManager.checkUpdateProcessInstanceByProcessDefinitionKey(processDefinitionKey); } } else if (processInstanceId != null) { authorizationManager.checkUpdateProcessInstanceById(processInstanceId); } else if (processDefinitionId != null) { authorizationManager.checkUpdateProcessInstanceByProcessDefinitionId(processDefinitionId); } else if (processDefinitionKey != null) { authorizationManager.checkUpdateProcessInstanceByProcessDefinitionKey(processDefinitionKey); } }
@Deployment( resources = { "org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml" }) public void testSetJobRetriesByDefinitionUnlocksInconsistentJobs() { // given a job definition final JobDefinition jobDefinition = managementService.createJobDefinitionQuery().singleResult(); // and an inconsistent job that is never again picked up by a job executor CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired(); commandExecutor.execute( new Command<Void>() { public Void execute(CommandContext commandContext) { JobManager jobManager = commandContext.getJobManager(); MessageEntity job = new MessageEntity(); job.setJobDefinitionId(jobDefinition.getId()); job.setJobHandlerType("any"); job.setLockOwner("owner"); job.setLockExpirationTime(ClockUtil.getCurrentTime()); job.setRetries(0); jobManager.send(job); return null; } }); // when the job retries are reset managementService.setJobRetriesByJobDefinitionId(jobDefinition.getId(), 3); // then the job can be picked up again JobEntity job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); }
protected ActivityImpl getCurrentActivity(CommandContext commandContext, JobEntity job) { String type = job.getJobHandlerType(); ActivityImpl activity = null; String configuration = job.getJobHandlerConfiguration(); if (TimerExecuteNestedActivityJobHandler.TYPE.equals(type) || TimerCatchIntermediateEventJobHandler.TYPE.equals(type)) { ExecutionEntity execution = fetchExecutionEntity(job.getExecutionId()); if (execution != null) { String acitivtyId = TimerEventJobHandler.getKey(configuration); activity = execution.getProcessDefinition().findActivity(acitivtyId); } } else if (TimerStartEventJobHandler.TYPE.equals(type)) { DeploymentCache deploymentCache = Context.getProcessEngineConfiguration().getDeploymentCache(); String definitionKey = TimerEventJobHandler.getKey(configuration); ProcessDefinitionEntity processDefinition = deploymentCache.findDeployedLatestProcessDefinitionByKey(definitionKey); if (processDefinition != null) { activity = processDefinition.getInitial(); } } else if (AsyncContinuationJobHandler.TYPE.equals(type)) { ExecutionEntity execution = fetchExecutionEntity(job.getExecutionId()); if (execution != null) { activity = execution.getActivity(); } } else { // noop, because activity type is not supported } return activity; }
@Override protected String getValue(JobEntity entity) { // JobEntityKey key = new JobEntityKey(entity); // return key.toJsonString(); return entity.getId(); }
@Override protected String getIndexValue(JobEntity entity) { return entity.getExecutionId(); }
public void testSetJobRetriesUnlocksInconsistentJob() { // case 1 // given an inconsistent job that is never again picked up by a job executor createJob(0, "owner", ClockUtil.getCurrentTime()); // when the job retries are reset JobEntity job = (JobEntity) managementService.createJobQuery().singleResult(); managementService.setJobRetries(job.getId(), 3); // then the job can be picked up again job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); // case 2 // given an inconsistent job that is never again picked up by a job executor createJob(2, "owner", null); // when the job retries are reset job = (JobEntity) managementService.createJobQuery().singleResult(); managementService.setJobRetries(job.getId(), 3); // then the job can be picked up again job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNull(job.getLockOwner()); assertNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); // case 3 // given a consistent job createJob(2, "owner", ClockUtil.getCurrentTime()); // when the job retries are reset job = (JobEntity) managementService.createJobQuery().singleResult(); managementService.setJobRetries(job.getId(), 3); // then the lock owner and expiration should not change job = (JobEntity) managementService.createJobQuery().singleResult(); assertNotNull(job); assertNotNull(job.getLockOwner()); assertNotNull(job.getLockExpirationTime()); assertEquals(3, job.getRetries()); deleteJobAndIncidents(job); TestHelper.clearOpLog(processEngineConfiguration); }
protected void setLockExpirationTime( JobEntity job, String failedJobRetryTimeCycle, DurationHelper durationHelper) { job.setLockExpirationTime(durationHelper.getDateAfter()); }