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) {