Author: jstrachan
Date: Wed Sep  5 14:42:52 2012
New Revision: 1381202

URL: http://svn.apache.org/viewvc?rev=1381202&view=rev
Log:
improved CAMEL-5566 so we can use @CamelStartup on @Produces methods too; for 
example when reusing a RouteBuilder class multiple times with different 
configurations/injections

Added:
    
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java
   (with props)
    
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java
   (with props)
    
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java
   (with props)
Modified:
    
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextBean.java
    
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java
    
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/Constants.java
    
camel/trunk/tests/camel-itest-cdi/src/test/java/org/apache/camel/itest/cdi/IntegrationTest.java

Modified: 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextBean.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextBean.java?rev=1381202&r1=1381201&r2=1381202&view=diff
==============================================================================
--- 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextBean.java
 (original)
+++ 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextBean.java
 Wed Sep  5 14:42:52 2012
@@ -47,19 +47,19 @@ public class CamelContextBean implements
     private final BeanManager beanManager;
     private final String name;
     private final String camelContextName;
-    private final List<Bean<?>> routeBuilderBeans;
     private final InjectionTarget<CdiCamelContext> target;
+    private final CamelContextConfig config;
 
     public CamelContextBean(BeanManager beanManager) {
-        this(beanManager, "CamelContext", "", Collections.EMPTY_LIST);
+        this(beanManager, "CamelContext", "", new CamelContextConfig());
     }
 
     public CamelContextBean(BeanManager beanManager, String name, String 
camelContextName,
-                            List<Bean<?>> routeBuilderBeans) {
+                            CamelContextConfig config) {
         this.beanManager = beanManager;
         this.name = name;
         this.camelContextName = camelContextName;
-        this.routeBuilderBeans = routeBuilderBeans;
+        this.config = config;
         this.target = 
beanManager.createInjectionTarget(beanManager.createAnnotatedType(CdiCamelContext.class));
     }
 
@@ -131,14 +131,6 @@ public class CamelContextBean implements
     }
 
     public void configureCamelContext(CdiCamelContext camelContext) {
-        for (Bean<?> bean : routeBuilderBeans) {
-            CreationalContext<?> creationalContext = 
beanManager.createCreationalContext(bean);
-            RouteBuilder routeBuilder = 
(RouteBuilder)beanManager.getReference(bean, RouteBuilder.class, 
creationalContext);
-            try {
-                camelContext.addRoutes(routeBuilder);
-            } catch (Exception e) {
-                throw new RuntimeCamelException("Could not add route builder " 
+ routeBuilder + ". Reason: " + e, e);
-            }
-        }
+        config.configure(camelContext, beanManager);
     }
 }

Added: 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java?rev=1381202&view=auto
==============================================================================
--- 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java
 (added)
+++ 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java
 Wed Sep  5 14:42:52 2012
@@ -0,0 +1,53 @@
+/**
+ *
+ * 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.cdi.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Producer;
+
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cdi.CdiCamelContext;
+
+/**
+ * Configuration options to be applied to a {@link CamelContext} by a {@link 
CamelContextBean}
+ */
+public class CamelContextConfig {
+    private final List<Bean<?>> routeBuilderBeans = new ArrayList<Bean<?>>();
+
+    public void addRouteBuilderBean(Bean<?> bean) {
+        routeBuilderBeans.add(bean);
+    }
+
+    public void configure(CdiCamelContext camelContext, BeanManager 
beanManager) {
+        for (Bean<?> bean : routeBuilderBeans) {
+            CreationalContext<?> createContext = 
beanManager.createCreationalContext(bean);
+            RouteBuilder routeBuilder = 
(RouteBuilder)beanManager.getReference(bean, RouteBuilder.class, createContext);
+            try {
+                camelContext.addRoutes(routeBuilder);
+            } catch (Exception e) {
+                throw new RuntimeCamelException("Could not add route builder " 
+ routeBuilder + ". Reason: " + e, e);
+            }
+        }
+    }
+}

Propchange: 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java?rev=1381202&r1=1381201&r2=1381202&view=diff
==============================================================================
--- 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java
 (original)
