All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.jonas.camel.component.RouteBuilderComponent Maven / Gradle / Ivy

There is a newer version: 1.7.0
Show newest version
/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: [email protected]
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: RouteBuilderComponent.java 21309 2011-05-25 10:48:03Z ardaaydin $
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.camel.component;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jms.ConnectionFactory;
import javax.naming.InitialContext;
import javax.xml.namespace.QName;

import org.apache.camel.CamelContext;
import org.apache.camel.LoggingLevel;
import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.file.FileEndpoint;
import org.apache.camel.component.file.strategy.GenericFileProcessStrategyFactory;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.impl.CompositeRegistry;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.processor.interceptor.Tracer;
import org.apache.camel.spi.Registry;
import org.apache.cxf.tools.common.extensions.soap.SoapBinding;
import org.osgi.framework.BundleContext;
import org.ow2.carol.jndi.intercept.spi.InterceptorInitialContextFactory;
import org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory;
import org.ow2.jonas.camel.service.api.ICamelService;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
import org.springframework.jms.support.destination.JndiDestinationResolver;

/**
 * iPOJO component that creates a CAMEL context with:
 * 
    *
  • CAROL classes accessed, so that the BND tool automatically adds * CAROL-related classes to the bundle's Import-Package * declarations
  • *
  • All CAMEL XML registry files and XML registry property files read from * $JONAS_BASE/conf and injected into the CAMEL context
  • *
  • The local JNDI registry added to the CAMEL context's registry, to ease * lookups with the jdbc component for instance
  • *
  • The JMS component bound on the JNDI registry
  • *
  • The bundle's {@link ClassLoader} positioned on the current thread, to * avoid any class loading issues with dynamic components such as JNDI, JMS or * CXF
  • *
  • The CAMEL trace component logging into the logger named * {@link RouteBuilderComponent#TRACE_LOGGER_NAME}
  • *
  • If {@link RouteBuilderComponent#traceDestination} is not null, traces * also sending a message to that endpoint
  • *
* In order to use it: *
    *
  • Override the {@link RouteBuilderComponent#configure()} method, making * sure you first call super.configure() in your implementation
  • *
  • Make sure the org.ow2.jonas.camel.component package is in * your bundle's Private-Package list
  • *
  • Make sure the metadata.xml file has the required * definitions:
    <ipojo ...
     * ...
     *   <component ...
     * ...
     *     <requires optional="false"
     *               specification="org.ow2.jonas.camel.service.api.ICamelService">
     *       <callback type="bind" method="setCamelService" />
     *     </requires>
     * 
     *     <callback transition="validate" method="start" />
     *     <callback transition="invalidate" method="stop" />
     * ...
     *   </component>
     * ...
     * </ipojo>
  • *
*/ public abstract class RouteBuilderComponent extends RouteBuilder { private Log logger = LogFactory.getLog(this.getClass()); public static final String TRACE_LOGGER_NAME = "org.ow2.jonas.camel.traces"; /** * The OSGi bundle context. Obtained via constructor. */ protected BundleContext bundleContext = null; /** * The Camel service. Injected by the container. */ protected ICamelService camelService = null; /** * Replacements to do in the registry. */ protected Map registryReplacements = new HashMap(); /** * @see RouteBuilderComponent#getRegistryPropertyOrReplacement(String) */ private Map allRegistryPropertiesAndReplacements; /** * The Camel context name. */ protected String camelContextName = null; /** * The external trace destination, might be null. */ protected String traceDestination = null; /** * The JONAS_BASE/conf folder. */ private File conf; /** * Saves the bundle context and gets the JONAS_BASE/conf folder. */ public RouteBuilderComponent(final BundleContext bundleContext) { this.bundleContext = bundleContext; final String JONAS_BASE = System.getProperty("jonas.base"); if (JONAS_BASE == null) { throw new RuntimeException("JONAS_BASE not defined"); } this.conf = new File(JONAS_BASE, "conf").getAbsoluteFile(); // Access some CAROL classes loader so that the BND tool automatically // adds CAROL to this bundle's Import-Package list and therefore avoid // JNDI lookup errors MultiOrbInitialContextFactory.class.getClassLoader(); InterceptorInitialContextFactory.class.getClassLoader(); // Access GenericFileProcessStrategyFactory in order to avoid // java.lang.TypeNotPresentException GenericFileProcessStrategyFactory.class.getClassLoader(); // Access SoapBinding.class and QName.class to avoid bug CXF-3184 // FIXME: CXF-3184 is fixed in CXF 2.2.13, 2.3.2 and 2.4. Once the CXF // version in JOnAS is upgraded, remove these lines. SoapBinding.class.getClassLoader(); QName.class.getClassLoader(); } /** * Start the Camel context. */ public void start() throws Throwable { this.logger.debug("Starting route {0}", this.getRouteName()); final ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); try { // Use the actual class's class loader so that dynamic class // creations (JNDI, CXF, etc.) don't fail Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); // Start a new Camel context for the application this.logger.debug("Starting CAMEL context for route {0}", this.getRouteName()); /* * If camelContextName is not overriden by a child class * or there is no already existing Camel context with overriden camelContextName * then create new Camel context */ if(null==this.camelContextName || !this.camelService.getContextNames().contains(this.camelContextName)) { this.camelContextName = this.camelService.startNewContext(this.bundleContext); } this.logger.info("Starting CAMEL context name for route {0}", this.camelContextName); DefaultCamelContext camelContext = (DefaultCamelContext) this.camelService.getCamelContext(this.camelContextName); // Add registry entries this.logger.debug("Adding registry entries for route {0}", this.getRouteName()); RegistryInjector injector = new RegistryInjector(this.registryReplacements); this.configureCamelComponents(camelContext, injector.getRegistryFilesContent()); this.logger.debug("Injecting registry entries for route {0}", this.getRouteName()); injector.injectRegistry(this.camelService, this.camelContextName); this.allRegistryPropertiesAndReplacements = injector.getAllReplacements(); // Add the JNDI registry this.logger.debug("Adding the JNDI registry to route {0}", this.getRouteName()); Registry jndiRegistry = new JndiRegistry(new InitialContext()); CompositeRegistry compositeRegistry = new CompositeRegistry(); compositeRegistry.addRegistry(camelContext.getRegistry()); compositeRegistry.addRegistry(jndiRegistry); camelContext.setRegistry(compositeRegistry); // Add the routes in the camel context this.logger.debug("Starting CAMEL routes on {0}", this.getRouteName()); this.camelService.addRoutes(this, this.camelContextName); this.logger.info("Route {0} has started", this.getRouteName()); } catch (Throwable t) { this.logger.error("Cannot start route {0}", this.getRouteName(), t); throw t; } finally { Thread.currentThread().setContextClassLoader(oldCL); } } /** * Stop the Camel context. */ public void stop() throws Throwable { try { if (this.camelContextName != null) { this.camelService.stop(this.camelContextName); } this.logger.info("Route {0} has stopped", this.getRouteName()); } catch (Throwable t) { this.logger.error("Cannot stop route {0}", this.getRouteName(), t); throw t; } finally { this.camelContextName = null; this.camelService = null; System.gc(); } } /** * Configure CAMEL components, called just before registry injection.
*
* By default, the jms component is configured to use the * JCF connection factory on JNDI.
*
* You can override this method to configure other components, for example * jdbc. * * @param camelContext CAMEL context. * @param registryFilesContent Actual contents of the CAMEL registry files * (with all variables replaced). */ protected void configureCamelComponents(final CamelContext camelContext, final List registryFilesContent) throws Exception { // Add JNDI resolver to the JMS component JmsComponent jms = camelContext.getComponent("jms", JmsComponent.class); ConnectionFactory connectionFactory = (ConnectionFactory) new InitialContext().lookup("JCF"); jms.setConnectionFactory(connectionFactory); JndiDestinationResolver jndiDestinationResolver = new JndiDestinationResolver(); jndiDestinationResolver.setCache(true); jms.setDestinationResolver(jndiDestinationResolver); } /** * Configures the Camel context with the tracer. */ @Override public void configure() throws Exception { if (this.traceDestination != null) { // Tracer, that will by default log on the Java logger Tracer tracer = new Tracer(); tracer.setFormatter(new MessageFormatter()); tracer.setLogLevel(LoggingLevel.INFO); tracer.setLogName(RouteBuilderComponent.TRACE_LOGGER_NAME); tracer.setTraceExceptions(false); tracer.setDestinationUri("direct:traced"); this.from("direct:traced").process(new DefaultTraceEventMessageToStringProcessor()).process( new ProducerProcessorUsingBundleClassLoader(this.traceDestination)); this.getContext().addInterceptStrategy(tracer); } } /** * @param camelService Camel service to inject. */ public void setCamelService(final ICamelService camelService) { this.camelService = camelService; } /** * @return The JONAS_BASE/conf folder. */ public final File getConfigurationFolder() { return this.conf; } /** * Returns the value of a certain key in the contents of all * camel*.properties files in JONAS_BASE/conf * merged with {@link RouteBuilderComponent#registryReplacements}. * * @param key the key to look for. * @return the corresponding value. * @throws IllegalArgumentException if key not found. */ public final String getRegistryPropertyOrReplacement(final String key) { String result = this.allRegistryPropertiesAndReplacements.get(key); if (result == null) { throw new IllegalArgumentException("Registry property files in the " + this.conf + " folder do not contain the key " + key + ". Full contents of properties: " + this.allRegistryPropertiesAndReplacements); } else { return result; } } /** * @return The route bundle's symbolic name. This implementation generates * the name based on the OSGi bundle JAR's location. */ public String getRouteName() { String location = this.bundleContext.getBundle().getLocation(); location = location.replace('\\', '/'); int lastSlash = location.lastIndexOf('/'); if (lastSlash != -1) { location = location.substring(lastSlash + 1); } if (location.endsWith(".jar")) { location = location.substring(0, location.length() - 4); } return location; } /** * @return The {@link File} object (source or target) of a Camel endpoint of * type "file". */ public File getFileEndpointFile(final String url) { FileEndpoint endpoint = this.getContext().getEndpoint(url, FileEndpoint.class); if (endpoint == null) { throw new ResolveEndpointFailedException("Cannot find " + url); } return endpoint.getFile(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy