Tuesday, March 16, 2010

jBPM 3 hints - finding a process instance in your deep dark jBPMContext

While writing some unit testing of the jBPM exception framework I needed to deal with two separately deployed process instances, one for the unit test and one for dealing with the exception I was causing.

My problem was how to obtain the exception process instance when all I know is the process name? I also had it easy from the unit testing point of view, I do not need to worry about multiple running instances of the exception framework as this is under my unit test control (at least I feel like I have some control over it!).

Below you see how you can locate your process instance and context within that instance. I will show you some helper methods that might come in handy for you (all logging done with log4j and assumes you understand what you see below):
/** Used to get the process id of the specific process I want. */
public long getExceptionProcId () {
  JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance();
  long procId;
  
  // Open the transaction.
  JbpmContext jbpmCtx = jbpmConf.createJbpmContext();

  try {
    // Get our process instance back.
    GraphSession graphSession = jbpmCtx.getGraphSession();
    ProcessDefinition processDefinition = 
      GraphSession.findLatestProcessDefinition("Exception Framework");
    assertThat("No process definition found.", 
      processDefinition, is(not(nullValue())));

    // Now, we search for all process instances of this process definition.
    List processInstances = 
      graphSession.findProcessInstances(processDefinition.getId());
    ProcessInstance procInst = (ProcessInstance) processInstances.get(0);
    procId = procInst.getId();
  } finally {
    // Close context.
    jbpmCtx.close();
  }   

  return procId;
}
With the above you can make use of the processId to recall your process instance as follows:
JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance(); 
JbpmContext jbpmCtx = jbpmConf.createJbpmContext();
  try {
    long processInstanceId = getExceptionProcId();
    ProcessInstance procInst = jbpmCtx.getProcessInstance(processInstanceId);
    assertThat("No exception process instance returned.", 
      procInst, is(not(nullValue())));
    assertThat("Exception process in unexpected state.", 
      procInst.hasEnded(), is(true));
  } finally {
    // Close context.
    jbpmCtx.close();
  } 
Another nice one to help you find what processes have been deployed in your current jBPMContext:
// find all our processes that have been deployed and log them.
JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance();
JbpmContext jbpmCtx = jbpmConf.createJbpmContext();

  try {
    List listProcs = 
      jbpmCtx.getGraphSession().findAllProcessDefinitions();
    if (getLogger().isDebugEnabled()) {
      for (ProcessDefinition processDefinition : listProcs) {
 getLogger().debug("Process definition is: " 
          + processDefinition 
          + " with version: " 
          + processDefinition.getVersion() 
          + ".");
      }
    }
  } finally {
    jbpmCtx.close();
  }