Package org.jboss.soa.esb.listeners.gateway.camel

Source Code of org.jboss.soa.esb.listeners.gateway.camel.CamelGateway$JndiTypeConverter

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* 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,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*
* (C) 2005-2010
*/
package org.jboss.soa.esb.listeners.gateway.camel;

import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import javax.jms.ConnectionFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.NoTypeConversionAvailableException;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.TypeConverter;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.DefaultPackageScanClassResolver;
import org.apache.camel.impl.JndiRegistry;
import org.apache.camel.model.Constants;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.TypeConverterRegistry;
import org.apache.log4j.Logger;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.addressing.eprs.JMSEpr;
import org.jboss.soa.esb.common.Configuration;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.helpers.NamingContextException;
import org.jboss.soa.esb.helpers.NamingContextPool;
import org.jboss.soa.esb.listeners.lifecycle.AbstractManagedLifecycle;
import org.jboss.soa.esb.listeners.lifecycle.ManagedLifecycleException;
import org.jboss.soa.esb.util.JndiUtil;

/**
* <p>The CamelGateway leverages Apache Camel's input capabilities, translates the Camel Message to an ESB Message,
* and invokes the associated ESB Service.</p>
*
* <p><em>Configuration example:</em></p>
*
* <p><code>&lt;jbossesb ...&gt;<br/>
* &nbsp;&nbsp;&lt;providers&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;camel-provider name="..."&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;camel-bus busid="..."&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;from uri="..."/&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/camel-bus&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/camel-provider&gt;<br/>
* &nbsp;&nbsp;&lt;/providers&gt;<br/>
* &nbsp;&nbsp;&lt;services&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;listeners&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;camel-gateway name="..." busidref="..."/&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/listeners&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;actions&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;action .../&gt;<br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/actions&gt;<br/>
* &nbsp;&nbsp;&lt;/services&gt;<br/>
* &lt;/jbossesb&gt;</code></p>
*
* <p>For more detailed information, please visit this wiki page:<br/>
* <a href="http://community.jboss.org/wiki/CamelGateway">http://community.jboss.org/wiki/CamelGateway</a><br/>
* or refer to the Programmer's Guide.</p>
*
* @author dward at jboss.org
*/
public class CamelGateway extends AbstractManagedLifecycle {

  public static final String ROUTES = "routes";

  private static final Logger logger = Logger.getLogger(CamelGateway.class);

  private static final String AS6_CLASS_RESOLVER = "org.jboss.soa.esb.listeners.gateway.camel.as6.JBossPackageScanClassResolver";
 
  private static final boolean isAS4;
        private static final boolean isAS5;
  private static final boolean isAS6;

  static {
    try {
      MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
      String versionNumber = (String)mbeanServer.getAttribute(new ObjectName("jboss.system:type=Server"), "VersionNumber");
      isAS4 = (Integer.valueOf(versionNumber.substring(0, 1)).intValue() == 4);
                        isAS5 = (Integer.valueOf(versionNumber.substring(0, 1)).intValue() == 5);
      isAS6 = (Integer.valueOf(versionNumber.substring(0, 1)).intValue() == 6);
    } catch (Throwable t) {
      throw new RuntimeException("problem detecting JBoss AS version", t);
    }
  }

  private String routesXML = null;
  private Properties jndiEnvironment = null;
  private Context jndiContext = null;
  private CamelContext camelContext = null;

  public CamelGateway(ConfigTree config) throws ConfigurationException {
    super(config);
    for (ConfigTree property: config.getChildren("property")) {
      if (ROUTES.equals(property.getRequiredAttribute("name"))) {
        routesXML = property.getRequiredAttribute("value").trim();
        break;
      }
    }
    if (routesXML == null || routesXML.length() == 0) {
      throw new ConfigurationException("property [" + ROUTES + "] missing or empty");
    } else {
      routesXML = routesXML.replaceAll("&", "&amp;");
    }
    jndiEnvironment = JndiUtil.parseEnvironmentProperties(config);
    jndiEnvironment.setProperty(Context.PROVIDER_URL, config.getAttribute(JMSEpr.JNDI_URL_TAG, Configuration.getJndiServerURL()));
    jndiEnvironment.setProperty(Context.INITIAL_CONTEXT_FACTORY, config.getAttribute(JMSEpr.JNDI_CONTEXT_FACTORY_TAG, Configuration.getJndiServerContextFactory()));
    jndiEnvironment.setProperty(Context.URL_PKG_PREFIXES, config.getAttribute(JMSEpr.JNDI_PKG_PREFIX_TAG, Configuration.getJndiServerPkgPrefix()));
  }

