Author: jstrachan
Date: Mon Feb 28 19:20:56 2011
New Revision: 1075495

URL: http://svn.apache.org/viewvc?rev=1075495&view=rev
Log:
fix for CAMEL-3726 to show camel-context working using Spring IoC along with 
solving a dependency issue with CamelPostProcessorHelper causing eager loading 
of CamelContext objects which breaks the depends-on attribute usage

Added:
    
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/SpringDslContextComponentTest.java
    camel/trunk/components/camel-context/src/test/resources/org/
    camel/trunk/components/camel-context/src/test/resources/org/apache/
    camel/trunk/components/camel-context/src/test/resources/org/apache/camel/
    
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/
    
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/
    
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/SpringDslContextComponentTest-context.xml
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
    camel/trunk/components/camel-context/pom.xml
    
camel/trunk/components/camel-context/src/main/java/org/apache/camel/component/context/LocalContextComponent.java
    
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/JavaDslBlackBoxTest.java
    
camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java?rev=1075495&r1=1075494&r2=1075495&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
 Mon Feb 28 19:20:56 2011
@@ -75,7 +75,7 @@ public class CamelPostProcessorHelper im
      */
     public boolean matchContext(String context) {
         if (ObjectHelper.isNotEmpty(context)) {
-            if (!camelContext.getName().equals(context)) {
+            if (!getCamelContext().getName().equals(context)) {
                 return false;
             }
         }

Modified: camel/trunk/components/camel-context/pom.xml
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-context/pom.xml?rev=1075495&r1=1075494&r2=1075495&view=diff
==============================================================================
--- camel/trunk/components/camel-context/pom.xml (original)
+++ camel/trunk/components/camel-context/pom.xml Mon Feb 28 19:20:56 2011
@@ -51,6 +51,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-xml</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
             <artifactId>camel-test</artifactId>
             <scope>test</scope>
         </dependency>

Modified: 
camel/trunk/components/camel-context/src/main/java/org/apache/camel/component/context/LocalContextComponent.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-context/src/main/java/org/apache/camel/component/context/LocalContextComponent.java?rev=1075495&r1=1075494&r2=1075495&view=diff
==============================================================================
--- 
camel/trunk/components/camel-context/src/main/java/org/apache/camel/component/context/LocalContextComponent.java
 (original)
+++ 
camel/trunk/components/camel-context/src/main/java/org/apache/camel/component/context/LocalContextComponent.java
 Mon Feb 28 19:20:56 2011
@@ -35,7 +35,7 @@ public class LocalContextComponent exten
     private static final transient Logger LOG = 
LoggerFactory.getLogger(LocalContextComponent.class);
 
     private CamelContext localCamelContext;
-    private List<String> localProtocolSchemes = new 
ArrayList<String>(Arrays.asList("direct", "seda"));
+    private List<String> localProtocolSchemes = new 
ArrayList<String>(Arrays.asList("direct", "seda", "mock"));
 
     public LocalContextComponent(CamelContext localCamelContext) {
         ObjectHelper.notNull(localCamelContext, "localCamelContext");
@@ -65,8 +65,14 @@ public class LocalContextComponent exten
     protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters)
         throws Exception {
 
+
+
         // lets first check if we are using a fully qualified name: 
[context:]contextId:endpointUri
         Map<String, Endpoint> map = getLocalCamelContext().getEndpointMap();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Trying to lookup " + remaining + " in local map " + 
map.keySet());
+        }
         Endpoint endpoint = map.get(remaining);
         if (endpoint != null) {
             logUsingEndpoint(uri, endpoint);

Modified: 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/JavaDslBlackBoxTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/JavaDslBlackBoxTest.java?rev=1075495&r1=1075494&r2=1075495&view=diff
==============================================================================
--- 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/JavaDslBlackBoxTest.java
 (original)
+++ 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/JavaDslBlackBoxTest.java
 Mon Feb 28 19:20:56 2011
@@ -38,7 +38,7 @@ public class JavaDslBlackBoxTest extends
     private ProducerTemplate template;
 
     @Test
-    public void testUsingBlackBox() throws Exception {
+    public void testUsingContextComponent() throws Exception {
         resultEndpoint.expectedHeaderReceived("received", "true");
         resultEndpoint.expectedMessageCount(2);
 
@@ -58,8 +58,8 @@ public class JavaDslBlackBoxTest extends
         blackBox.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                // receive purchase orders, lets process it in some way then 
send an invoice
-                // to our invoice endpoint
+                // receive purchase orders, lets process it in some way then
+                // send an invoice to our invoice endpoint
                 
from("direct:purchaseOrder").setHeader("received").constant("true").to("direct:invoice");
             }
         });

Added: 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/SpringDslContextComponentTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/SpringDslContextComponentTest.java?rev=1075495&view=auto
==============================================================================
--- 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/SpringDslContextComponentTest.java
 (added)
+++ 
camel/trunk/components/camel-context/src/test/java/org/apache/camel/component/context/SpringDslContextComponentTest.java
 Mon Feb 28 19:20:56 2011
@@ -0,0 +1,67 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.context;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.context.ContextConfiguration;
+import 
org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import java.util.List;
+
+/**
+ * Test defining a context component using the Spring XML DSL
+ */
+@ContextConfiguration
+public class SpringDslContextComponentTest extends 
AbstractJUnit4SpringContextTests {
+    private static final transient Logger LOG = 
LoggerFactory.getLogger(SpringDslContextComponentTest.class);
+
+    @EndpointInject(uri = "tester:results")
+    private MockEndpoint resultEndpoint;
+
+    @Produce(uri = "tester:start")
+    private ProducerTemplate template;
+
+    @Test
+    public void testUsingContextComponent() throws Exception {
+
+        Object accounts = applicationContext.getBean("accounts");
+        System.out.println("Found accounts: " + accounts);
+
+        resultEndpoint.expectedHeaderReceived("received", "true");
+        resultEndpoint.expectedMessageCount(2);
+
+        template.sendBody("<purchaseOrder>one</purchaseOrder>");
+        template.sendBody("<purchaseOrder>two</purchaseOrder>");
+
+        resultEndpoint.assertIsSatisfied();
+
+        List<Exchange> receivedExchanges = 
resultEndpoint.getReceivedExchanges();
+        for (Exchange exchange : receivedExchanges) {
+            Message in = exchange.getIn();
+            LOG.info("Received from: " + exchange.getFromEndpoint() + " 
headers: " + in.getHeaders() + " body: " + in.getBody());
+        }
+    }
+}

Added: 
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/SpringDslContextComponentTest-context.xml
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/SpringDslContextComponentTest-context.xml?rev=1075495&view=auto
==============================================================================
--- 
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/SpringDslContextComponentTest-context.xml
 (added)
+++ 
camel/trunk/components/camel-context/src/test/resources/org/apache/camel/component/context/SpringDslContextComponentTest-context.xml
 Mon Feb 28 19:20:56 2011
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+  <!-- the test case route -->
+  <camelContext id="tester" xmlns="http://camel.apache.org/schema/spring"; 
depends-on="accounts">
+    <route>
+      <from uri="direct:start"/>
+      <to uri="accounts:purchaseOrder"/>
+    </route>
+    <route>
+      <from uri="accounts:invoice"/>
+      <to uri="mock:results"/>
+    </route>
+  </camelContext>
+
+  <!-- lets define a context component -->
+  <camelContext id="accounts" xmlns="http://camel.apache.org/schema/spring";>
+    <route>
+      <!--
+        receive purchase orders, lets process it in some way then
+        send an invoice to our invoice endpoint
+      -->
+      <from uri="direct:purchaseOrder"/>
+      <setHeader headerName="received">
+        <constant>true</constant>
+      </setHeader>
+      <to uri="direct:invoice"/>
+    </route>
+  </camelContext>
+
+
+
+
+</beans>

Modified: 
camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java?rev=1075495&r1=1075494&r2=1075495&view=diff
==============================================================================
--- 
camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
 (original)
+++ 
camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
 Mon Feb 28 19:20:56 2011
@@ -91,19 +91,16 @@ public class CamelBeanPostProcessor impl
             return bean;
         }
 
-        if (camelContext == null && applicationContext.containsBean(camelId)) {
-            setCamelContext((CamelContext) 
applicationContext.getBean(camelId));
-        }
-
         injectFields(bean, beanName);
         injectMethods(bean, beanName);
 
         if (bean instanceof CamelContextAware && canSetCamelContext(bean, 
beanName)) {
             CamelContextAware contextAware = (CamelContextAware)bean;
-            if (camelContext == null) {
+            CamelContext context = getOrLookupCamelContext();
+            if (context == null) {
                 LOG.warn("No CamelContext defined yet so cannot inject into 
bean: " + beanName);
             } else {
-                contextAware.setCamelContext(camelContext);
+                contextAware.setCamelContext(context);
             }
         }
 
@@ -141,36 +138,6 @@ public class CamelBeanPostProcessor impl
 
     public void setCamelContext(CamelContext camelContext) {
         this.camelContext = camelContext;
-        postProcessor = new CamelPostProcessorHelper(camelContext) {
-            @Override
-            protected RuntimeException 
createProxyInstantiationRuntimeException(Class<?> type, Endpoint endpoint, 
Exception e) {
-                return new BeanInstantiationException(type, "Could not 
instantiate proxy of type " + type.getName() + " on endpoint " + endpoint, e);
-            }
-
-            protected boolean isSingleton(Object bean, String beanName) {
-                // no application context has been injected which means the 
bean
-                // has not been enlisted in Spring application context
-                if (applicationContext == null || beanName == null) {
-                    return super.isSingleton(bean, beanName);
-                } else {
-                    return applicationContext.isSingleton(beanName);
-                }
-            }
-
-            protected void startService(Service service, Object bean, String 
beanName) throws Exception {
-                if (isSingleton(bean, beanName)) {
-                    getCamelContext().addService(service);
-                } else {
-                    // only start service and do not add it to CamelContext
-                    ServiceHelper.startService(service);
-                    if (prototypeBeans.add(beanName)) {
-                        // do not spam the log with WARN so do this only once 
per bean name
-                        LOG.warn("The bean with id [" + beanName + "] is 
prototype scoped and cannot stop the injected service when bean is destroyed: "
-                                + service + ". You may want to stop the 
service manually from the bean.");
-                    }
-                }
-            }
-        };
     }
 
     public String getCamelId() {
@@ -228,12 +195,12 @@ public class CamelBeanPostProcessor impl
         ReflectionUtils.doWithFields(bean.getClass(), new 
ReflectionUtils.FieldCallback() {
             public void doWith(Field field) throws IllegalArgumentException, 
IllegalAccessException {
                 EndpointInject endpointInject = 
field.getAnnotation(EndpointInject.class);
-                if (endpointInject != null && 
postProcessor.matchContext(endpointInject.context())) {
+                if (endpointInject != null && 
getPostProcessor().matchContext(endpointInject.context())) {
                     injectField(field, endpointInject.uri(), 
endpointInject.ref(), bean, beanName);
                 }
 
                 Produce produce = field.getAnnotation(Produce.class);
-                if (produce != null && 
postProcessor.matchContext(produce.context())) {
+                if (produce != null && 
getPostProcessor().matchContext(produce.context())) {
                     injectField(field, produce.uri(), produce.ref(), bean, 
beanName);
                 }
             }
@@ -255,12 +222,12 @@ public class CamelBeanPostProcessor impl
 
     protected void setterInjection(Method method, Object bean, String 
beanName) {
         EndpointInject endpointInject = 
method.getAnnotation(EndpointInject.class);
-        if (endpointInject != null && 
postProcessor.matchContext(endpointInject.context())) {
+        if (endpointInject != null && 
getPostProcessor().matchContext(endpointInject.context())) {
             setterInjection(method, bean, beanName, endpointInject.uri(), 
endpointInject.ref());
         }
 
         Produce produce = method.getAnnotation(Produce.class);
-        if (produce != null && postProcessor.matchContext(produce.context())) {
+        if (produce != null && 
getPostProcessor().matchContext(produce.context())) {
             setterInjection(method, bean, beanName, produce.uri(), 
produce.ref());
         }
     }
@@ -278,8 +245,57 @@ public class CamelBeanPostProcessor impl
         }
     }
 
+    protected CamelContext getOrLookupCamelContext() {
+        if (camelContext == null && applicationContext.containsBean(camelId)) {
+            camelContext = (CamelContext) applicationContext.getBean(camelId);
+        }
+        return camelContext;
+    }
+
     public CamelPostProcessorHelper getPostProcessor() {
-        ObjectHelper.notNull(postProcessor, "postProcessor");
+        // lets lazily create the post processor
+        if (postProcessor == null) {
+            postProcessor = new CamelPostProcessorHelper() {
+
+                @Override
+                public CamelContext getCamelContext() {
+                    // lets lazily lookup the camel context here
+                    // as doing this will cause this context to be started 
immediately
+                    // breaking the lifecycle ordering of different camel 
contexts
+                    // so we only want to do this on demand
+                    return getOrLookupCamelContext();
+                }
+
+                @Override
+                protected RuntimeException 
createProxyInstantiationRuntimeException(Class<?> type, Endpoint endpoint, 
Exception e) {
+                    return new BeanInstantiationException(type, "Could not 
instantiate proxy of type " + type.getName() + " on endpoint " + endpoint, e);
+                }
+
+                protected boolean isSingleton(Object bean, String beanName) {
+                    // no application context has been injected which means 
the bean
+                    // has not been enlisted in Spring application context
+                    if (applicationContext == null || beanName == null) {
+                        return super.isSingleton(bean, beanName);
+                    } else {
+                        return applicationContext.isSingleton(beanName);
+                    }
+                }
+
+                protected void startService(Service service, Object bean, 
String beanName) throws Exception {
+                    if (isSingleton(bean, beanName)) {
+                        getCamelContext().addService(service);
+                    } else {
+                        // only start service and do not add it to CamelContext
+                        ServiceHelper.startService(service);
+                        if (prototypeBeans.add(beanName)) {
+                            // do not spam the log with WARN so do this only 
once per bean name
+                            LOG.warn("The bean with id [" + beanName + "] is 
prototype scoped and cannot stop the injected service when bean is destroyed: "
+                                    + service + ". You may want to stop the 
service manually from the bean.");
+                        }
+                    }
+                }
+            };
+        }
         return postProcessor;
     }
 


Reply via email to