Search code examples
apache-cameljbpm

How to get the process variable back from jbpm using camel?


I am starting a process in jbpm through camel by passing the variable map. In jbpm I am changing the value of that variable(here "name") and I am not able to get the variable back to camel. Following is the code :

        final Map map = new HashMap();
        JBPMConfiguration bPMConfiguration = new JBPMConfiguration();
        bPMConfiguration.setUserName("admin");
        bPMConfiguration.setPassword("***");
         bPMConfiguration.setProcessId("HelloWorld.helloworldBusinessProcess");
        bPMConfiguration.setDeploymentId("SAN:HelloWorld:1.0");

        bPMConfiguration.setConnectionURL(new URL("http://127.0.0.1:8080/kie-wb62"));
        JBPMEndpoint bPMEndpoint = new JBPMEndpoint("jbpm:http", new JBPMComponent(), bPMConfiguration);
         JBPMProducer bPMProducer=(JBPMProducer) bPMEndpoint.createProducer();
        if (bPMProducer instanceof JBPMProducer) {
         Exchange exchange = ((JBPMProducer) bPMProducer).createExchange();
            map.put("name", "SAntanu");
            bPMConfiguration.setParameters(map);
            exchange.setPattern(ExchangePattern.OutIn);
            exchange.getOut().setHeader("CamelJBPMParameters",map);
            bPMProducer.start();
            bPMProducer.process(exchange);

           }

Solution

  • Here is an example (code is in scala, but i am sure you'll get the idea)

    It uses camel-jbpm to start the process and for custom code to obtain a process variable (pure kie).

    In this demo i am using the standard camel-jbpm component to start the process. To get values, you need a second rest request. At the time of this writing (July 2016), this is not yet supported by the camel-jbpm component. I am using a custom processor to send the FindVariableInstancesCommand request for the name process variable. I have also listed the import statements, as they might not be as evident as you might have thought (notice it is all kie)

    I am using the hiring process from jbpm-workbench *

    package demo.http
    
    import java.net.URL
    
    import org.apache.camel.Exchange
    import org.apache.camel.component.jbpm.JBPMConstants
    import org.apache.camel.scala.dsl.builder.RouteBuilder
    import org.kie.api.runtime.manager.RuntimeEngine
    import org.kie.api.runtime.process.ProcessInstance
    import org.kie.remote.client.api.RemoteRuntimeEngineFactory
    import org.kie.remote.jaxb.gen.FindVariableInstancesCommand
    import org.kie.services.client.serialization.jaxb.impl.audit.JaxbVariableInstanceLog
    
    import scala.collection.JavaConverters._
    
    /**
      * todo
      */
    class JBpmnRoute extends RouteBuilder {
    
        "direct:jbpmRoute" ==> {
          // set the process id
          setHeader(JBPMConstants.PROCESS_ID, constant("hiring"))
    
          // in this example: copy map from in.body to header[JBPMConstants.PARAMETERS]
          process((e: Exchange) => {
            e.getIn().setHeader(JBPMConstants.PARAMETERS, e.in[Map[String, AnyRef]].asJava)
          })
    
          // Start the process
          to("jbpm:http://localhost:8080/jbpm-console?userName=admin&password=admin"
            + "&deploymentId=org.jbpm:HR:1.0&operation=startProcess")
    
          // obtain process variable (in this example "name") 
          process((e: Exchange) => {
            val rte: RuntimeEngine = RemoteRuntimeEngineFactory.newRestBuilder()
              .addUrl(new URL("http://localhost:8080/jbpm-console/")).addUserName("admin").addPassword("admin")
              .addDeploymentId("org.jbpm:HR:1.0").build()
    
            val cmd: FindVariableInstancesCommand = new FindVariableInstancesCommand()
            cmd.setProcessInstanceId(e.in[ProcessInstance].getId)
            cmd.setVariableId("name")
            val result = rte.getKieSession.execute(cmd).asInstanceOf[java.util.List[AnyRef]].asScala
            e.in  = result.head.asInstanceOf[JaxbVariableInstanceLog].getValue
          })
          log("value of name ${body}")
        }
    
    }
    

    Test case used

    @Test
    def exampleTest(): Unit = {
      val param: Map[String, AnyRef] = Map("name" -> "Mike Wheeler")
      val response = template.requestBody("direct:jbpmRoute",
        param, classOf[String])
      org.junit.Assert.assertThat(response, Is.is("Mike Wheeler"))
    
    }
    

    *) If you want to test it quickly, run the following docker container

    docker run -Pd -p 8080:8080 -p 8001:8001 --name jbpm-workbench docker.io/jboss/jbpm-workbench-showcase