+++ 
camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java
 Wed Sep  5 14:42:52 2012
@@ -28,6 +28,7 @@ import javax.enterprise.context.spi.Crea
 import javax.enterprise.event.Observes;
 import javax.enterprise.inject.spi.AfterBeanDiscovery;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
@@ -36,6 +37,7 @@ import javax.enterprise.inject.spi.Injec
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
 import javax.enterprise.inject.spi.ProcessBean;
 import javax.enterprise.inject.spi.ProcessInjectionTarget;
+import javax.enterprise.inject.spi.ProcessProducerMethod;
 import javax.inject.Inject;
 
 import org.apache.camel.CamelContext;
@@ -60,7 +62,7 @@ public class CamelExtension implements E
     CamelContextMap camelContextMap;
 
     private Set<Bean<?>> eagerBeans = new HashSet<Bean<?>>();
-    private Map<String, List<Bean<?>>> namedCamelContexts = new 
HashMap<String, List<Bean<?>>>();
+    private Map<String, CamelContextConfig> camelContextConfigMap = new 
HashMap<String, CamelContextConfig>();
     private List<CamelContextBean> camelContextBeans = new 
ArrayList<CamelContextBean>();
 
     public CamelExtension() {
@@ -83,7 +85,7 @@ public class CamelExtension implements E
      * @throws Exception In case of exceptions.
      */
     protected void contextAwareness(@Observes 
ProcessAnnotatedType<CamelContextAware> process)
-        throws Exception {
+            throws Exception {
         AnnotatedType<CamelContextAware> annotatedType = 
process.getAnnotatedType();
         Class<CamelContextAware> javaClass = annotatedType.getJavaClass();
         if (CamelContextAware.class.isAssignableFrom(javaClass)) {
@@ -113,14 +115,15 @@ public class CamelExtension implements E
      */
     protected void registerManagedCamelContext(@Observes AfterBeanDiscovery 
abd, BeanManager manager) {
         // lets ensure we have at least one camel context
-        if (namedCamelContexts.isEmpty()) {
+        if (camelContextConfigMap.isEmpty()) {
             abd.addBean(new CamelContextBean(manager));
         } else {
-            Set<Map.Entry<String, List<Bean<?>>>> entries = 
namedCamelContexts.entrySet();
-            for (Map.Entry<String, List<Bean<?>>> entry : entries) {
+            Set<Map.Entry<String, CamelContextConfig>> entries = 
camelContextConfigMap.entrySet();
+            for (Map.Entry<String, CamelContextConfig> entry : entries) {
                 String name = entry.getKey();
-                List<Bean<?>> beans = entry.getValue();
-                CamelContextBean camelContextBean = new 
CamelContextBean(manager, "CamelContext:" + name, name, beans);
+                CamelContextConfig config = entry.getValue();
+                CamelContextBean camelContextBean = new 
CamelContextBean(manager, "CamelContext:" + name,
+                        name, config);
                 camelContextBeans.add(camelContextBean);
                 abd.addBean(camelContextBean);
             }
@@ -144,31 +147,57 @@ public class CamelExtension implements E
                 }
             }
         });
+    }
 
-        // detect all RouteBuilder instances
+    /**
+     * Lets detect all beans annotated of type {@link RouteBuilder}
+     * which are annotated with {@link org.apache.camel.cdi.CamelStartup}
+     * so they can be auto-registered
+     */
+    public void detectRouteBuilderBeans(@Observes ProcessBean<?> event) {
+        final Bean<?> bean = event.getBean();
+        Class<?> beanClass = bean.getBeanClass();
         if (RouteBuilder.class.isAssignableFrom(beanClass)) {
-            CamelStartup annotation = 
beanClass.getAnnotation(CamelStartup.class);
-            if (annotation != null) {
-                String contextName = annotation.contextName();
-                List<Bean<?>> beans = namedCamelContexts.get(contextName);
-                if (beans == null) {
-                    beans = new ArrayList<Bean<?>>();
-                    namedCamelContexts.put(contextName, beans);
-                }
-                beans.add(bean);
+            addRouteBuilderBean(bean, 
beanClass.getAnnotation(CamelStartup.class));
+        }
+    }
+
+    private void addRouteBuilderBean(Bean<?> bean, CamelStartup annotation) {
+        if (annotation != null) {
+            String contextName = annotation.contextName();
+            CamelContextConfig config = camelContextConfigMap.get(contextName);
+            if (config == null) {
+                config = new CamelContextConfig();
+                camelContextConfigMap.put(contextName, config);
             }
+            config.addRouteBuilderBean(bean);
+        }
+    }
+
+    /**
+     * Lets detect all producer methods createing instances of {@link 
RouteBuilder} which are annotated with {@link org.apache.camel.cdi.CamelStartup}
+     * so they can be auto-registered
+     */
+    public void detectProducerRoutes(@Observes ProcessProducerMethod<?, ?> 
event) {
+        Annotated annotated = event.getAnnotated();
+        CamelStartup annotation = annotated.getAnnotation(CamelStartup.class);
+        Class<?> returnType = 
event.getAnnotatedProducerMethod().getJavaMember().getReturnType();
+        if (RouteBuilder.class.isAssignableFrom(returnType)) {
+            addRouteBuilderBean(event.getBean(), annotation);
         }
     }
 
     /**
      * Lets force the CDI container to create all beans annotated with 
@Consume so that the consumer becomes active
      */
-    public void startConsumeBeans(@Observes AfterDeploymentValidation event, 
BeanManager beanManager) throws Exception {
+    public void startConsumeBeans(@Observes AfterDeploymentValidation event, 
BeanManager beanManager)
+            throws Exception {
         for (CamelContextBean bean : camelContextBeans) {
             String name = bean.getCamelContextName();
             CamelContext context = getCamelContext(name);
             if (context == null) {
-                throw new IllegalStateException("CamelContext '" + name + "' 
has not been injected into the CamelContextMap");
+                throw new IllegalStateException(
+                        "CamelContext '" + name + "' has not been injected 
into the CamelContextMap");
             }
             bean.configureCamelContext((CdiCamelContext)context);
         }
@@ -210,7 +239,7 @@ public class CamelExtension implements E
 
     /**
      * Perform injection on an existing bean such as a test case which is 
created directly by a testing framework.
-     *
+     * <p/>
      * This is because BeanProvider.injectFields() does not invoke the 
onInjectionTarget() method so the injection
      * of @Produce / @EndpointInject and processing of the @Consume 
annotations are not performed.
      */

Modified: 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/Constants.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/Constants.java?rev=1381202&r1=1381201&r2=1381202&view=diff
==============================================================================
--- 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/Constants.java
 (original)
+++ 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/Constants.java
 Wed Sep  5 14:42:52 2012
@@ -22,4 +22,7 @@ public class Constants {
     public static Object[] EXPECTED_BODIES_B = {"messageB1", "messageB2"};
     public static Object[] EXPECTED_BODIES_C = {"messageC1", "messageC2"};
     public static Object[] EXPECTED_BODIES_D = {"messageD1", "messageD2"};
+
+    public static Object[] EXPECTED_BODIES_Ea = {"messageEa1", "messageEa2"};
+    public static Object[] EXPECTED_BODIES_Ec = {"messageEc1", "messageEc2"};
 }

Added: 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java?rev=1381202&view=auto
==============================================================================
--- 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java
 (added)
+++ 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java
 Wed Sep  5 14:42:52 2012
@@ -0,0 +1,41 @@
+/**
+ *
+ * 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.itest.cdi;
+
+import javax.enterprise.inject.Produces;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.cdi.CamelStartup;
+
+/**
+ * Instantiate a number of route builders using
+ */
+public class MyConfig {
+
+    @Produces
+    @CamelStartup(contextName = "contextE")
+    public RouteBuilder createRouteA() {
+        return new MyRouteBuilder("seda:E.a", "mock:E.b");
+    }
+
+    @Produces
+    @CamelStartup(contextName = "contextE")
+    public RouteBuilder createRouteB() {
+        return new MyRouteBuilder("seda:E.c", "mock:E.d");
+    }
+}

Propchange: 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java?rev=1381202&view=auto
==============================================================================
--- 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java
 (added)
+++ 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java
 Wed Sep  5 14:42:52 2012
@@ -0,0 +1,44 @@
+/**
+ *
+ * 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.itest.cdi;
+
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * An example configurable {@link RouteBuilder}
+ */
+public class MyRouteBuilder extends RouteBuilder {
+    private final String a;
+    private final String b;
+
+    public MyRouteBuilder(String a, String b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    @Override
+    public String toString() {
+        return "MyRouteBuilder(" + a + " -> " + b + ")";
+
+    }
+
+    @Override
+    public void configure() throws Exception {
+        from(a).to(b);
+    }
+}

Propchange: 
camel/trunk/tests/camel-itest-cdi/src/main/java/org/apache/camel/itest/cdi/MyRouteBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
camel/trunk/tests/camel-itest-cdi/src/test/java/org/apache/camel/itest/cdi/IntegrationTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-cdi/src/test/java/org/apache/camel/itest/cdi/IntegrationTest.java?rev=1381202&r1=1381201&r2=1381202&view=diff
==============================================================================
--- 
camel/trunk/tests/camel-itest-cdi/src/test/java/org/apache/camel/itest/cdi/IntegrationTest.java
 (original)
+++ 
camel/trunk/tests/camel-itest-cdi/src/test/java/org/apache/camel/itest/cdi/IntegrationTest.java
 Wed Sep  5 14:42:52 2012
@@ -22,9 +22,12 @@ import javax.inject.Inject;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.cdi.Uri;
 import org.apache.camel.component.cdi.internal.CamelContextMap;
 import org.apache.camel.component.cdi.internal.CamelExtension;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.util.CamelContextHelper;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
@@ -53,6 +56,9 @@ public class IntegrationTest {
     @Inject
     RoutesContextD routesD;
 
+    @Inject @Uri(value="seda:foo", context = "contextE")
+    ProducerTemplate producerE;
+
     @Test
     public void checkContextsHaveCorrectEndpointsAndRoutes() throws Exception {
         Set<Map.Entry<String,CamelContext>> entries = 
camelContextMap.getCamelContextMap().entrySet();
@@ -77,6 +83,7 @@ public class IntegrationTest {
         routesB.sendMessages();
         mockEndpointB.assertIsSatisfied();
 
+        // lets check the routes where we default the context from the 
@CamelStartup
         CamelContext contextC = assertCamelContext("contextC");
         assertHasEndpoints(contextC, "seda://C.a", "mock://C.b");
 
@@ -92,6 +99,30 @@ public class IntegrationTest {
         mockEndpointD.expectedBodiesReceived(Constants.EXPECTED_BODIES_D);
         routesD.sendMessages();
         mockEndpointD.assertIsSatisfied();
+
+        // lets check the 2 routes created using @CamelStartup on a @Produces 
method
+        CamelContext contextE = assertCamelContext("contextE");
+        assertHasEndpoints(contextE, "seda://E.a", "mock://E.b", "seda://E.c", 
"mock://E.d");
+
+        MockEndpoint mockEb = CamelContextHelper
+                .getMandatoryEndpoint(contextE, "mock://E.b", 
MockEndpoint.class);
+        MockEndpoint mockEd = CamelContextHelper
+                .getMandatoryEndpoint(contextE, "mock://E.d", 
MockEndpoint.class);
+
+
+        mockEb.expectedBodiesReceived(Constants.EXPECTED_BODIES_Ea);
+        mockEd.expectedBodiesReceived(Constants.EXPECTED_BODIES_Ec);
+
+        for (Object body : Constants.EXPECTED_BODIES_Ea) {
+            producerE.sendBody("seda:E.a", body);
+        }
+
+        for (Object body : Constants.EXPECTED_BODIES_Ec) {
+            producerE.sendBody("seda:E.c", body);
+        }
+
+        mockEb.assertIsSatisfied();
+        mockEd.assertIsSatisfied();
     }
 
     public static void assertHasEndpoints(CamelContext context, String... 
uris) {


Reply via email to