org.activiti.engine.impl.cmd.ExecuteAsyncJobCmd Java Examples

The following examples show how to use org.activiti.engine.impl.cmd.ExecuteAsyncJobCmd. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExecuteAsyncRunnable.java    From activiti6-boot2 with Apache License 2.0 6 votes vote down vote up
protected void executeJob() {
  try {
    processEngineConfiguration.getCommandExecutor().execute(new ExecuteAsyncJobCmd(jobId));

  } catch (final ActivitiOptimisticLockingException e) {

    handleFailedJob(e);

    if (log.isDebugEnabled()) {
      log.debug("Optimistic locking exception during job execution. If you have multiple async executors running against the same database, "
          + "this exception means that this thread tried to acquire an exclusive job, which already was changed by another async executor thread."
          + "This is expected behavior in a clustered environment. " + "You can ignore this message if you indeed have multiple job executor threads running against the same database. "
          + "Exception message: {}", e.getMessage());
    }

  } catch (Throwable exception) {
    handleFailedJob(exception);

    // Finally, Throw the exception to indicate the ExecuteAsyncJobCmd failed
    String message = "Job " + jobId + " failed";
    log.error(message, exception);
  }
}
 
Example #2
Source File: HerdCommandInvoker.java    From herd with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the JobEntity from the given ExecuteAsyncJobCmd.
 *
 * @param executeAsyncJobCmd The ExecuteAsyncJobCmd
 *
 * @return The JobEntity
 */
private JobEntity getJobEntity(ExecuteAsyncJobCmd executeAsyncJobCmd)
{
    /*
     * Unfortunately, ExecuteAsyncJobCmd does not provide an accessible method to get the JobEntity stored within it.
     * We use reflection to force the value out of the object.
     * Also, we cannot simply get the entity and update it. We must retrieve it through the entity manager so it registers in Activiti's persistent object
     * cache. This way when the transaction commits, Activiti is aware of any changes in the JobEntity and persists them correctly.
     */
    try
    {
        Field field = ExecuteAsyncJobCmd.class.getDeclaredField("job");
        ReflectionUtils.makeAccessible(field);
        String jobId = ((JobEntity) ReflectionUtils.getField(field, executeAsyncJobCmd)).getId();

        return Context.getCommandContext().getJobEntityManager().findJobById(jobId);
    }
    catch (NoSuchFieldException | SecurityException e)
    {
        /*
         * This exception should not happen.
         */
        throw new IllegalStateException(e);
    }
}
 
Example #3
Source File: HerdCommandInvokerTest.java    From herd with Apache License 2.0 6 votes vote down vote up
@Test
public void testExecuteWithExceptionAndGetJobEntityWithNoSuchFieldException()
{
    // Mock dependencies.
    CommandConfig config = mock(CommandConfig.class);
    JobEntity jobEntity = mock(JobEntity.class);
    ExecuteAsyncJobCmd command = new ExecuteAsyncJobCmd(jobEntity);
    doThrow(NoSuchFieldException.class).when(jobEntity).getId();

    // Try to call the method under test.
    try
    {
        herdCommandInvoker.execute(config, command);
        fail();
    }
    catch (IllegalStateException e)
    {
        assertEquals(NoSuchFieldException.class.getName(), e.getMessage());
    }
}
 
Example #4
Source File: HerdCommandInvokerTest.java    From herd with Apache License 2.0 6 votes vote down vote up
@Test
public void testExecuteWithExceptionAndGetJobEntityWithSecurityException()
{
    // Mock dependencies.
    CommandConfig config = mock(CommandConfig.class);
    JobEntity jobEntity = mock(JobEntity.class);
    ExecuteAsyncJobCmd command = new ExecuteAsyncJobCmd(jobEntity);
    doThrow(SecurityException.class).when(jobEntity).getId();

    // Try to call the method under test.
    try
    {
        herdCommandInvoker.execute(config, command);
        fail();
    }
    catch (IllegalStateException e)
    {
        assertEquals(SecurityException.class.getName(), e.getMessage());
    }
}
 
