Package net.timewalker.ffmq3

Source Code of net.timewalker.ffmq3.FFMQServer

/*
* This file is part of FFMQ.
*
* FFMQ 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 of the License, or
* (at your option) any later version.
*
* FFMQ 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 FFMQ; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.timewalker.ffmq3;

import java.io.File;
import java.util.List;
import java.util.Vector;

import javax.jms.JMSException;
import javax.management.ObjectName;

import net.timewalker.ffmq3.admin.RemoteAdministrationThread;
import net.timewalker.ffmq3.cluster.bridge.JMSBridge;
import net.timewalker.ffmq3.jmx.JMXAgent;
import net.timewalker.ffmq3.jmx.rmi.JMXOverRMIAgent;
import net.timewalker.ffmq3.listeners.ClientListener;
import net.timewalker.ffmq3.listeners.tcp.io.TcpListener;
import net.timewalker.ffmq3.listeners.tcp.nio.NIOTcpListener;
import net.timewalker.ffmq3.local.FFMQEngine;
import net.timewalker.ffmq3.local.FFMQEngineListener;
import net.timewalker.ffmq3.local.destination.LocalQueue;
import net.timewalker.ffmq3.local.destination.LocalTopic;
import net.timewalker.ffmq3.management.BridgeDefinitionProvider;
import net.timewalker.ffmq3.management.bridge.BridgeDefinition;
import net.timewalker.ffmq3.utils.Settings;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* <p>Implementation of an FFMQ Server instance.</p>
*/
public final class FFMQServer implements FFMQServerMBean, FFMQEngineListener, Runnable
{
    private static final Log log = LogFactory.getLog(FFMQServer.class);
   
    private static final int ADMIN_THREAD_STOP_TIMEOUT = 30; // seconds
   
    // Settings
    private String engineName;
    private Settings settings;

    // Runtime
    private long startupTime;
    private JMXAgent jmxAgent;
    private FFMQEngine engine;
    private ClientListener tcpListener;
    private RemoteAdministrationThread adminThread;
    private BridgeDefinitionProvider bridgeDefinitionProvider;
    private List bridges = new Vector();
    private boolean started;
    private boolean stopRequired;
    private boolean inRunnableMode;
    
    /**
     * Constructor
     */
    public FFMQServer( String engineName , Settings settings ) throws JMSException
    {
      this.engineName = engineName;
        this.settings = settings;
        init();
    }
   
