You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2018/12/05 12:58:35 UTC

[camel] 25/35: CAMEL-12973: Init deferred to first call when WIH uses Deployment-scoped context in combination with Singleton RuntimeStrategy. Removed redundant double slash from 'direct' URL.

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch sandbox/camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9c421bd1661bb8479472d21634a4d4a675f4500f
Author: Duncan Doyle <Du...@gmail.com>
AuthorDate: Mon Dec 3 11:47:07 2018 +0100

    CAMEL-12973: Init deferred to first call when WIH uses Deployment-scoped context in combination with Singleton RuntimeStrategy. Removed redundant double slash from 'direct' URL.
---
 .../jbpm/workitem/AbstractCamelCommand.java        |   4 +-
 .../workitem/AbstractCamelWorkItemHandler.java     |  51 +++++++---
 .../CamelWorkItemHandlerIntegrationTests.java      |   4 +
 .../DeploymentContextCamelCommandTest.java         |  62 +++++------
 .../workitem/GlobalContextCamelCommandTest.java    |  36 ++++---
 .../workitem/InOnlyCamelWorkItemHandlerTest.java   |  40 ++++----
 .../workitem/InOutCamelWorkItemHandlerTest.java    | 113 ++++++++++++++++++---
 7 files changed, 219 insertions(+), 91 deletions(-)

diff --git a/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelCommand.java b/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelCommand.java
index 1900960..212dd71 100644
--- a/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelCommand.java
+++ b/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelCommand.java
@@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
  * The command passes the {@WorkItem} retrieved from the {@link CommandContext} to the route that has a consumer on the endpoint-id 
  * that can be passed with the <code>camel-endpoint-id</code> {@link WorkItem} parameter. E.g. when a the value "myCamelEndpoint" is passed to the 
  * {link WorkItem} via the <code>camel-endpoint-id</code> parameter, this {@link Command} will send the {@link WorkItem} to 
- * the Camel URI <code>direct://myCamelEndpoint</code>.  
+ * the Camel URI <code>direct:myCamelEndpoint</code>.  
  * <p/>
  * The body of the result {@link Message} of the invocation is returned via the <code>Response</code> parameter. Access to the raw response 
  * {@link Message} is provided via the <code>Message</code> parameter. This gives the user access to more advanced fields like message headers 
@@ -55,7 +55,7 @@ public abstract class AbstractCamelCommand implements Command, Cacheable {
         String camelEndpointId = (String) workItem.getParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM);
 
         // We only support direct. We don't need to support more, as direct simply gives us the entrypoint into the actual Camel Routes.
-        String camelUri = "direct://" + camelEndpointId;
+        String camelUri = "direct:" + camelEndpointId;
         
         ProducerTemplate producerTemplate = getProducerTemplate(ctx);
         Exchange inExchange = ExchangeBuilder.anExchange(producerTemplate.getCamelContext()).withBody(workItem).build();
diff --git a/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelWorkItemHandler.java b/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelWorkItemHandler.java
index d5ea7df..1361889 100644
--- a/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelWorkItemHandler.java
+++ b/components/camel-jbpm/src/main/java/org/apache/camel/component/jbpm/workitem/AbstractCamelWorkItemHandler.java
@@ -35,9 +35,9 @@ import org.slf4j.LoggerFactory;
  * Camel jBPM {@link WorkItemHandler} which allows to call Camel routes with a <code>direct</code> endpoint.
  * <p/>
  * The handler passes the {@WorkItem} to the route that has a consumer on the endpoint-id that can be passed with the
- * <code>CamelEndpointId</code>{@link WorkItem} parameter. E.g. when a the value "myCamelEndpoint" is passed to the {link WorkItem} via
- * the <code>CamelEndpointId</code> parameter, this command will send the {@link WorkItem} to the Camel URI
- * <code>direct://myCamelEndpoint</code>.
+ * <code>CamelEndpointId</code>{@link WorkItem} parameter. E.g. when a the value "myCamelEndpoint" is passed to the {link WorkItem} via the
+ * <code>CamelEndpointId</code> parameter, this command will send the {@link WorkItem} to the Camel URI
+ * <code>direct:myCamelEndpoint</code>.
  * <p/>
  * The body of the result {@link Message} of the invocation is returned via the <code>Response</code> parameter. Access to the raw response
  * {@link Message} is provided via the <code>Message</code> parameter. This gives the user access to more advanced fields like message
