Package org.xmlBlaster.protocol.xmlrpc

Source Code of org.xmlBlaster.protocol.xmlrpc.XmlRpcDriver

/*------------------------------------------------------------------------------
Name:      XmlRpcDriver.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
Comment:   XmlRpcDriver class to invoke the xmlBlaster server in the same JVM.
Version:   $Id: XmlRpcDriver.java 17680 2009-05-08 22:10:57Z laghi $
------------------------------------------------------------------------------*/
package org.xmlBlaster.protocol.xmlrpc;

import java.io.IOException;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.context.ContextNode;
import org.xmlBlaster.util.def.Constants;
import org.xmlBlaster.util.def.ErrorCode;
import org.xmlBlaster.util.plugin.PluginInfo;
import org.xmlBlaster.util.protocol.socket.SocketUrl;
import org.xmlBlaster.util.protocol.xmlrpc.XblRequestFactoryFactory;
import org.xmlBlaster.util.protocol.xmlrpc.XblWriterFactory;
import org.xmlBlaster.engine.qos.AddressServer;
import org.xmlBlaster.protocol.I_Authenticate;
import org.xmlBlaster.protocol.I_XmlBlaster;
import org.xmlBlaster.protocol.I_Driver;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcHttpServer;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;

/**
* XmlRpc driver class to invoke the xmlBlaster server over HTTP XMLRPC.
* <p />
* This driver needs to be registered in xmlBlaster.properties
* and will be started on xmlBlaster startup, for example:
* <pre>
* ProtocolPlugin[XMLRPC][1.0]=org.xmlBlaster.protocol.xmlrpc.XmlRpcDriver
* CbProtocolPlugin[XMLRPC][1.0]=org.xmlBlaster.protocol.xmlrpc.CallbackXmlRpcDriver
* </pre>
*
* The variable plugin/xmlrpc/port (default 8080) sets the http web server port,
* you may change it in xmlBlaster.properties or on command line:
* <pre>
* java -jar lib/xmlBlaster.jar  -plugin/xmlrpc/port 9080
* </pre>
*
* The interface I_Driver is needed by xmlBlaster to instantiate and shutdown
* this driver implementation.
* @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/protocol.xmlrpc.html">The protocol.xmlrpc requirement</a>
* @see <a href="http://marc.theaimsgroup.com/?l=rpc-user&m=102009663407418&w=2">Configuring SSL with XmlRpc</a>
* @author xmlBlaster@marcelruff.info
*/
public class XmlRpcDriver implements I_Driver, XmlRpcDriverMBean
{
   private String ME = "XmlRpcDriver";
   private Global glob;
   private PluginInfo pluginInfo;
   private static Logger log = Logger.getLogger(XmlRpcDriver.class.getName());
   /** The singleton handle for this xmlBlaster server */
   private I_Authenticate authenticate = null;
   /** The singleton handle for this xmlBlaster server */
   private I_XmlBlaster xmlBlasterImpl = null;
   public static final int DEFAULT_HTTP_PORT = 8080;
   /** The xml-rpc HTTP web server */
   private WebServer webServer;
   /** The URL which clients need to use to access this server */
   private XmlRpcUrl xmlRpcUrl;
   /** Our configuration */
   private AddressServer addressServer;
   /** My JMX registration, can be done optionally by implementing classes */
   protected Object mbeanHandle;
   protected ContextNode contextNode;
   protected boolean isActive;


   /**
    * Get a human readable name of this driver.
    * <p />
    * Enforced by interface I_Driver.
    */
   public String getName() {
      return ME;
   }

   /**
    * Access the xmlBlaster internal name of the protocol driver.
    * @return "XMLRPC"
    */
   public String getProtocolId() {
      return (pluginInfo == null) ? "XMLRPC" : pluginInfo.getType();
   }

   /** Enforced by I_Plugin */
   public String getType() {
      return getProtocolId();
   }

   /** Enforced by I_Plugin */
   public String getVersion() {
      return (pluginInfo == null) ? "1.0" : pluginInfo.getVersion();
   }