Example #5
Source File: JobExecutorCmdHappyTest.java    From activiti6-boot2 with Apache License 2.0 5 votes vote down vote up
public void testJobCommandsWithTimer() {
  // clock gets automatically reset in LogTestCase.runTest
  processEngineConfiguration.getClock().setCurrentTime(new Date(SOME_TIME));

  AsyncExecutor asyncExecutor = processEngineConfiguration.getAsyncExecutor();
  CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();

  String jobId = commandExecutor.execute(new Command<String>() {

    public String execute(CommandContext commandContext) {
      TimerJobEntity timer = createTweetTimer("i'm coding a test", new Date(SOME_TIME + (10 * SECOND)));
      commandContext.getJobManager().scheduleTimerJob(timer);
      return timer.getId();
    }
  });

  AcquiredTimerJobEntities acquiredJobs = commandExecutor.execute(new AcquireTimerJobsCmd(asyncExecutor));
  assertEquals(0, acquiredJobs.size());

  processEngineConfiguration.getClock().setCurrentTime(new Date(SOME_TIME + (20 * SECOND)));

  acquiredJobs = commandExecutor.execute(new AcquireTimerJobsCmd(asyncExecutor));
  assertEquals(1, acquiredJobs.size());

  TimerJobEntity job = acquiredJobs.getJobs().iterator().next();

  assertEquals(jobId, job.getId());

  assertEquals(0, tweetHandler.getMessages().size());

  Job executableJob = managementService.moveTimerToExecutableJob(jobId);
  commandExecutor.execute(new ExecuteAsyncJobCmd(executableJob.getId()));

  assertEquals("i'm coding a test", tweetHandler.getMessages().get(0));
  assertEquals(1, tweetHandler.getMessages().size());
}
 
Example #6
Source File: HerdCommandInvokerTest.java    From herd with Apache License 2.0 5 votes vote down vote up
@Test(expected = CannotCreateTransactionException.class)
public void testExecuteWithExceptionAndGetCreateTransactionException()
{
    // Mock dependencies.
    CommandConfig config = mock(CommandConfig.class);
    ExecuteAsyncJobCmd command = mock(ExecuteAsyncJobCmd.class);
    doThrow(CannotCreateTransactionException.class).when(command).execute(any());
    herdCommandInvoker.execute(config, command);
}
 
Example #7
Source File: JobExecutorCmdHappyTest.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
public void testJobCommandsWithTimer() {
    ProcessEngineConfigurationImpl activiti5ProcessEngineConfig = (ProcessEngineConfigurationImpl) processEngineConfiguration.getFlowable5CompatibilityHandler().getRawProcessConfiguration();

    // clock gets automatically reset in LogTestCase.runTest
    Clock clock = processEngineConfiguration.getClock();
    clock.setCurrentTime(new Date(SOME_TIME));
    processEngineConfiguration.setClock(clock);

    AsyncExecutor asyncExecutor = processEngineConfiguration.getAsyncExecutor();
    CommandExecutor commandExecutor = (CommandExecutor) processEngineConfiguration.getFlowable5CompatibilityHandler().getRawCommandExecutor();

    String jobId = commandExecutor.execute(new Command<String>() {

        public String execute(CommandContext commandContext) {
            TimerJobEntity timer = createTweetTimer("i'm coding a test", new Date(SOME_TIME + (10 * SECOND)));
            commandContext.getJobEntityManager().schedule(timer);
            return timer.getId();
        }
    });

    AcquiredTimerJobEntities acquiredJobs = processEngineConfiguration.getCommandExecutor().execute(new AcquireTimerJobsCmd(asyncExecutor));
    assertEquals(0, acquiredJobs.size());

    clock.setCurrentTime(new Date(SOME_TIME + (20 * SECOND)));
    processEngineConfiguration.setClock(clock);

    acquiredJobs = processEngineConfiguration.getCommandExecutor().execute(new AcquireTimerJobsCmd(asyncExecutor));
    assertEquals(1, acquiredJobs.size());

    Job job = acquiredJobs.getJobs().iterator().next();

    assertEquals(jobId, job.getId());

    assertEquals(0, tweetHandler.getMessages().size());

    managementService.moveTimerToExecutableJob(jobId);
    JobEntity jobEntity = (JobEntity) activiti5ProcessEngineConfig.getManagementService().createJobQuery().singleResult();
    activiti5ProcessEngineConfig.getCommandExecutor().execute(new ExecuteAsyncJobCmd(jobEntity));

    assertEquals("i'm coding a test", tweetHandler.getMessages().get(0));
    assertEquals(1, tweetHandler.getMessages().size());

    processEngineConfiguration.resetClock();
}
 