  @Override
  protected void doInitialise() throws ManagedLifecycleException {
    try {
      jndiContext = NamingContextPool.getNamingContext(jndiEnvironment);
    } catch (NamingContextException nce) {
      throw new ManagedLifecycleException(nce);
    }
    // this allows us to use Camel's property replacement via ref:{{jndiName}} - actually (ref:%7B%7BjndiName%7D%7D)
    camelContext = new DefaultCamelContext(new JndiRegistry(jndiContext));
    // we need to disable JMX so we don't depend on Spring classes
    camelContext.disableJMX();
    // configure correct classloading
    DefaultPackageScanClassResolver packageScanClassResolver = null;
    if (isAS4) {
                    packageScanClassResolver = (DefaultPackageScanClassResolver) camelContext.getPackageScanClassResolver();
                    if (packageScanClassResolver == null) {
                            packageScanClassResolver = new DefaultPackageScanClassResolver();
                            camelContext.setPackageScanClassResolver(packageScanClassResolver);
                    }
    } else if (isAS5) {
      // JBossESB on AS5+ needs this to handle VFS classloading URIs.
      // JBossESB on AS4 will not work if we use this.
      packageScanClassResolver = new JBossPackageScanClassResolver();
      camelContext.setPackageScanClassResolver(packageScanClassResolver);
    } else if (isAS6) {      
        try {
            Class c = Class.forName(AS6_CLASS_RESOLVER);
            Constructor con = c.getConstructor();
            packageScanClassResolver= (DefaultPackageScanClassResolver) con.newInstance();
                        camelContext.setPackageScanClassResolver(packageScanClassResolver);           
        } catch (InstantiationException e) {
            throw new ManagedLifecycleException(e);
        } catch (ClassNotFoundException e) {
                        throw new ManagedLifecycleException(e);
                    } catch (SecurityException e) {
                        throw new ManagedLifecycleException(e);
                    } catch (NoSuchMethodException e) {
                        throw new ManagedLifecycleException(e);
                    } catch (IllegalArgumentException e) {
                        throw new ManagedLifecycleException(e);
                    } catch (IllegalAccessException e) {
                        throw new ManagedLifecycleException(e);
                    } catch (InvocationTargetException e) {
                        throw new ManagedLifecycleException(e);
                    }
               
                    camelContext.setPackageScanClassResolver(packageScanClassResolver);       
    }
    Set<ClassLoader> classLoaders = new HashSet<ClassLoader>();
    classLoaders.add(Thread.currentThread().getContextClassLoader());
    packageScanClassResolver.setClassLoaders(classLoaders);
    // register JndiTypeConverters
    Set<Class<?>> jndiTypes = new HashSet<Class<?>>();
    jndiTypes.add(ConnectionFactory.class);
    jndiTypes.add(DataSource.class);
    // TODO: add classes from comma-separated config property for more jndiTypes that get looked up?
    TypeConverterRegistry typeConverterRegistry = camelContext.getTypeConverterRegistry();
    TypeConverter jndiTypeConverter = new JndiTypeConverter(jndiContext);
    for (Class<?> jndiType : jndiTypes) {
      typeConverterRegistry.addTypeConverter(jndiType, String.class, jndiTypeConverter);
    }
    camelContext.addComponent(JBossESBComponent.JBOSSESB, new JBossESBComponent(getConfig()));
    if (logger.isDebugEnabled()) {
      try {
        StringWriter sw = new StringWriter();
        OutputFormat of = OutputFormat.createPrettyPrint();
        of.setSuppressDeclaration(true);
        new XMLWriter(sw, of).write(DocumentHelper.parseText(routesXML));
        logger.debug("adding routes [" + sw.toString().replaceAll("&amp;", "&") + "]");
      } catch (Exception e) {
        logger.warn("problem pretty-printing routes: " + e.getMessage());
        logger.debug("adding routes [" + routesXML.replaceAll("&amp;", "&") + "]");
      }
    }
    try {
      JAXBContext jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES);
      Unmarshaller um = jaxbContext.createUnmarshaller();
      RoutesDefinition rd = (RoutesDefinition)um.unmarshal(new StringReader(routesXML));
     
      camelContext.addRouteDefinitions(rd.getRoutes());
    } catch (Exception e) {
      throw new ManagedLifecycleException("problem adding routes", e);
    }
  }

  @Override
  protected void doStart() throws ManagedLifecycleException {
    try {
      camelContext.start();
    } catch (Exception e) {
      throw new ManagedLifecycleException("problem starting CamelContext", e);
    }
  }

  @Override
  protected void doStop() throws ManagedLifecycleException {
    try {
      camelContext.stop();
    } catch (Exception e) {
      throw new ManagedLifecycleException("problem stopping CamelContext", e);
    }
  }

  @Override
  protected void doDestroy() throws ManagedLifecycleException {
    camelContext = null;
    if (jndiContext != null) {
      try {
        NamingContextPool.releaseNamingContext(jndiContext);
      } catch (NamingContextException nce) {
        throw new ManagedLifecycleException(nce);
      } finally {
        jndiContext = null;
      }
    }
  }

  private static class JndiTypeConverter implements TypeConverter {

    private Context jndiContext;

    private JndiTypeConverter(Context jndiContext) {
      this.jndiContext = jndiContext;
    }

    public <T> T convertTo(Class<T> type, Object value) {
      if (value instanceof String) {
        String jndiName = (String)value;
        Object jndiObject;
        try {
          jndiObject = jndiContext.lookup(jndiName);
        } catch (NamingException ne) {
          throw new RuntimeCamelException(ne);
        }
        return type.cast(jndiObject);
      }
      return null;
    }

    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
      return convertTo(type, value);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
      return convertTo(type, value);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
      return convertTo(type, value);
    }

  }

}
TOP

Related Classes of org.jboss.soa.esb.listeners.gateway.camel.CamelGateway$JndiTypeConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.