This is an automated email from the ASF dual-hosted git repository. ffang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new ba21445 [CAMEL-12026]ensure camel bundle with spring configuration works in OSGi with aries-blueprint-spring bridge ba21445 is described below commit ba21445a2548946871ddd3ee2007c4659dbed223 Author: Freeman Fang <freeman.f...@gmail.com> AuthorDate: Thu Nov 23 16:46:00 2017 +0800 [CAMEL-12026]ensure camel bundle with spring configuration works in OSGi with aries-blueprint-spring bridge --- components/camel-spring/pom.xml | 13 ++++ .../main/java/org/apache/camel/osgi/Activator.java | 45 +++++++++++++ .../apache/camel/osgi/CamelContextFactoryBean.java | 74 ++++++++++++++++++++++ .../apache/camel/osgi/OsgiSpringCamelContext.java | 64 +++++++++++++++++++ .../spring/handler/CamelNamespaceHandler.java | 15 +++-- .../karaf/features/src/main/resources/features.xml | 2 + 6 files changed, 206 insertions(+), 7 deletions(-) diff --git a/components/camel-spring/pom.xml b/components/camel-spring/pom.xml index cbcb8cb..544ea93 100644 --- a/components/camel-spring/pom.xml +++ b/components/camel-spring/pom.xml @@ -65,12 +65,25 @@ org.apache.camel.spi.ComponentResolver;component=spring-event, org.apache.camel.spi.LanguageResolver;language=spel </camel.osgi.export.service> + <camel.osgi.activator> + org.apache.camel.osgi.Activator + </camel.osgi.activator> <!-- do not skip any tests by default --> <platform.skip.tests/> </properties> <dependencies> <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core-osgi</artifactId> + </dependency> + <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> </dependency> diff --git a/components/camel-spring/src/main/java/org/apache/camel/osgi/Activator.java b/components/camel-spring/src/main/java/org/apache/camel/osgi/Activator.java new file mode 100644 index 0000000..c8b6aaa --- /dev/null +++ b/components/camel-spring/src/main/java/org/apache/camel/osgi/Activator.java @@ -0,0 +1,45 @@ +/** + * 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.osgi; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + private static Bundle bundle; + + public static Bundle getBundle() { + return bundle; + } + + public static BundleContext getBundleContext() { + return context; + } + + public void start(BundleContext context) throws Exception { + Activator.context = context; + Activator.bundle = context.getBundle(); + } + + public void stop(BundleContext context) throws Exception { + Activator.context = null; + Activator.bundle = null; + } +} diff --git a/components/camel-spring/src/main/java/org/apache/camel/osgi/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/osgi/CamelContextFactoryBean.java new file mode 100644 index 0000000..d28b587 --- /dev/null +++ b/components/camel-spring/src/main/java/org/apache/camel/osgi/CamelContextFactoryBean.java @@ -0,0 +1,74 @@ +/** + * 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.osgi; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + +import org.apache.camel.core.osgi.OsgiCamelContextPublisher; +import org.apache.camel.core.osgi.OsgiEventAdminNotifier; +import org.apache.camel.spring.SpringCamelContext; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@XmlRootElement(name = "camelContext") +@XmlAccessorType(XmlAccessType.FIELD) +public class CamelContextFactoryBean extends org.apache.camel.spring.CamelContextFactoryBean { + private static final Logger LOG = LoggerFactory.getLogger(CamelContextFactoryBean.class); + + @XmlTransient + private BundleContext bundleContext; + + + public BundleContext getBundleContext() { + return bundleContext; + } + + public void setBundleContext(BundleContext bundleContext) { + LOG.debug("Using BundleContext: {}", bundleContext); + this.bundleContext = bundleContext; + } + + protected SpringCamelContext createContext() { + SpringCamelContext ctx = newCamelContext(); + // only set the name if its explicit (Camel will auto assign name if none explicit set) + if (!isImplicitId()) { + ctx.setName(getId()); + } + return ctx; + } + + protected SpringCamelContext newCamelContext() { + return new OsgiSpringCamelContext(getApplicationContext(), getBundleContext()); + } + + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + getContext().getManagementStrategy().addEventNotifier(new OsgiCamelContextPublisher(bundleContext)); + try { + getClass().getClassLoader().loadClass("org.osgi.service.event.EventAdmin"); + getContext().getManagementStrategy().addEventNotifier(new OsgiEventAdminNotifier(bundleContext)); + } catch (Throwable t) { + // Ignore, if the EventAdmin package is not available, just don't use it + LOG.debug("EventAdmin package is not available, just don't use it"); + } + } +} diff --git a/components/camel-spring/src/main/java/org/apache/camel/osgi/OsgiSpringCamelContext.java b/components/camel-spring/src/main/java/org/apache/camel/osgi/OsgiSpringCamelContext.java new file mode 100644 index 0000000..52449bf --- /dev/null +++ b/components/camel-spring/src/main/java/org/apache/camel/osgi/OsgiSpringCamelContext.java @@ -0,0 +1,64 @@ +/** + * 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.osgi; + +import org.apache.camel.TypeConverter; +import org.apache.camel.core.osgi.OsgiCamelContextHelper; +import org.apache.camel.core.osgi.OsgiFactoryFinderResolver; +import org.apache.camel.core.osgi.OsgiTypeConverter; +import org.apache.camel.core.osgi.utils.BundleContextUtils; +import org.apache.camel.spi.FactoryFinder; +import org.apache.camel.spi.Registry; +import org.apache.camel.spring.SpringCamelContext; +import org.osgi.framework.BundleContext; +import org.springframework.context.ApplicationContext; + +public class OsgiSpringCamelContext extends SpringCamelContext { + + private final BundleContext bundleContext; + + public OsgiSpringCamelContext(ApplicationContext applicationContext, BundleContext bundleContext) { + super(applicationContext); + this.bundleContext = bundleContext; + OsgiCamelContextHelper.osgiUpdate(this, bundleContext); + } + + @Override + protected TypeConverter createTypeConverter() { + // CAMEL-3614: make sure we use a bundle context which imports org.apache.camel.impl.converter package + BundleContext ctx = BundleContextUtils.getBundleContext(getClass()); + if (ctx == null) { + ctx = bundleContext; + } + FactoryFinder finder = new OsgiFactoryFinderResolver(bundleContext).resolveDefaultFactoryFinder(getClassResolver()); + return new OsgiTypeConverter(ctx, this, getInjector(), finder); + } + + @Override + protected Registry createRegistry() { + return OsgiCamelContextHelper.wrapRegistry(this, super.createRegistry(), bundleContext); + } + + @Override + public void setName(String name) { + super.setName(name); + // in OSGi prefix the bundle id to the management name so it will be unique in the JVM + // and also nicely sorted based on bundle id + super.setManagementName(bundleContext.getBundle().getBundleId() + "-" + name); + } + +} diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java index 9ecdf6c..2ab865d 100644 --- a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java +++ b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java @@ -81,7 +81,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport { private JAXBContext jaxbContext; private Map<String, BeanDefinition> autoRegisterMap = new HashMap<String, BeanDefinition>(); - + private boolean osgi = false; /** * Prepares the nodes before parsing. */ @@ -154,7 +154,6 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport { parserMap.put("errorHandler", errorHandlerParser); // camel context - boolean osgi = false; Class<?> cl = CamelContextFactoryBean.class; // These code will try to detected if we are in the OSGi environment. // If so, camel will use the OSGi version of CamelContextFactoryBean to create the CamelContext. @@ -680,14 +679,16 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport { LOG.debug("Registered default: {} with id: {} on camel context: {}", new Object[]{definition.getBeanClassName(), id, contextId}); } } else { - // ups we have already registered it before with same id, but on another camel context - // this is not good so we need to remove all traces of this auto registering. - // end user must manually add the needed XML elements and provide unique ids access all camel context himself. - LOG.debug("Unregistered default: {} with id: {} as we have multiple camel contexts and they must use unique ids." + if (!osgi) { + // ups we have already registered it before with same id, but on another camel context + // this is not good so we need to remove all traces of this auto registering. + // end user must manually add the needed XML elements and provide unique ids access all camel context himself. + LOG.debug("Unregistered default: {} with id: {} as we have multiple camel contexts and they must use unique ids." + " You must define the definition in the XML file manually to avoid id clashes when using multiple camel contexts", definition.getBeanClassName(), id); - parserContext.getRegistry().removeBeanDefinition(id); + parserContext.getRegistry().removeBeanDefinition(id); + } } } diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml index 696a941..9934fa7 100644 --- a/platforms/karaf/features/src/main/resources/features.xml +++ b/platforms/karaf/features/src/main/resources/features.xml @@ -62,6 +62,8 @@ <feature version='${spring-version-range}'>spring</feature> <feature version='${spring-version-range}'>spring-tx</feature> <feature version='${project.version}'>camel-core</feature> + <feature>eventadmin</feature> + <bundle dependency='true'>mvn:org.apache.camel/camel-core-osgi/${project.version}</bundle> <bundle>mvn:org.apache.camel/camel-spring/${project.version}</bundle> </feature> <feature name='camel-scr' version='${project.version}' resolver='(obr)' start-level='50'> -- To stop receiving notification emails like this one, please contact ['"commits@camel.apache.org" <commits@camel.apache.org>'].