cancel
Showing results for 
Search instead for 
Did you mean: 

Weird issue when using Camel with Activiti

sdesbure
Champ in-the-making
Champ in-the-making
Hello all,
First I'm quite a noob in Spring, Activiti and Camel so I hope that my issue is an easy one ^^. And sorry for the previous topic which is not working…

So for my further needs, I want to use Camel for a long processing task.

I've then created the following flow to test:


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
   xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
   typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
   targetNamespace="http://www.activiti.org/test">
   <process id="camelProcess" isExecutable="true">
      <startEvent id="start">
         <extensionElements>
            <activiti:formProperty id="first_var"
               name="first Var" type="string" default="first-variable"
               required="true"></activiti:formProperty>
            <activiti:formProperty id="customer_name"
               name="Client Name" type="string" default="Customer" required="true"></activiti:formProperty>
         </extensionElements>
      </startEvent>
      <sequenceFlow id="flow1" sourceRef="start" targetRef="camelTask"></sequenceFlow>
      <serviceTask id="camelTask" name="Invoke Camel route"
         activiti:type="camel">
         <!– <extensionElements>
            <activiti:field name="camelBehaviorClass"
               stringValue="org.activiti.camel.impl.CamelBehaviorDefaultImpl" />
         </extensionElements> –>
      </serviceTask>
      <sequenceFlow id="flow2" sourceRef="camelTask" targetRef="receiveTask"></sequenceFlow>
      <receiveTask id="receiveTask" name="Wait for response"></receiveTask>
      <serviceTask id="servicetask1" name="Service Task"
         activiti:class="com.easyvpn.oss.orchestrator.workflow.TestTask"></serviceTask>
      <sequenceFlow id="flow3" sourceRef="receiveTask"
         targetRef="servicetask1"></sequenceFlow>
      <endEvent id="endevent1" name="End"></endEvent>
      <sequenceFlow id="flow4" sourceRef="servicetask1"
         targetRef="endevent1"></sequenceFlow>
   </process>
</definitions>


I've got the following route in Camel:

import org.apache.camel.builder.RouteBuilder;

public class AsyncTestCamel extends RouteBuilder {

    @Override
    public void configure() throws Exception {
       from("activiti:camelProcess:camelTask").to("seda:asyncQueue");
       from("seda:asyncQueue").to("bean:testAsyncTask").to("seda:receiveQueue");
       from("seda:receiveQueue").to("activiti:camelProcess:receiveTask");
   }
}


I've got the following classes:

import java.util.Map;

import org.apache.camel.OutHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestAsyncTask {
   private static final Logger logger = LoggerFactory.getLogger(CreateInternetFirewallServiceInstance.class);
   
   public void execute(String first_var, String customer_name, @OutHeaders Map<String,String> headers) throws Exception {
      logger.debug("Entering CreateInternetFirewallServiceInstance");
      logger.debug("value received: first_var: "+first_var+", customer_name: "+customer_name);

      String name = customer_name.replaceAll(" ", "-").replaceAll("_", "-").toLowerCase() + "-test-test";
      headers.put("new_var", name);
   }
}



import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestTask implements JavaDelegate {
   private static final Logger logger = LoggerFactory.getLogger(CreateCoreVirtualNetwork.class);

   @Override
   public void execute(DelegateExecution execution) throws Exception {
      String new_var = (String) execution.getVariable("new_var");
      logger.debug("retrieved new_var: "+new_var);
   }

}


To test that, I use the following test class:

import static org.junit.Assert.assertNotNull;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyProcessTest {
   private static final Logger logger = LoggerFactory.getLogger(CreateInternetChainTest.class);

   @Rule
   public ActivitiRule activitiRule = new ActivitiRule("activiti.cfg-mem.xml");
   
   @Test
   @Deployment(resources={"diagrams/MyProcess.bpmn"})
   public void startMyProcess() {
      logger.debug("Starting test");
      RuntimeService runtimeService = activitiRule.getProcessEngine().getRuntimeService();

      Map<String, Object> formProperties = new HashMap<String, Object>();
      formProperties.put("first_var", "var-var");
      formProperties.put("customer_name", "Customer Name");
      
      ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("camelProcess", formProperties);
      logger.debug("processInstance ID: "+processInstance.getId());
         
      assertNotNull(processInstance.getId());
   }
      
}


Finally, I use the following spring configurations (activiti.cfg-mem.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
   xmlns:camel="http://camel.apache.org/schema/spring"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

   <context:property-placeholder location="classpath:application.properties"
      ignore-resource-not-found="false" />

   <import resource="orchestrator.xml" />

   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
      <property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
   </bean>

   <bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>

   <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
      <property name="dataSource" ref="dataSource" />
      <property name="transactionManager" ref="transactionManager" />
      <property name="databaseSchemaUpdate" value="true" />
      <property name="jobExecutorActivate" value="false" />
   </bean>

   <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
      <property name="processEngineConfiguration" ref="processEngineConfiguration" />
   </bean>

   <bean id="repositoryService" factory-bean="processEngine"
      factory-method="getRepositoryService" />
   <bean id="runtimeService" factory-bean="processEngine"
      factory-method="getRuntimeService" />
   <bean id="taskService" factory-bean="processEngine"
      factory-method="getTaskService" />
   <bean id="historyService" factory-bean="processEngine"
      factory-method="getHistoryService" />
   <bean id="managementService" factory-bean="processEngine"
      factory-method="getManagementService" />


</beans>


(orchestrator.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
   xmlns:camel="http://camel.apache.org/schema/spring"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

   <context:property-placeholder location="classpath:application.properties"
      ignore-resource-not-found="false" />

   <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
      <property name="brokerURL" value="tcp://somehost:61616" />
   </bean>

   <camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
      <packageScan>
         <package>com.easyvpn.oss.orchestrator.routes</package>
      </packageScan>
   </camelContext>

   <bean id="mapper" class="com.fasterxml.jackson.databind.ObjectMapper" />

   <bean id="testTask" class="com.easyvpn.oss.orchestrator.workflow.TestTask">
   </bean>

   <bean id="testAsyncTask" class="com.easyvpn.oss.orchestrator.workflow.TestAsyncTask">
   </bean>

</beans>


When I launch my test via Eclipse (maven seems to load the right jars, i.e. activiti-***-5.16.4, camel-***-2.14.0, activemq-***-5.10, …), Here's the following error I have:

DEBUG TransactionTemplate - Initiating transaction rollback on application exception
java.lang.NullPointerException
   at org.activiti.camel.CamelBehavior.setAppropriateCamelContext(CamelBehavior.java:222)
   at org.activiti.camel.CamelBehavior.execute(CamelBehavior.java:107)



the log of the test is attached

any idea why it's not working?

Thanks in advance
1 REPLY 1

smirzai
Champ on-the-rise
Champ on-the-rise
I am not sure if ActivitiRule creates a real spring context or it only reads the config file.
Safer is to use something like this for test cases:

<code>
@ContextConfiguration("classpath:camel-activiti-context.xml")
public class AsyncPingTest extends SpringActivitiTestCase {

  @Autowired
  RuntimeService runtimeService;

  @Deployment(resources = {"process/asyncPing.bpmn20.xml"})
  public void testRunProcess() throws Exception {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("asyncPingProcess");
   
    List<Execution> executionList = runtimeService.createExecutionQuery().list();
</code>