Author: gnodet Date: Mon Dec 6 20:29:22 2010 New Revision: 1042780 URL: http://svn.apache.org/viewvc?rev=1042780&view=rev Log: [CAMEL-3271] packageScan does not work with camel-blueprint
Added: camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/TestRouteBuilder.java camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-4.xml camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-5.xml Modified: camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java Modified: camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java?rev=1042780&r1=1042779&r2=1042780&view=diff ============================================================================== --- camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java (original) +++ camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java Mon Dec 6 20:29:22 2010 @@ -27,12 +27,14 @@ import javax.xml.bind.annotation.XmlElem import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; +import org.apache.aries.blueprint.ExtendedBlueprintContainer; import org.apache.camel.RoutesBuilder; import org.apache.camel.ShutdownRoute; import org.apache.camel.ShutdownRunningTask; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.core.osgi.OsgiCamelContextPublisher; import org.apache.camel.core.osgi.OsgiEventAdminNotifier; +import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader; import org.apache.camel.core.xml.AbstractCamelContextFactoryBean; import org.apache.camel.core.xml.CamelJMXAgentDefinition; import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition; @@ -197,6 +199,15 @@ public class CamelContextFactoryBean ext @Override protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception { + // add filter to class resolver which then will filter + getContext().getPackageScanClassResolver().addFilter(filter); + ClassLoader classLoader = new BundleDelegatingClassLoader(((ExtendedBlueprintContainer) blueprintContainer).getBundleContext().getBundle()); + PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, classLoader, + /*getBeanPostProcessor(),*/ getContext().getPackageScanClassResolver()); + finder.appendBuilders(builders); + + // and remove the filter + getContext().getPackageScanClassResolver().removeFilter(filter); } @Override Added: camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java?rev=1042780&view=auto ============================================================================== --- camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java (added) +++ camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java Mon Dec 6 20:29:22 2010 @@ -0,0 +1,122 @@ +/** + * 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.blueprint; + +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.spi.PackageScanClassResolver; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.blueprint.container.BlueprintContainer; +import org.osgi.service.blueprint.reflect.BeanMetadata; + +/** + * A helper class which will find all {...@link org.apache.camel.builder.RouteBuilder} instances on the classpath + * + * @version $Revision$ + */ +public class PackageScanRouteBuilderFinder { + private static final transient Log LOG = LogFactory.getLog(PackageScanRouteBuilderFinder.class); + private final BlueprintCamelContext camelContext; + private final String[] packages; + private final PackageScanClassResolver resolver; + private final BlueprintContainer blueprintContainer; +// private final BeanPostProcessor beanPostProcessor; + + public PackageScanRouteBuilderFinder(BlueprintCamelContext camelContext, String[] packages, ClassLoader classLoader, + /*BeanPostProcessor postProcessor,*/ PackageScanClassResolver resolver) { + this.camelContext = camelContext; + this.blueprintContainer = camelContext.getBlueprintContainer(); + this.packages = packages; +// this.beanPostProcessor = postProcessor; + this.resolver = resolver; + // add our provided loader as well + resolver.addClassLoader(classLoader); + } + + /** + * Appends all the {...@link org.apache.camel.builder.RouteBuilder} instances that can be found on the classpath + */ + public void appendBuilders(List<RoutesBuilder> list) throws IllegalAccessException, InstantiationException { + Set<Class<?>> classes = resolver.findImplementations(RoutesBuilder.class, packages); + for (Class aClass : classes) { + if (LOG.isTraceEnabled()) { + LOG.trace("Found RouteBuilder class: " + aClass); + } + + // certain beans should be ignored + if (shouldIgnoreBean(aClass)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Ignoring RouteBuilder class: " + aClass); + } + continue; + } + + if (!isValidClass(aClass)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Ignoring invalid RouteBuilder class: " + aClass); + } + continue; + } + + // type is valid so create and instantiate the builder + RoutesBuilder builder = instantiateBuilder(aClass); +// if (beanPostProcessor != null) { + // Inject the annotated resource +// beanPostProcessor.postProcessBeforeInitialization(builder, builder.toString()); +// } + if (LOG.isDebugEnabled()) { + LOG.debug("Adding instantiated RouteBuilder: " + builder); + } + list.add(builder); + } + } + + /** + * Lets ignore beans that are explicitly configured in the Spring XML files + */ + protected boolean shouldIgnoreBean(Class<?> type) { + for (BeanMetadata metadata : blueprintContainer.getMetadata( BeanMetadata.class )) { + if (BeanMetadata.SCOPE_SINGLETON.equals(metadata.getScope())) { + Object bean = blueprintContainer.getComponentInstance( metadata.getId() ); + if (type.isInstance( bean )) { + return true; + } + } + } + return false; + } + + /** + * Returns true if the object is non-abstract and supports a zero argument constructor + */ + protected boolean isValidClass(Class type) { + if (!Modifier.isAbstract(type.getModifiers()) && !type.isInterface()) { + return true; + } + return false; + } + + @SuppressWarnings("unchecked") + protected RoutesBuilder instantiateBuilder(Class type) throws IllegalAccessException, InstantiationException { + return (RoutesBuilder) camelContext.getInjector().newInstance(type); + } +} Modified: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java?rev=1042780&r1=1042779&r2=1042780&view=diff ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java (original) +++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/OSGiBlueprintTestSupport.java Mon Dec 6 20:29:22 2010 @@ -39,9 +39,7 @@ import static org.ops4j.pax.exam.CoreOpt import static org.ops4j.pax.exam.CoreOptions.felix; import static org.ops4j.pax.exam.CoreOptions.options; import static org.ops4j.pax.exam.CoreOptions.wrappedBundle; -import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.profile; -import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures; -import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.workingDirectory; +import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.*; import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.newBundle; import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.withBnd; @@ -98,6 +96,22 @@ public class OSGiBlueprintTestSupport ex getOsgiService(CamelContext.class, "(camel.context.symbolicname=CamelBlueprintTestBundle3)", 5000); } + @Test + public void testRouteWithPackage() throws Exception { + getInstalledBundle("CamelBlueprintTestBundle4").start(); + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle4)", 5000); + CamelContext ctx = getOsgiService(CamelContext.class, "(camel.context.symbolicname=CamelBlueprintTestBundle4)", 5000); + assertEquals(1, ctx.getRoutes().size()); + } + + @Test + public void testRouteWithPackageScan() throws Exception { + getInstalledBundle("CamelBlueprintTestBundle5").start(); + getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=CamelBlueprintTestBundle5)", 5000); + CamelContext ctx = getOsgiService(CamelContext.class, "(camel.context.symbolicname=CamelBlueprintTestBundle5)", 5000); + assertEquals(1, ctx.getRoutes().size()); + } + @Before public void setUp() throws Exception { } @@ -126,6 +140,18 @@ public class OSGiBlueprintTestSupport ex .set(Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle3") .build()).noStart(), + bundle(newBundle() + .add("OSGI-INF/blueprint/test.xml", OSGiBlueprintTestSupport.class.getResource("blueprint-4.xml")) + .add(TestRouteBuilder.class) + .set(Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle4") + .build(withBnd())).noStart(), + + bundle(newBundle() + .add("OSGI-INF/blueprint/test.xml", OSGiBlueprintTestSupport.class.getResource("blueprint-5.xml")) + .add(TestRouteBuilder.class) + .set(Constants.BUNDLE_SYMBOLICNAME, "CamelBlueprintTestBundle5") + .build(withBnd())).noStart(), + // install the spring dm profile profile("spring.dm").version("1.2.0"), // this is how you set the default log level when using pax logging (logProfile) @@ -144,6 +170,8 @@ public class OSGiBlueprintTestSupport ex workingDirectory("target/paxrunner/"), + //vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"), + //felix(), equinox()); Added: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/TestRouteBuilder.java URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/TestRouteBuilder.java?rev=1042780&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/TestRouteBuilder.java (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/TestRouteBuilder.java Mon Dec 6 20:29:22 2010 @@ -0,0 +1,30 @@ +/** + * 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.osgi.blueprint; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy; + +public class TestRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("seda:foo") + .aggregate(constant("messageId"), new UseLatestAggregationStrategy()).completionTimeout(1000L). + to("seda:aggregated"); + } +} Added: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-4.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-4.xml?rev=1042780&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-4.xml (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-4.xml Mon Dec 6 20:29:22 2010 @@ -0,0 +1,24 @@ +<?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. +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <camelContext xmlns="http://camel.apache.org/schema/blueprint"> + <package>org.apache.camel.itest.osgi.blueprint</package> + </camelContext> + +</blueprint> Added: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-5.xml URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-5.xml?rev=1042780&view=auto ============================================================================== --- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-5.xml (added) +++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-5.xml Mon Dec 6 20:29:22 2010 @@ -0,0 +1,26 @@ +<?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. +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <camelContext xmlns="http://camel.apache.org/schema/blueprint"> + <packageScan> + <package>org.apache.camel.itest.osgi.blueprint</package> + </packageScan> + </camelContext> + +</blueprint>