7

Is it possible (and if so: how) to add a custom Job to the jobexecutor in camunda BPM? My requirement is to execute a process-related Service by Timer or Loop. I do NOT want to model this in the BPMN directly, since it is not really part of the process. I could start additional arbitrary processes containing just one async Service task to archieve this, but I would prefer adding a method call containing the SOAP/REST/RMI call to the Job Queue Directly without the extra effort. Anyone tried this before?

Simon Zambrovski
  • 746
  • 6
  • 18
Jan Galinski
  • 11,768
  • 8
  • 54
  • 77

1 Answers1

8

This is an advanced question. It is possible to create a Job using internal API. You need to provide two things:

A custom Job handler:

public class CustomjobHandler implements JobHandler {

  public static final String TYPE = "customjobHandler";

    public String getType() {
      return TYPE;
    }

    public void execute(String configuration, ExecutionEntity execution, CommandContext commandContext) {
      // provide custom job execution logic
    }    
}

The job handler is added to the process engine configuration. See (customJobHandlers list).

Command for creating the Job

For example from a Java Delegate (you could also use a custom command).

public class CreateJobCommand implements Command<String> {

  public String execute(CommandContext commandContext) {

    MessageEntity message = new MessageEntity();
    message.setJobHandlerType(CustomJobHandler.TYPE);
    String config = "some string you want to pass to the hanlder";
    message.setJobHandlerConfiguration(config);

    Context
      .getCommandContext()
      .getJobManager()
      .send(message);

    return message.getId();
  }

}

This creates a "Message Entity" which executes as soon as possible. If you want a timed execution you can create a TimerEntity. Then you can execute the command on the command executor of the process engine.

Edit: to test this in the Standalone Engine, you have to add the CustomJobHandler to the camunda.cfg.xml:

<property name="customJobHandlers">
 <list>
   <bean class="<FQN of CustomJobHandler>" />
 </list>
</property>
Jan Galinski
  • 11,768
  • 8
  • 54
  • 77
meyerdan
  • 529
  • 2
  • 4
  • Thanks Daniel. How can I get the command executor of the engine? Casting to ProcessEngineImpl and then getConfiguration().getCommandExecutor? Or is there a better (non casting) way? – Jan Galinski Sep 09 '13 at 11:03
  • Currently not. We could think about providing a method on the management service. Something like managementService.executeCommand(cmd) – meyerdan Sep 09 '13 at 11:34
  • Do you have a working example? I wrote a Spike with the two classes above but get a NPE inside the JobEntity when I do managementService.executeJob(). Seems like the job cannot execute without an execution ... My test class: https://gist.github.com/jangalinski/6497803 – Jan Galinski Sep 09 '13 at 16:05
  • 1
    Hi Jan, it works for me. Did you add the CustomJobHandler to the `customJobHandlers` list of the ProcessEngineConfiguration class in your camunda.cfg.xml file? – meyerdan Sep 10 '13 at 11:10
  • Of course not, why should I? :-) I might give that a try ... Suppose I use the JEE process engine, I would have to register a global module containing an extension of the DefaultConfiguration? – Jan Galinski Sep 10 '13 at 12:03
  • Yes, if you use a container managed process engine you need to add the handler class to the classloader of the process engine. We should probably discuss this in a separate thread if you need assistance with that. – meyerdan Sep 10 '13 at 12:18