   /**
    * This method is called by the PluginManager (enforced by I_Plugin).
    * @see org.xmlBlaster.util.plugin.I_Plugin#init(org.xmlBlaster.util.Global,org.xmlBlaster.util.plugin.PluginInfo)
    */
   public void init(org.xmlBlaster.util.Global glob, org.xmlBlaster.util.plugin.PluginInfo pluginInfo)
      throws XmlBlasterException {
      this.glob = glob;
      this.pluginInfo = pluginInfo;
      org.xmlBlaster.engine.ServerScope engineGlob = (org.xmlBlaster.engine.ServerScope)glob.getObjectEntry(Constants.OBJECT_ENTRY_ServerScope);
      if (engineGlob == null)
         throw new XmlBlasterException(this.glob, ErrorCode.INTERNAL_UNKNOWN, ME + ".init", "could not retreive the ServerNodeScope. Am I really on the server side ?");

      this.authenticate = engineGlob.getAuthenticate();
      if (this.authenticate == null) {
         throw new XmlBlasterException(this.glob, ErrorCode.INTERNAL_UNKNOWN, ME + ".init", "authenticate object is null");
      }
      I_XmlBlaster xmlBlasterImpl = this.authenticate.getXmlBlaster();
      if (xmlBlasterImpl == null) {
         throw new XmlBlasterException(this.glob, ErrorCode.INTERNAL_UNKNOWN, ME + ".init", "xmlBlasterImpl object is null");
      }

      // For JMX instanceName may not contain ","
      this.contextNode = new ContextNode(ContextNode.SERVICE_MARKER_TAG,
            "XmlRpcDriver[" + getType() + "]",
            glob.getContextNode());
      this.mbeanHandle = this.glob.registerMBean(this.contextNode, this);
        
      try {
         init(glob, new AddressServer(glob, getType(), glob.getId(), pluginInfo.getParameters()), this.authenticate, xmlBlasterImpl);

         activate();
      }
      catch (XmlBlasterException ex) {
         throw ex;
      }
      catch (Throwable ex) {
         throw new XmlBlasterException(this.glob, ErrorCode.INTERNAL_UNKNOWN, ME + ".init", "init. Could'nt initialize the driver.", ex);
      }
   }

   /**
    * Get the address how to access this driver.
    * @return "http://server.mars.universe:8080/"
    */
   public String getRawAddress() {
      return this.xmlRpcUrl.getUrl();
   }

   /**
    * Start xmlBlaster XMLRPC access.
    * <p />
    * Enforced by interface I_Driver.
    * @param glob Global handle to access logging, property and commandline args
    * @param authenticate Handle to access authentication server
    * @param xmlBlasterImpl Handle to access xmlBlaster core
    */
   private synchronized void init(Global glob, AddressServer addressServer, I_Authenticate authenticate, I_XmlBlaster xmlBlasterImpl)
      throws XmlBlasterException
   {
      this.glob = glob;
      this.ME = "XmlRpcDriver" + this.glob.getLogPrefixDashed();

      this.addressServer = addressServer;
      if (log.isLoggable(Level.FINER)) log.finer("Entering init()");
      this.authenticate = authenticate;
      this.xmlBlasterImpl = xmlBlasterImpl;

      this.xmlRpcUrl = new XmlRpcUrl(glob, this.addressServer); // e.g. "http://127.168.1.1:8080/"
      if (this.xmlRpcUrl.getPort() < 1) {
         log.info("Option plugin/xmlrpc/port set to " + this.xmlRpcUrl.getPort() + ", xmlRpc server not started");
         return;
      }

      // "-plugin/xmlrpc/debug true"
      /*
      if (this.addressServer.getEnv("debug", false).getValue() == true)
         XmlRpc.setDebug(true);
       */
   }

   /**
    * The server configuration of this plugin
    */
   public AddressServer getAddressServer() {
      return this.addressServer;
   }

   /**
    * Activate xmlBlaster access through this protocol.
    */
   public synchronized void activate() throws XmlBlasterException {
      if (log.isLoggable(Level.FINER)) log.finer("Entering activate");
      try {
         final boolean isLocal = false;
         // SocketUrl socketUrl = new SocketUrl(glob, addressServer, isLocal, DEFAULT_HTTP_PORT);
         SocketUrl socketUrl = new SocketUrl(glob, xmlRpcUrl.getHostname(), xmlRpcUrl.getPort());

         webServer = new XblWebServer(xmlRpcUrl, socketUrl, addressServer);
         // publish the public methods to the XmlRpc web server:
         // webServer.addHandler("authenticate", new AuthenticateImpl(glob, this, authenticate));
         // webServer.addHandler("xmlBlaster", new XmlBlasterImpl(glob, this, xmlBlasterImpl));
        
         PropertyHandlerMapping mapping = new PropertyHandlerMapping();
        
         XmlBlasterImpl xblImpl = new XmlBlasterImpl(glob, this, xmlBlasterImpl);
         AuthenticateImpl auImpl = new AuthenticateImpl(glob, this, authenticate, xblImpl);
        
         XblRequestFactoryFactory factoryFactory = new XblRequestFactoryFactory();
         factoryFactory.add(auImpl);
         factoryFactory.add(xblImpl);
         mapping.setRequestProcessorFactoryFactory(factoryFactory);
        
         mapping.addHandler("authenticate", auImpl.getClass());      // register update() method
         mapping.addHandler("xmlBlaster", xblImpl.getClass());
        
         XmlRpcHttpServer xmlRpcServer = (XmlRpcHttpServer)webServer.getXmlRpcServer();
         XmlRpcServerConfigImpl serverCfg = new XmlRpcServerConfigImpl();
         serverCfg.setEnabledForExceptions(true);
         serverCfg.setEnabledForExtensions(true);
         xmlRpcServer.setConfig(serverCfg);
         xmlRpcServer.setHandlerMapping(mapping);
         boolean useCDATA = addressServer.getEnv("useCDATA", false).getValue();
         XblWriterFactory writerFactory = new XblWriterFactory(useCDATA);
         xmlRpcServer.setXMLWriterFactory(writerFactory);

        
         webServer.start();
         log.info("Started successfully XMLRPC driver, access url=" + this.xmlRpcUrl.getUrl());
      }
      catch (IOException e) {
         log.severe("Error creating webServer on '" + this.xmlRpcUrl.getUrl() + "': " + e.toString());
         //e.printStackTrace();
      }
      catch (XmlRpcException e) {
         log.severe("Error creating webServer on '" + this.xmlRpcUrl.getUrl() + "': " + e.toString());
         //e.printStackTrace();
      }
      this.isActive = true;
   }

