Author: jstrachan Date: Wed Sep 5 18:15:15 2012 New Revision: 1381278 URL: http://svn.apache.org/viewvc?rev=1381278&view=rev Log: initial implementation of CAMEL-5554 so we can easily reuse XML based route definitions from inside CDI
Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java (with props) camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java (with props) camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java (with props) camel/trunk/components/camel-cdi/src/test/resources/routes.xml (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Mock.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java 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/CamelContextConfig.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelExtension.java camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/EndpointDefinedUsingConfigPropertyTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java?rev=1381278&r1=1381277&r2=1381278&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java Wed Sep 5 18:15:15 2012 @@ -16,6 +16,7 @@ */ package org.apache.camel.model; +import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import javax.xml.bind.JAXBContext; @@ -43,9 +44,7 @@ public final class ModelHelper { * @throws JAXBException is throw if error marshalling to XML */ public static String dumpModelAsXml(NamedNode definition) throws JAXBException { - // create a new jaxb context - // must use classloader from CamelContext to have JAXB working - JAXBContext jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader()); + JAXBContext jaxbContext = createJaxbContext(); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); @@ -64,10 +63,7 @@ public final class ModelHelper { * @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model */ public static <T extends NamedNode> T createModelFromXml(String xml, Class<T> type) throws JAXBException { - // create a new jaxb context - // must use classloader from CamelContext to have JAXB working - JAXBContext jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader()); - + JAXBContext jaxbContext = createJaxbContext(); StringReader reader = new StringReader(xml); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Object result = unmarshaller.unmarshal(reader); @@ -76,7 +72,26 @@ public final class ModelHelper { if (result == null) { throw new JAXBException("Cannot unmarshal to " + type + " using JAXB from XML: " + xml); } + return type.cast(result); + } + /** + * Marshal the xml to the model definition + * + * @param stream the xml stream + * @param type the definition type to return, will throw a {@link ClassCastException} if not the expected type + * @return the model definition + * @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model + */ + public static <T extends NamedNode> T createModelFromXml(InputStream stream, Class<T> type) throws JAXBException { + JAXBContext jaxbContext = createJaxbContext(); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + Object result = unmarshaller.unmarshal(stream); return type.cast(result); } + + public static JAXBContext createJaxbContext() throws JAXBException { + // must use classloader from CamelContext to have JAXB working + return JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader()); + } } Modified: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Mock.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Mock.java?rev=1381278&r1=1381277&r2=1381278&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Mock.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/Mock.java Wed Sep 5 18:15:15 2012 @@ -15,11 +15,11 @@ * limitations under the License. */ package org.apache.camel.cdi; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - import javax.enterprise.util.Nonbinding; import javax.inject.Qualifier; Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java?rev=1381278&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java (added) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java Wed Sep 5 18:15:15 2012 @@ -0,0 +1,84 @@ +/** + * + * 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.cdi; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import javax.xml.bind.JAXBException; + +import org.apache.camel.model.ModelHelper; +import org.apache.camel.model.RoutesDefinition; +import org.apache.camel.util.ObjectHelper; + +/** + * A helper class for loading route definitions from a file, URL or the classpath + */ +public class RoutesXml { + + /** + * Loads the routes from the given XML content + */ + public static RoutesDefinition loadRoutesFromXML(String xml) throws JAXBException { + return ModelHelper.createModelFromXml(xml, RoutesDefinition.class); + } + + /** + * Loads the routes from the classpath + */ + public static RoutesDefinition loadRoutesFromClasspath(String uri) throws JAXBException { + InputStream stream = ObjectHelper.loadResourceAsStream(uri); + ObjectHelper.notNull(stream, "Could not find resource '" + uri + "' on the ClassLoader"); + return ModelHelper.createModelFromXml(stream, RoutesDefinition.class); + } + + /** + * Loads the routes from a {@link URL} + */ + public static RoutesDefinition loadRoutesFromURL(URL url) throws JAXBException, IOException { + ObjectHelper.notNull(url, "url"); + return ModelHelper.createModelFromXml(url.openStream(), RoutesDefinition.class); + } + + /** + * Loads the routes from a {@link URL} + */ + public static RoutesDefinition loadRoutesFromURL(String url) throws IOException, JAXBException { + return loadRoutesFromURL(new URL(url)); + } + + /** + * Loads the routes from a {@link File} + */ + public static RoutesDefinition loadRoutesFromFile(File file) throws JAXBException, FileNotFoundException { + ObjectHelper.notNull(file, "file"); + return ModelHelper.createModelFromXml(new FileInputStream(file), RoutesDefinition.class); + } + + /** + * Loads the routes from a {@link File} + */ + public static RoutesDefinition loadRoutesFromFile(String fileName) + throws JAXBException, FileNotFoundException { + return loadRoutesFromFile(new File(fileName)); + } + +} Propchange: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/cdi/RoutesXml.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java?rev=1381278&r1=1381277&r2=1381278&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java Wed Sep 5 18:15:15 2012 @@ -19,7 +19,6 @@ package org.apache.camel.component.cdi; import java.util.HashMap; import java.util.Map; import java.util.Set; - import javax.enterprise.inject.spi.Bean; import org.apache.camel.spi.Registry; 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=1381278&r1=1381277&r2=1381278&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 18:15:15 2012 @@ -19,9 +19,7 @@ package org.apache.camel.component.cdi.i import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; @@ -31,8 +29,6 @@ import javax.enterprise.inject.spi.Injec import javax.enterprise.inject.spi.InjectionTarget; import org.apache.camel.CamelContext; -import org.apache.camel.RuntimeCamelException; -import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.cdi.CdiCamelContext; import org.apache.camel.util.ObjectHelper; import org.apache.deltaspike.core.api.literal.AnyLiteral; Modified: 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=1381278&r1=1381277&r2=1381278&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/internal/CamelContextConfig.java Wed Sep 5 18:15:15 2012 @@ -19,18 +19,18 @@ package org.apache.camel.component.cdi.i 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.RoutesBuilder; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.cdi.CdiCamelContext; +import org.apache.camel.model.RouteContainer; +import org.apache.camel.util.ObjectHelper; /** - * Configuration options to be applied to a {@link CamelContext} by a {@link CamelContextBean} + * Configuration options to be applied to a {@link org.apache.camel.CamelContext} by a {@link CamelContextBean} */ public class CamelContextConfig { private final List<Bean<?>> routeBuilderBeans = new ArrayList<Bean<?>>(); @@ -42,11 +42,25 @@ public class CamelContextConfig { 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); + Class<?> beanClass = bean.getBeanClass(); + Object reference = beanManager.getReference(bean, beanClass, createContext); + ObjectHelper.notNull(reference, "Could not instantiate bean of type " + beanClass.getName() + " for " + bean); try { - camelContext.addRoutes(routeBuilder); + if (reference instanceof RoutesBuilder) { + RoutesBuilder routeBuilder = (RoutesBuilder)reference; + camelContext.addRoutes(routeBuilder); + } else if (reference instanceof RouteContainer) { + RouteContainer routeContainer = (RouteContainer)reference; + camelContext.addRouteDefinitions(routeContainer.getRoutes()); + } else { + throw new IllegalArgumentException("Invalid route builder " + reference + + " of type " + beanClass.getName() + + ". Should be RoutesBuilder or RoutesContainer"); + } } catch (Exception e) { - throw new RuntimeCamelException("Could not add route builder " + routeBuilder + ". Reason: " + e, e); + throw new RuntimeCamelException( + "Could not add " + reference + " to CamelContext: " + camelContext + ". Reason: " + e, + e); } } } 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=1381278&r1=1381277&r2=1381278&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 18:15:15 2012 @@ -45,10 +45,12 @@ import org.apache.camel.CamelContextAwar import org.apache.camel.Consume; import org.apache.camel.EndpointInject; import org.apache.camel.Produce; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.cdi.ContextName; import org.apache.camel.component.cdi.CdiCamelContext; import org.apache.camel.impl.DefaultCamelBeanPostProcessor; +import org.apache.camel.model.RouteContainer; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.ReflectionHelper; import org.apache.deltaspike.core.api.provider.BeanProvider; @@ -158,7 +160,7 @@ public class CamelExtension implements E public void detectRouteBuilderBeans(@Observes ProcessBean<?> event) { final Bean<?> bean = event.getBean(); Class<?> beanClass = bean.getBeanClass(); - if (RouteBuilder.class.isAssignableFrom(beanClass)) { + if (isRoutesBean(beanClass)) { addRouteBuilderBean(bean, beanClass.getAnnotation(ContextName.class)); } } @@ -183,7 +185,7 @@ public class CamelExtension implements E Annotated annotated = event.getAnnotated(); ContextName annotation = annotated.getAnnotation(ContextName.class); Class<?> returnType = event.getAnnotatedProducerMethod().getJavaMember().getReturnType(); - if (RouteBuilder.class.isAssignableFrom(returnType)) { + if (isRoutesBean(returnType)) { addRouteBuilderBean(event.getBean(), annotation); } } @@ -314,4 +316,7 @@ public class CamelExtension implements E return field.getAnnotation(Inject.class) != null; } + protected boolean isRoutesBean(Class<?> returnType) { + return RoutesBuilder.class.isAssignableFrom(returnType) || RouteContainer.class.isAssignableFrom(returnType); + } } Modified: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/EndpointDefinedUsingConfigPropertyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/EndpointDefinedUsingConfigPropertyTest.java?rev=1381278&r1=1381277&r2=1381278&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/EndpointDefinedUsingConfigPropertyTest.java (original) +++ camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/EndpointDefinedUsingConfigPropertyTest.java Wed Sep 5 18:15:15 2012 @@ -18,7 +18,6 @@ package org.apache.camel.cdi; import java.util.ArrayList; import java.util.List; - import javax.inject.Inject; import org.apache.camel.EndpointInject; Added: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java?rev=1381278&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java (added) +++ camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java Wed Sep 5 18:15:15 2012 @@ -0,0 +1,61 @@ +/** + * + * 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.cdi; + +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.model.RoutesDefinition; +import org.junit.Test; + +/** + * Checks we can load XML routes from the classpath and use then with CDI + */ +public class XmlRoutesFromClassPathTest extends CdiTestSupport { + @Produces + @ContextName + public RoutesDefinition createRoutes() throws Exception { + return RoutesXml.loadRoutesFromClasspath("routes.xml"); + } + + @Inject + @Mock + MockEndpoint results; + + @Inject + @Uri("direct:start") + ProducerTemplate producer; + + Object[] expectedBodies = { "body:1", "body:2" }; + + @Test + public void xmlRoutesWorkOnClassPath() throws Exception { + assertNotNull("results not injected", results); + assertNotNull("producer not injected", producer); + + results.expectedBodiesReceived(expectedBodies); + + for (Object body : expectedBodies) { + producer.sendBody(body); + } + + results.assertIsSatisfied(); + } +} Propchange: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromClassPathTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java?rev=1381278&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java (added) +++ camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java Wed Sep 5 18:15:15 2012 @@ -0,0 +1,43 @@ +/** + * + * 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.cdi; + +import java.io.File; +import java.net.URL; + +import org.apache.camel.model.RoutesDefinition; + +/** + * Tests loading of routes as XML from a URL + */ +public class XmlRoutesFromURLTest extends XmlRoutesFromClassPathTest { + + @Override + public RoutesDefinition createRoutes() throws Exception { + String[] prefixes = { "camel-cdi", "components"}; + String fileName = "src/test/resources/routes.xml"; + File file = new File(fileName); + for (String prefix : prefixes) { + if (file.exists()) break; + file = new File(prefix, file.getPath()); + } + assertTrue("The file " + file.getPath() + " does not exist", file.exists()); + URL url = file.toURI().toURL(); + return RoutesXml.loadRoutesFromURL(url); + } +} Propchange: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/XmlRoutesFromURLTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: camel/trunk/components/camel-cdi/src/test/resources/routes.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/test/resources/routes.xml?rev=1381278&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/test/resources/routes.xml (added) +++ camel/trunk/components/camel-cdi/src/test/resources/routes.xml Wed Sep 5 18:15:15 2012 @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<routes xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:start"/> + <to uri="mock:results"/> + </route> +</routes> + Propchange: camel/trunk/components/camel-cdi/src/test/resources/routes.xml ------------------------------------------------------------------------------ svn:eol-style = native