@@ -47,18 +47,22 @@ import org.slf4j.LoggerFactory;
  * to find the global KIE {@link CamelContext} from the <code>jBPM</code> {@link ServiceRegistry}. When the {@link RuntimeManager} is passed
  * to the constructor, the handler will retrieve and use the {@link CamelContext} bound to the {@link RuntimeManage} from the
  * {@link ServiceRegistry}. When a <code>CamelEndpointId</code> is passed to the constructor, the handler will send all requests to the
- * Camel route that is consuming from that endpoint, unless the endpoint is overridden by passing a the <code>CamelEndpointId</code> in
- * the {@link WorkItem} parameters.
+ * Camel route that is consuming from that endpoint, unless the endpoint is overridden by passing a the <code>CamelEndpointId</code> in the
+ * {@link WorkItem} parameters.
  * 
  */
 public abstract class AbstractCamelWorkItemHandler extends AbstractLogOrThrowWorkItemHandler implements Cacheable {
 
     private static Logger logger = LoggerFactory.getLogger(AbstractCamelWorkItemHandler.class);
 
-    private final ProducerTemplate producerTemplate;
+    private ProducerTemplate producerTemplate;
 
     private final String camelEndpointId;
-
+    
+    private final String camelContextKey;
+    
+    private boolean initialized = false;
+    
     /**
      * Default Constructor. This creates a {@link ProducerTemplate} for the global {@link CamelContext}.
      */
@@ -67,9 +71,10 @@ public abstract class AbstractCamelWorkItemHandler extends AbstractLogOrThrowWor
     }
 
     public AbstractCamelWorkItemHandler(String camelEndointId) {
-        CamelContext globalCamelContext = (CamelContext) ServiceRegistry.get().service(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
-        this.producerTemplate = globalCamelContext.createProducerTemplate();
         this.camelEndpointId = camelEndointId;
+        this.camelContextKey = JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY;
+        this.producerTemplate = buildProducerTemplate(camelContextKey);
+        this.initialized = true;
     }
 
     /**
@@ -81,18 +86,38 @@ public abstract class AbstractCamelWorkItemHandler extends AbstractLogOrThrowWor
     }
 
     public AbstractCamelWorkItemHandler(RuntimeManager runtimeManager, String camelEndpointId) {
-        String runtimeCamelContextKey = runtimeManager.getIdentifier() + JBPMConstants.DEPLOYMENT_CAMEL_CONTEXT_SERVICE_KEY_POSTFIX;
-        CamelContext runtimeCamelContext = (CamelContext) ServiceRegistry.get().service(runtimeCamelContextKey);
-        this.producerTemplate = runtimeCamelContext.createProducerTemplate();
         this.camelEndpointId = camelEndpointId;
+        this.camelContextKey = runtimeManager.getIdentifier() + JBPMConstants.DEPLOYMENT_CAMEL_CONTEXT_SERVICE_KEY_POSTFIX;
+        /*
+         * Depending on the order of session creation and CamelContext creation and registration, the CamelContext might not yet be
+         * available. Hence, when we deal with a Deployment scoped CamelContext, we can lazy-init when the context is not yet available.
+         */
+        try {
+            this.producerTemplate = buildProducerTemplate(camelContextKey);
+            this.initialized = true;
+        } catch (IllegalArgumentException iae) {
+            String message = "CamelContext with identifier '" + camelContextKey
+                    + "' not found in ServiceRegistry. This can be caused by the order in which the platform extensions are initialized. Deferring Camel ProducerTemplate creation until the first WorkItemHandler call.";
+            logger.info(message, iae);
+        }
     }
 