Example #8
Source File: AsyncJobUtil.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
public static void executeJob(final JobEntity job, final CommandExecutor commandExecutor) {
    try {
        if (job.isExclusive()) {
            commandExecutor.execute(new LockExclusiveJobCmd(job));
        }

    } catch (Throwable lockException) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Could not lock exclusive job. Unlocking job so it can be acquired again. Caught exception: {}", lockException.getMessage());
        }

        unacquireJob(commandExecutor, job);
        return;

    }

    try {
        commandExecutor.execute(new Command<Void>() {
            @Override
            public Void execute(CommandContext commandContext) {
                new ExecuteAsyncJobCmd(job).execute(commandContext);
                if (job.isExclusive()) {
                    new UnlockExclusiveJobCmd(job).execute(commandContext);
                }
                return null;
            }
        });

    } catch (final ActivitiOptimisticLockingException e) {

        handleFailedJob(job, e, commandExecutor);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Optimistic locking exception during job execution. If you have multiple async executors running against the same database, " +
                    "this exception means that this thread tried to acquire an exclusive job, which already was changed by another async executor thread." +
                    "This is expected behavior in a clustered environment. " +
                    "You can ignore this message if you indeed have multiple job executor threads running against the same database. " +
                    "Exception message: {}", e.getMessage());
        }

    } catch (Throwable exception) {
        handleFailedJob(job, exception, commandExecutor);

        // Finally, Throw the exception to indicate the ExecuteAsyncJobCmd failed
        String message = "Job " + job.getId() + " failed";
        LOGGER.error(message, exception);
    }
}
 
Example #9
Source File: HerdCommandInvoker.java    From herd with Apache License 2.0 4 votes vote down vote up
@Override
public <T> T execute(CommandConfig config, Command<T> command)
{
    LOGGER.debug("command=\"{}\"", command.getClass().getName());
    try
    {
        // Perform the normal execution.
        return super.execute(config, command);
    }
    catch (Exception e)
    {
        LOGGER.warn(String.format("HerdCommandInvoker caught an exception."), e);

        /*
         * If the exception is unable to create transaction due to JDBC connection issue,
         * throw out the exception, then let the Activiti engine take care of retries
         */
        if (StringUtils.containsIgnoreCase(ExceptionUtils.getMessage(e), CANNOT_CREATE_TRANSACTION_EXCEPTION))
        {
            LOGGER.warn(String.format("HerdCommandInvoker caught a CannotCreateTransactionException."), e);
            throw e;
        }

        /*
         * Attempt to handle exception based on the command.
         * If we bubble the exception up here, the transaction will be rolled back and all variables which were not committed will not be persisted.
         * The problem with swallowing the exception, however, is that the exception message is not persisted automatically. To get around it, we must save
         * the exception message and stacktrace into a JobEntity which is associated with the current execution.
         */

        if (command instanceof ExecuteAsyncJobCmd)
        {
            /*
             * ExecuteAsyncJobCmd is executed when a task is asynchronous.
             * Save the exception information in the command's JobEntity
             */
            ExecuteAsyncJobCmd executeAsyncJobCmd = (ExecuteAsyncJobCmd) command;
            JobEntity jobEntity = getJobEntity(executeAsyncJobCmd);
            jobEntity.setExceptionMessage(ExceptionUtils.getMessage(e));
            jobEntity.setExceptionStacktrace(ExceptionUtils.getStackTrace(e));
            return null;
        }
        else
        {
            /*
             * We do not know how to handle any other commands, so just bubble it up and let Activiti's default mechanism kick in.
             */
            throw e;
        }
    }
}