    private void init() throws JMSException
    {
        // Bridge definitions directory
        String bridgeDefinitionDirPath = settings.getStringProperty(FFMQCoreSettings.BRIDGE_DEFINITIONS_DIR, null);
        if (bridgeDefinitionDirPath != null)
        {
            File bridgeDefinitionsDir = new File(bridgeDefinitionDirPath);
            if (!bridgeDefinitionsDir.isDirectory())
                throw new FFMQException("Bridge definitions directory does not exist : "+bridgeDefinitionsDir.getAbsolutePath(),"FS_ERROR");
            this.bridgeDefinitionProvider = new BridgeDefinitionProvider(bridgeDefinitionsDir);   
        }
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#getVersion()
     */
    public String getVersion()
    {
      return FFMQVersion.getProviderMajorVersion()+"."+FFMQVersion.getProviderMinorVersion()+"."+FFMQVersion.getProviderReleaseVersion();
    }
   
    /*
     * (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#start()
     */
    public synchronized boolean start()
    {
      if (started)
        return false;
     
      try
      {
        long startTime = System.currentTimeMillis();
       
        // Banners
          log.info("FFMQ server "+getVersion()+
                   " (Java "+System.getProperty("java.version")+")");
          log.info("Running on "+System.getProperty("os.name","?")+" "+System.getProperty("os.version","?"));
          log.info("JVM is "+System.getProperty("java.vm.vendor","?")+" "+System.getProperty("java.runtime.version","?")+" ["+System.getProperty("java.vm.name","?")+"] at "+System.getProperty("java.home","?"));
          log.info("Server local engine name is '"+engineName+"'");
       
          log.debug("Server startup ...");
         
          // Deploy JMX support
          boolean jmxAgentEnabled = settings.getBooleanProperty(FFMQCoreSettings.JMX_AGENT_ENABLED, false);
          int jmxJndiRmiPort = settings.getIntProperty(FFMQCoreSettings.JMX_AGENT_JNDI_RMI_PORT,10003);
          String jmxRmiListenAddr = settings.getStringProperty(FFMQCoreSettings.JMX_AGENT_RMI_LISTEN_ADDR, "0.0.0.0");
          if (jmxAgentEnabled)
          {
            jmxAgent = new JMXOverRMIAgent("FFMQ-server",jmxJndiRmiPort,jmxRmiListenAddr);
            try
            {
              jmxAgent.register(new ObjectName(":type=Server"), this);
            }
            catch (Exception e)
            {
              log.error("Cannot register server on JMX agent",e);
            }
          }
         
          // Deploy local engine
          engine = new FFMQEngine(engineName,settings,this);
          try
        {
          if (jmxAgent != null)
            jmxAgent.register(new ObjectName(":type=Engines,engine="+engine.getName()), engine);
        }
        catch (Exception e)
        {
          log.error("Cannot register local engine on JMX agent",e);
        }
          engine.deploy();
         
          // Deploy listeners
          String listenAddr          = settings.getStringProperty(FFMQServerSettings.LISTENER_TCP_LISTEN_ADDR,null);
          int listenPort             = settings.getIntProperty(FFMQServerSettings.LISTENER_TCP_LISTEN_PORT,FFMQConstants.DEFAULT_SERVER_PORT);
          boolean tcpListenerEnabled = settings.getBooleanProperty(FFMQServerSettings.LISTENER_TCP_ENABLED,true);
          boolean useNIOListener     = settings.getBooleanProperty(FFMQServerSettings.LISTENER_TCP_USE_NIO,false);
          boolean useSSL             = settings.getBooleanProperty(FFMQCoreSettings.TRANSPORT_TCP_SSL_ENABLED, false);
          if (useSSL && useNIOListener)
            throw new FFMQException("Cannot enable SSL & NIO listener at the same time.","CONFIGURATION_ERROR"); // JDK 1.4 limitation
 
          if (tcpListenerEnabled)
          {
            if (useNIOListener)
              tcpListener = new NIOTcpListener(engine,listenAddr,listenPort,settings,jmxAgent);
            else
              tcpListener = new TcpListener(engine,listenAddr,listenPort,settings,jmxAgent);
 
            if (jmxAgent != null)
            {
          try
          {
            jmxAgent.register(new ObjectName(":type=Listeners,listener="+tcpListener.getName()),tcpListener);
          }
          catch (Exception e)
          {
            log.error("Cannot register listener on JMX agent",e);
          }
            }
             
              tcpListener.start();
          }
         
          // Deploy remote admin support
          boolean remoteAdminEnabled = settings.getBooleanProperty(FFMQServerSettings.REMOTE_ADMIN_ENABLED,false);
          if (remoteAdminEnabled)
          {
              adminThread = new RemoteAdministrationThread(this,engine);
              adminThread.start();
              try
              {
                  adminThread.waitForStartup();
              }
              catch (InterruptedException e)
              {
                  throw new FFMQException("Deploy was interrupted while waiting for the admin thread to start","INTERNAL_ERROR");
              }
          }
         
          // Deploy bridges
          deployBridges();
         
          long endTime = System.currentTimeMillis();
          log.info("Server startup complete. ("+(endTime-startTime)+" ms)");
         
          started = true;
          startupTime = System.currentTimeMillis();
                   
          return true;
      }
      catch (JMSException e)
      {
        if (e.getLinkedException() != null)
          {
            log.error("Server startup failed",e);
            log.error("Original error was :",e.getLinkedException());
          }
          else
            log.error("Server startup failed",e);
       
        return false;
      }
      catch (Exception e)
      {
        log.error("Server startup failed",e);
        return false;
      }
    }
   
    private void deployBridges() throws JMSException
    {
        if (bridgeDefinitionProvider != null)
        {
            // Load definitions
            this.bridgeDefinitionProvider.loadExistingDefinitions();

            BridgeDefinition[] bridgeDefs = bridgeDefinitionProvider.getBridgeDefinitions();
            for (int i = 0; i < bridgeDefs.length; i++)
            {
                log.debug("Deploying JMS bridge : "+bridgeDefs[i].getName());
                JMSBridge bridge = new JMSBridge(bridgeDefs[i]);
                if (bridgeDefs[i].isEnabled())
                    bridge.start();
                else
                    log.debug("JMS bridge is disabled : "+bridgeDefs[i].getName());
                bridges.add(bridge);
                bridgeDeployed(bridge);
            }
        }
    }
   
    private void undeployBridges()
    {
        for (int i = 0; i < bridges.size(); i++)
        {
            JMSBridge bridge = (JMSBridge)bridges.get(i);
           
            log.debug("Undeploying JMS bridge : "+bridge.getBridgeDefinition().getName());
            if (bridge.isStarted())
                bridge.stop();
            bridgeUndeployed(bridge);
        }
        bridges.clear();
    }
   
    /*
     * (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#shutdown()
     */
    public synchronized boolean shutdown()
    {
      if (!started)
        return false;
     
      try
      {
          log.info("Server shutting down ...");
         
          // Undeploy bridges
          undeployBridges();
         
          // Stop the tcp listener
          if (tcpListener != null)
          {
            tcpListener.stop();
            tcpListener = null;
          }
         
          // Terminate the admin thread
          if (adminThread != null)
          {
              adminThread.pleaseStop();
              try
              {
                  adminThread.join(ADMIN_THREAD_STOP_TIMEOUT*1000);
                  adminThread = null;
              }
              catch (InterruptedException e)
              {
                  log.warn("Shutdown was interrupted while waiting for the admin thread to stop");
              }
          }
         
          // Undeploy engine
          engine.undeploy();
          try
        {
          if (jmxAgent != null)
            jmxAgent.unregister(new ObjectName(":type=Engines,engine="+engine.getName()));
        }
        catch (Exception e)
        {
          log.error("Cannot unregister local engine from JMX agent",e);
        }
         
          // Undeploy JMX
          if (jmxAgent != null)
            jmxAgent.stop();
         
          started = false;
                   
          return true;
      }
      catch (Exception e)
      {
        log.error("Server shutdown failed",e);
        return false;
      }
    }
   
    /*
     * (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#isStarted()
     */
    public synchronized boolean isStarted()
    {
        return started;
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#engineDeployed()
     */
    public void engineDeployed()
    {
      // Nothing
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#engineUndeployed()
     */
    public void engineUndeployed()
    {
      // Nothing
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#queueDeployed(net.timewalker.ffmq3.local.destination.LocalQueue)
     */
    public void queueDeployed(LocalQueue queue)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.register(new ObjectName(":type=Engines,engine="+engine.getName()+",children=queues,name="+queue.getName()), queue);
      }
      catch (Exception e)
      {
        log.error("Cannot register local queue on JMX agent",e);
      }
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#queueUndeployed(net.timewalker.ffmq3.local.destination.LocalQueue)
     */
    public void queueUndeployed(LocalQueue queue)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.unregister(new ObjectName(":type=Engines,engine="+engine.getName()+",children=queues,name="+queue.getName()));
      }
      catch (Exception e)
      {
        log.error("Cannot unregister local queue from JMX agent",e);
      }
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#topicDeployed(net.timewalker.ffmq3.local.destination.LocalTopic)
     */
    public void topicDeployed(LocalTopic topic)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.register(new ObjectName(":type=Engines,engine="+engine.getName()+",children=topics,name="+topic.getName()), topic);
      }
      catch (Exception e)
      {
        log.error("Cannot register local topic on JMX agent",e);
      }
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.local.LocalEngineListener#topicUndeployed(net.timewalker.ffmq3.local.destination.LocalTopic)
     */
    public void topicUndeployed(LocalTopic topic)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.unregister(new ObjectName(":type=Engines,engine="+engine.getName()+",children=topics,name="+topic.getName()));
      }
      catch (Exception e)
      {
        log.error("Cannot unregister local topic from JMX agent",e);
      }
    }

    private void bridgeDeployed(JMSBridge bridge)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.register(new ObjectName(":type=Bridges,bridge="+bridge.getName()), bridge);
      }
      catch (Exception e)
      {
        log.error("Cannot register bridge on JMX agent",e);
      }
    }

    private void bridgeUndeployed(JMSBridge bridge)
    {
      try
      {
        if (jmxAgent != null)
          jmxAgent.unregister(new ObjectName(":type=Bridges,bridge="+bridge.getName()));
      }
      catch (Exception e)
      {
        log.error("Cannot unregister bridge fromJMX agent",e);
      }
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#isRemoteAdministrationEnabled()
     */
    public synchronized boolean isRemoteAdministrationEnabled()
    {
      return adminThread != null;
    }
   
    /* (non-Javadoc)
     * @see net.timewalker.ffmq3.FFMQServerMBean#getUptime()
     */
    public synchronized long getUptime()
    {
      return started ? System.currentTimeMillis()-startupTime : 0;
    }
   
    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    public synchronized void run()
    {
        if (!start())
          return;
       
        try
        {
          inRunnableMode = true;
          while (!stopRequired)
            wait();
        }
        catch (InterruptedException e)
        {
          log.error("Server was interrupted.");
        }
       
        shutdown();     
    }
   
    public synchronized void pleaseStop()
    {
      stopRequired = true;
      notify();
    }
   
    /**
   * @return the inRunnableMode
   */
  public synchronized boolean isInRunnableMode()
  {
    return inRunnableMode;
  }
}
TOP

Related Classes of net.timewalker.ffmq3.FFMQServer

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.