+    private ProducerTemplate buildProducerTemplate(String key) {
+        CamelContext camelContext = (CamelContext) ServiceRegistry.get().service(key);
+        return this.producerTemplate = camelContext.createProducerTemplate();
+    }
+    
+    
     public void executeWorkItem(WorkItem workItem, final WorkItemManager manager) {
+        if (!initialized) {
+            this.producerTemplate = buildProducerTemplate(camelContextKey);
+            initialized = true;
+        }
 
         String workItemCamelEndpointId = getCamelEndpointId(workItem);
 
         // We only support direct. We don't need to support more, as direct simply gives us the entrypoint into the actual Camel Routes.
-        String camelUri = "direct://" + workItemCamelEndpointId;
+        String camelUri = "direct:" + workItemCamelEndpointId;
 
         try {
             Exchange requestExchange = buildExchange(producerTemplate, workItem);
diff --git a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/CamelWorkItemHandlerIntegrationTests.java b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/CamelWorkItemHandlerIntegrationTests.java
index 67d54fb..a0fcee5 100644
--- a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/CamelWorkItemHandlerIntegrationTests.java
+++ b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/CamelWorkItemHandlerIntegrationTests.java
@@ -79,6 +79,7 @@ public class CamelWorkItemHandlerIntegrationTests extends CamelTestSupport {
         } finally {
             // Cleanup
             context.removeRoute(routeId);
+            ServiceRegistry.get().remove(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
         }
     }
 
@@ -120,6 +121,7 @@ public class CamelWorkItemHandlerIntegrationTests extends CamelTestSupport {
         } finally {
             // Cleanup
             context.removeRoute(routeId);
+            ServiceRegistry.get().remove(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
         }
     }
 
@@ -160,6 +162,7 @@ public class CamelWorkItemHandlerIntegrationTests extends CamelTestSupport {
         } finally {
             // Cleanup
             context.removeRoute(routeId);
+            ServiceRegistry.get().remove(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
         }
 
     }
@@ -198,6 +201,7 @@ public class CamelWorkItemHandlerIntegrationTests extends CamelTestSupport {
         } finally {
             // Cleanup
             context.removeRoute(routeId);
+            ServiceRegistry.get().remove(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
         }
     }
 
diff --git a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/DeploymentContextCamelCommandTest.java b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/DeploymentContextCamelCommandTest.java
index b0086b9..d2d3d94 100644
--- a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/DeploymentContextCamelCommandTest.java
+++ b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/DeploymentContextCamelCommandTest.java
@@ -38,58 +38,62 @@ import static org.mockito.Mockito.*;
 
 @RunWith(MockitoJUnitRunner.class)
 public class DeploymentContextCamelCommandTest {
-    
+
     @Mock
     ProducerTemplate producerTemplate;
 
     @Mock
     Exchange outExchange;
-    
+
     @Mock
     Message outMessage;
-    
+
     @Mock
     CamelContext camelContext;
-    
+
     @Mock
     RuntimeManager runtimeManager;
-    
+
     @Mock
     CommandContext commandContext;
 
     @Test
     public void testExecuteCommandDeploymentCamelContext() throws Exception {
-    
+
         String camelEndpointId = "testCamelRoute";
-        String camelRouteUri = "direct://" + camelEndpointId;
-        
+        String camelRouteUri = "direct:" + camelEndpointId;
+
         String testReponse = "testResponse";
-        
+
         String deploymentId = "testDeployment";
-        
+
         when(producerTemplate.send(eq(camelRouteUri), any(Exchange.class))).thenReturn(outExchange);
         when(producerTemplate.getCamelContext()).thenReturn(camelContext);
-        
+
         when(camelContext.createProducerTemplate()).thenReturn(producerTemplate);
-        
+
         when(outExchange.getOut()).thenReturn(outMessage);
         when(outMessage.getBody()).thenReturn(testReponse);
-        
-        //Register the RuntimeManager bound camelcontext.
-        ServiceRegistry.get().register(deploymentId + JBPMConstants.DEPLOYMENT_CAMEL_CONTEXT_SERVICE_KEY_POSTFIX, camelContext);
-        
-        WorkItemImpl workItem = new WorkItemImpl();
-        workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
-        workItem.setParameter("Request", "someRequest");
-        
-        when(commandContext.getData("workItem")).thenReturn(workItem);
-        when(commandContext.getData("deploymentId")).thenReturn(deploymentId);
-        
-        Command command = new DeploymentContextCamelCommand();
-        ExecutionResults results = command.execute(commandContext);
-        
-        assertNotNull(results);
-        assertEquals(2, results.getData().size());
-        assertEquals(testReponse, results.getData().get(JBPMConstants.RESPONSE_WI_PARAM));
+
+        // Register the RuntimeManager bound camelcontext.
+        try {
+            ServiceRegistry.get().register(deploymentId + JBPMConstants.DEPLOYMENT_CAMEL_CONTEXT_SERVICE_KEY_POSTFIX, camelContext);
+
+            WorkItemImpl workItem = new WorkItemImpl();
+            workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
+            workItem.setParameter("Request", "someRequest");
+
+            when(commandContext.getData("workItem")).thenReturn(workItem);
+            when(commandContext.getData("deploymentId")).thenReturn(deploymentId);
+
+            Command command = new DeploymentContextCamelCommand();
+            ExecutionResults results = command.execute(commandContext);
+
+            assertNotNull(results);
+            assertEquals(2, results.getData().size());
+            assertEquals(testReponse, results.getData().get(JBPMConstants.RESPONSE_WI_PARAM));
+        } finally {
+            ServiceRegistry.get().remove(deploymentId + JBPMConstants.DEPLOYMENT_CAMEL_CONTEXT_SERVICE_KEY_POSTFIX);
+        }
     }
 }
diff --git a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/GlobalContextCamelCommandTest.java b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/GlobalContextCamelCommandTest.java
index 031bc69..0d0db7c 100644
--- a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/GlobalContextCamelCommandTest.java
+++ b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/GlobalContextCamelCommandTest.java
@@ -44,16 +44,16 @@ public class GlobalContextCamelCommandTest {
 
     @Mock
     Exchange outExchange;
-    
+
     @Mock
     Message outMessage;
-    
+
     @Mock
     CamelContext camelContext;
-    
+
     @Mock
     RuntimeManager runtimeManager;
-    
+
     @Mock
     CommandContext commandContext;
 
@@ -61,7 +61,7 @@ public class GlobalContextCamelCommandTest {
     public void testExecuteGlobalCommand() throws Exception {
     
         String camelEndpointId = "testCamelRoute";
-        String camelRouteUri = "direct://" + camelEndpointId;
+        String camelRouteUri = "direct:" + camelEndpointId;
 
         String testReponse = "testResponse";
 
@@ -76,20 +76,24 @@ public class GlobalContextCamelCommandTest {
         when(outExchange.getOut()).thenReturn(outMessage);
         when(outMessage.getBody()).thenReturn(testReponse);
 
-        //Register the RuntimeManager bound camelContext.
-        ServiceRegistry.get().register(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY, camelContext);
+        // Register the RuntimeManager bound camelcontext.
+        try {
+            ServiceRegistry.get().register(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY, camelContext);
 
-        WorkItemImpl workItem = new WorkItemImpl();
-        workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
-        workItem.setParameter("Request", "someRequest");
+            WorkItemImpl workItem = new WorkItemImpl();
+            workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
+            workItem.setParameter("Request", "someRequest");
 
-        when(commandContext.getData(anyString())).thenReturn(workItem);
+            when(commandContext.getData(anyString())).thenReturn(workItem);
 
-        Command command = new GlobalContextCamelCommand();
-        ExecutionResults results = command.execute(commandContext);
+            Command command = new GlobalContextCamelCommand();
+            ExecutionResults results = command.execute(commandContext);
 
-        assertNotNull(results);
-        assertEquals(2, results.getData().size());
-        assertEquals(testReponse, results.getData().get(JBPMConstants.RESPONSE_WI_PARAM));
+            assertNotNull(results);
+            assertEquals(2, results.getData().size());
+            assertEquals(testReponse, results.getData().get(JBPMConstants.RESPONSE_WI_PARAM));
+        } finally {
+            ServiceRegistry.get().remove(JBPMConstants.GLOBAL_CAMEL_CONTEXT_SERVICE_KEY);
+        }
     }
 }
\ No newline at end of file
diff --git a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOnlyCamelWorkItemHandlerTest.java b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOnlyCamelWorkItemHandlerTest.java
index b97822e..324f04c 100644
--- a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOnlyCamelWorkItemHandlerTest.java
+++ b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOnlyCamelWorkItemHandlerTest.java
@@ -60,7 +60,7 @@ public class InOnlyCamelWorkItemHandlerTest {
     public void testExecuteInOnlyLocalCamelContext() throws Exception {
 
         String camelEndpointId = "testCamelRoute";
-        String camelRouteUri = "direct://" + camelEndpointId;
+        String camelRouteUri = "direct:" + camelEndpointId;
 
         String testReponse = "testResponse";
 
@@ -76,22 +76,26 @@ public class InOnlyCamelWorkItemHandlerTest {
         when(camelContext.getHeadersMapFactory()).thenReturn(hmf);
 
         // Register the RuntimeManager bound camelcontext.
-        ServiceRegistry.get().register(runtimeManagerId + "_CamelService", camelContext);
-
-        WorkItemImpl workItem = new WorkItemImpl();
-        workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
-        workItem.setParameter("Request", "someRequest");
-        workItem.setDeploymentId("testDeploymentId");
-        workItem.setProcessInstanceId(1L);
-        workItem.setId(1L);
-        
-        AbstractCamelWorkItemHandler handler = new InOnlyCamelWorkItemHandler(runtimeManager);
-
-        TestWorkItemManager manager = new TestWorkItemManager();
-        handler.executeWorkItem(workItem,
-                manager);
-        assertThat(manager.getResults(), is(notNullValue()));
-        //InOnly does not complete WorkItem.
-        assertThat(manager.getResults().size(), equalTo(0));
+        try {
+            ServiceRegistry.get().register(runtimeManagerId + "_CamelService", camelContext);
+
+            WorkItemImpl workItem = new WorkItemImpl();
+            workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
+            workItem.setParameter("Request", "someRequest");
+            workItem.setDeploymentId("testDeploymentId");
+            workItem.setProcessInstanceId(1L);
+            workItem.setId(1L);
+
+            AbstractCamelWorkItemHandler handler = new InOnlyCamelWorkItemHandler(runtimeManager);
+
+            TestWorkItemManager manager = new TestWorkItemManager();
+            handler.executeWorkItem(workItem,
+                    manager);
+            assertThat(manager.getResults(), is(notNullValue()));
+            // InOnly does not complete WorkItem.
+            assertThat(manager.getResults().size(), equalTo(0));
+        } finally {
+            ServiceRegistry.get().remove(runtimeManagerId + "_CamelService");
+        }
     }
 }
diff --git a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOutCamelWorkItemHandlerTest.java b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOutCamelWorkItemHandlerTest.java
index 578de78..8453f09 100644
--- a/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOutCamelWorkItemHandlerTest.java
+++ b/components/camel-jbpm/src/test/java/org/apache/camel/component/jbpm/workitem/InOutCamelWorkItemHandlerTest.java
@@ -63,7 +63,7 @@ public class InOutCamelWorkItemHandlerTest {
     public void testExecuteInOutGlobalCamelContext() throws Exception {
 
         String camelEndpointId = "testCamelRoute";
-        String camelRouteUri = "direct://" + camelEndpointId;
+        String camelRouteUri = "direct:" + camelEndpointId;
 
         String testReponse = "testResponse";
 
@@ -77,6 +77,7 @@ public class InOutCamelWorkItemHandlerTest {
         when(outExchange.getOut()).thenReturn(outMessage);
         when(outMessage.getBody()).thenReturn(testReponse);
 
+        try {
         ServiceRegistry.get().register("GlobalCamelService", camelContext);
 
         TestWorkItemManager manager = new TestWorkItemManager();
@@ -97,13 +98,18 @@ public class InOutCamelWorkItemHandlerTest {
         Map<String, Object> results = manager.getResults(workItem.getId());
         assertThat(results.size(), equalTo(2));
         assertThat(results.get("Response"), equalTo(testReponse));
+        
+        } finally {
+            ServiceRegistry.get().remove("GlobalCamelService");
+        }
+        
     }
 
     @Test
     public void testExecuteInOutLocalCamelContext() throws Exception {
 
         String camelEndpointId = "testCamelRoute";
-        String camelRouteUri = "direct://" + camelEndpointId;
+        String camelRouteUri = "direct:" + camelEndpointId;
 
         String testReponse = "testResponse";
 
@@ -122,7 +128,94 @@ public class InOutCamelWorkItemHandlerTest {
         when(outMessage.getBody()).thenReturn(testReponse);
 
         // Register the RuntimeManager bound camelcontext.
-        ServiceRegistry.get().register(runtimeManagerId + "_CamelService", camelContext);
+        try {
+            ServiceRegistry.get().register(runtimeManagerId + "_CamelService", camelContext);
+
+            WorkItemImpl workItem = new WorkItemImpl();
+            workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
+            workItem.setParameter("Request", "someRequest");
+            workItem.setDeploymentId("testDeploymentId");
+            workItem.setProcessInstanceId(1L);
+            workItem.setId(1L);
+
+            AbstractCamelWorkItemHandler handler = new InOutCamelWorkItemHandler(runtimeManager);
+
+            TestWorkItemManager manager = new TestWorkItemManager();
+            handler.executeWorkItem(workItem,
+                    manager);
+            assertThat(manager.getResults(), is(notNullValue()));
+            assertThat(manager.getResults().size(), equalTo(1));
+            assertThat(manager.getResults().containsKey(workItem.getId()), is(true));
+
+            Map<String, Object> results = manager.getResults(workItem.getId());
+            assertThat(results.size(), equalTo(2));
+            assertThat(results.get(JBPMConstants.RESPONSE_WI_PARAM), equalTo(testReponse));
+        } finally {
+            ServiceRegistry.get().remove(runtimeManagerId + "_CamelService");
+        }
+    }
+
+    @Test
+    public void testExecuteInOutLocalCamelContextLazyInit() throws Exception {
+
+        String camelEndpointId = "testCamelRoute";
+        String camelRouteUri = "direct:" + camelEndpointId;
+
+        String testReponse = "testResponse";
+
+        String runtimeManagerId = "testRuntimeManager";
+
+        when(runtimeManager.getIdentifier()).thenReturn(runtimeManagerId);
+
+        when(producerTemplate.send(eq(camelRouteUri), ArgumentMatchers.any(Exchange.class))).thenReturn(outExchange);
+        when(producerTemplate.getCamelContext()).thenReturn(camelContext);
+
+        when(camelContext.createProducerTemplate()).thenReturn(producerTemplate);
+        HeadersMapFactory hmf = new DefaultHeadersMapFactory();
+        when(camelContext.getHeadersMapFactory()).thenReturn(hmf);
+
+        when(outExchange.getOut()).thenReturn(outMessage);
+        when(outMessage.getBody()).thenReturn(testReponse);
+
+        WorkItemImpl workItem = new WorkItemImpl();
+        workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
+        workItem.setParameter("Request", "someRequest");
+        workItem.setDeploymentId("testDeploymentId");
+        workItem.setProcessInstanceId(1L);
+        workItem.setId(1L);
+
+        AbstractCamelWorkItemHandler handler = new InOutCamelWorkItemHandler(runtimeManager);
+
+        // Register the context after we've created the WIH to test lazy-init.
+        try {
+            ServiceRegistry.get().register(runtimeManagerId + "_CamelService", camelContext);
+
+            TestWorkItemManager manager = new TestWorkItemManager();
+            handler.executeWorkItem(workItem,
+                    manager);
+            assertThat(manager.getResults(), is(notNullValue()));
+            assertThat(manager.getResults().size(), equalTo(1));
+            assertThat(manager.getResults().containsKey(workItem.getId()), is(true));
+
+            Map<String, Object> results = manager.getResults(workItem.getId());
+            assertThat(results.size(), equalTo(2));
+            assertThat(results.get(JBPMConstants.RESPONSE_WI_PARAM), equalTo(testReponse));
+        } finally {
+            ServiceRegistry.get().remove(runtimeManagerId + "_CamelService");
+        }
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testExecuteInOutLocalCamelContextLazyInitFail() throws Exception {
+
+        String camelEndpointId = "testCamelRoute";
+        String camelRouteUri = "direct:" + camelEndpointId;
+
+        String testReponse = "testResponse";
+
+        String runtimeManagerId = "testRuntimeManager";
+
+        when(runtimeManager.getIdentifier()).thenReturn(runtimeManagerId);
 
         WorkItemImpl workItem = new WorkItemImpl();
         workItem.setParameter(JBPMConstants.CAMEL_ENDPOINT_ID_WI_PARAM, camelEndpointId);
@@ -134,15 +227,9 @@ public class InOutCamelWorkItemHandlerTest {
         AbstractCamelWorkItemHandler handler = new InOutCamelWorkItemHandler(runtimeManager);
 
         TestWorkItemManager manager = new TestWorkItemManager();
-        handler.executeWorkItem(workItem,
-                manager);
-        assertThat(manager.getResults(), is(notNullValue()));
-        assertThat(manager.getResults().size(), equalTo(1));
-        assertThat(manager.getResults().containsKey(workItem.getId()), is(true));
-        
-        Map<String, Object> results = manager.getResults(workItem.getId());
-        assertThat(results.size(), equalTo(2));
-        assertThat(results.get(JBPMConstants.RESPONSE_WI_PARAM), equalTo(testReponse));
+        // This is expected to throw an exception.
+        handler.executeWorkItem(workItem, manager);
+
     }
-   
+
 }