   /**
    * Deactivate xmlBlaster access (standby), no clients can connect.
    */
   public synchronized void deActivate() {
      if (log.isLoggable(Level.FINER)) log.finer("Entering deActivate");
      this.isActive = false;
      if (webServer != null) {
         try {
            webServer.getXmlRpcServer().setHandlerMapping(null);
            // getHandlerMapping().removeHandler("authenticate");
            // webServer.removeHandler("xmlBlaster");
            webServer.shutdown();
         }
         catch(Throwable e) {
            log.warning("Problems during shutdown of xmlrpc web server: " + e.toString());
         }
         webServer = null;
         log.info("XMLRPC driver stopped, handler released.");
      }
      else
         log.info("XMLRPC shutdown, nothing to do.");
   }

   /**
    * Instructs XMLRPC driver to shut down.
    * <p />
    * Enforced by interface I_Driver.
    */
   public void shutdown() throws XmlBlasterException {
      deActivate();
      this.glob.unregisterMBean(this.mbeanHandle);
   }

   public String getEnvPrefix() {
      return (addressServer != null) ? addressServer.getEnvPrefix() : "plugin/"+getType().toLowerCase();
   }

   /**
    * Command line usage.
    * <p />
    * Enforced by interface I_Driver.
    */
   public String usage() {
      String text = "\n";
      text += "XmlRpcDriver options:\n";
      text += "   -"+getEnvPrefix()+"port\n";
      text += "                       The XMLRPC web server port [" + DEFAULT_HTTP_PORT + "].\n";
      text += "   -"+getEnvPrefix()+"hostname\n";
      text += "                       Specify a hostname where the XMLRPC web server runs.\n";
      text += "                       Default is the localhost. If you specify the protocol then port and ssl info are taken from here\n";
      text += "                       for example https://localhost:8443/somePath would ignore port, SSL, path\n";
      // text += "   -plugin/xmlrpc/debug\n";
      // text += "                       true switches on detailed XMLRPC debugging [false].\n";
     
      text += "   -"+getEnvPrefix()+"SoTimeout\n";
      text += "                       How long may a socket read block in msec.\n";
      text += "   -"+getEnvPrefix()+"responseTimeout\n";
      text += "                       Max wait for the method return value/exception in msec.\n";
//      text += "                       The default is " +getDefaultResponseTimeout() + ".\n";
      text += "                       Defaults to 'forever', the value to pass is milli seconds.\n";
      // text += "   -"+getEnvPrefix()+"backlog\n";
      // text += "                       Queue size for incoming connection request [50].\n";
      text += "   -"+getEnvPrefix()+"SSL\n";
      text += "                       True enables SSL support on socket [false] (if no protocol specified in hostname).\n";
      text += "   -"+getEnvPrefix()+"keyStore\n";
      text += "                       The path of your keystore file. Use the java utility keytool.\n";
      text += "   -"+getEnvPrefix()+"keyStorePassword\n";
      text += "                       The password of your keystore file.\n";
      text += "   -dispatch/connection/plugin/socket/compress/type\n";
      text += "                       Valid values are: '', '"+Constants.COMPRESS_ZLIB_STREAM+"', '"+Constants.COMPRESS_ZLIB+"' [].\n";
      text += "                       '' disables compression, '"+Constants.COMPRESS_ZLIB_STREAM+"' compresses whole stream.\n";
      text += "                       '"+Constants.COMPRESS_ZLIB+"' both compress the same (both are provided as compatibility to the socket protocol).\n";
     
      text += "   " + Global.getJmxUsageLinkInfo(this.getClass().getName(), null);
      text += "\n";
      return text;
   }

   /**
    * @return A link for JMX usage
    */
   public java.lang.String getUsageUrl() {
      return Global.getJavadocUrl(this.getClass().getName(), null);
   }

   /* dummy to have a copy/paste functionality in jconsole */
   public void setUsageUrl(java.lang.String url) {
   }

   /**
    * JMX
    * @see org.xmlBlaster.util.admin.I_AdminService#isActive()
    */
   public boolean isActive() {
      return this.isActive;
   }

   /**
    * JMX
    * @see org.xmlBlaster.util.admin.I_AdminPlugin#isShutdown()
    */
   public boolean isShutdown() {
      return isActive();
   }
}
TOP

Related Classes of org.xmlBlaster.protocol.xmlrpc.XmlRpcDriver

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.