Package net.timewalker.ffmq3.admin

Source Code of net.timewalker.ffmq3.admin.RemoteAdministrationThread

/*
* 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.admin;

import java.util.Enumeration;

import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;

import net.timewalker.ffmq3.FFMQAdminConstants;
import net.timewalker.ffmq3.FFMQConstants;
import net.timewalker.ffmq3.FFMQException;
import net.timewalker.ffmq3.FFMQServer;
import net.timewalker.ffmq3.local.FFMQEngine;
import net.timewalker.ffmq3.local.connection.LocalQueueConnection;
import net.timewalker.ffmq3.local.destination.LocalQueue;
import net.timewalker.ffmq3.management.destination.definition.QueueDefinition;
import net.timewalker.ffmq3.management.destination.definition.TopicDefinition;
import net.timewalker.ffmq3.utils.ErrorTools;
import net.timewalker.ffmq3.utils.Settings;
import net.timewalker.ffmq3.utils.StringTools;
import net.timewalker.ffmq3.utils.concurrent.SynchronizableThread;

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

/**
* AdministrationThread
*/
public final class RemoteAdministrationThread extends SynchronizableThread
{
    private static final Log log          = LogFactory.getLog(RemoteAdministrationThread.class);

    protected FFMQServer     server;
    private FFMQEngine       engine;
    private QueueConnection  conn         = null;
    private QueueSession     session      = null;
    private QueueSender      sender       = null;
    private QueueReceiver    receiver     = null;
    private boolean          stopRequired = false;
   
    /**
     * Constructor
     */
    public RemoteAdministrationThread(FFMQServer server,FFMQEngine engine)
    {
        super("FFMQ-RemoteAdminThread");
        this.server = server;
        this.engine = engine;
    }

    /*
     * (non-Javadoc)
     * @see net.timewalker.ffmq3.utils.concurrent.SynchronizableThread#run()
     */
    public void run()
    {
        log.info("Starting remote administration thread ...");

        try
        {
            LocalQueue inputQueue = engine.getLocalQueue(FFMQConstants.ADM_REQUEST_QUEUE);
            LocalQueue outputQueue = engine.getLocalQueue(FFMQConstants.ADM_REPLY_QUEUE);
           
            conn = new LocalQueueConnection(engine, null, null);
            session = conn.createQueueSession(true, Session.SESSION_TRANSACTED);
            receiver = session.createReceiver(inputQueue);
            sender = session.createSender(outputQueue);

            conn.start();

            // Flush input queue on startup
            inputQueue.purge(null);
            outputQueue.purge(null);
           
            // Enter listening loop
            notifyStartup();
            while (!stopRequired)
            {
                Message message = receiver.receive();
                if (message == null)
                    break; // Interrupted
                log.debug("Received message " + message);

                try
                {
                    // Process the command
                    String errorMsg = process(message);
   
                    // Build response message
                    Message response = session.createMessage();
                    response.setJMSCorrelationID(message.getJMSMessageID());
                    if (errorMsg != null)
                        response.setStringProperty(FFMQAdminConstants.ADM_HEADER_ERRMSG, errorMsg);
                   
                    sender.send(response,DeliveryMode.NON_PERSISTENT,Message.DEFAULT_PRIORITY,Message.DEFAULT_TIME_TO_LIVE);
                }
                catch (JMSException e)
                {
                    log.error("Cannot process admin command",e);
                }
                finally
                {
                    session.commit();
                }
            }
           
            log.debug("Remote administration thread has stopped");
        }
        catch (Throwable e)
        {
            log.fatal("Administration thread failed", e);
            notifyStartup();
        }
        finally
        {
            try
            {
                if (sender != null)
                    sender.close();
            }
            catch (JMSException e)
            {
              ErrorTools.log(e, log);
            }

            try
            {
                if (receiver != null)
                    receiver.close();
            }
            catch (JMSException e)
            {
              ErrorTools.log(e, log);
            }

            try
            {
                if (session != null)
                    session.close();
            }
            catch (JMSException e)
            {
              ErrorTools.log(e, log);
            }

            try
            {
                if (conn != null)
                    conn.close();
            }
            catch (JMSException e)
            {
              ErrorTools.log(e, log);
            }
        }
    }

    private String process(Message msg)
    {
        try
        {
            String command = msg.getStringProperty(FFMQAdminConstants.ADM_HEADER_COMMAND);
            if (StringTools.isEmpty(command))
                return "Administration command not set in message header";
               
            // Dispatch
            if (command.equals(FFMQAdminConstants.ADM_COMMAND_CREATE_QUEUE))
                return processCreateQueue(msg);
           
            if (command.equals(FFMQAdminConstants.ADM_COMMAND_CREATE_TOPIC))
                return processCreateTopic(msg);
           
            if (command.equals(FFMQAdminConstants.ADM_COMMAND_DELETE_QUEUE))
                return processDeleteQueue(msg);
           
            if (command.equals(FFMQAdminConstants.ADM_COMMAND_DELETE_TOPIC))
                return processDeleteTopic(msg);
           
            if (command.equals(FFMQAdminConstants.ADM_COMMAND_SHUTDOWN))
                return processShutdown(msg);

            return "Invalid administration command : "+command;
        }
        catch (JMSException e)
        {
          ErrorTools.log(e, log);
          return "Error processing administration command : "+e.getMessage();
        }
        catch (Exception e)
        {
          ErrorTools.log(new FFMQException("Cannot process admin message","INVALID_ADMIN_MESSAGE",e), log);
            return "Error processing administration command : "+e.getMessage();
        }
    }
   
    private Settings createSettings( Message msg ) throws JMSException
    {
        // Fill settings from message headers
        Settings queueSettings = new Settings();
        Enumeration headers = msg.getPropertyNames();
        while (headers.hasMoreElements())
        {
            String propName = (String)headers.nextElement();
            if (propName.startsWith(FFMQAdminConstants.ADM_HEADER_PREFIX))
                continue;
           
            String propValue = msg.getStringProperty(propName);
            queueSettings.setStringProperty(propName, propValue);
        }
        return queueSettings;
    }
   
    private String processCreateQueue( Message msg ) throws JMSException
    {
        Settings queueSettings = createSettings(msg);
        QueueDefinition queueDef = new QueueDefinition(queueSettings);
       
        log.debug("Creating queue : "+queueDef);
        engine.createQueue(queueDef);
       
        // Success
        return null;
    }
   
    private String processCreateTopic( Message msg ) throws JMSException
    {
        Settings topicSettings = createSettings(msg);
        TopicDefinition topicDef = new TopicDefinition(topicSettings);

        log.debug("Creating topic : "+topicDef);
        engine.createTopic(topicDef);
       
        // Success
        return null;
    }
   
    private String processDeleteQueue( Message msg ) throws JMSException
    {
        String destName = msg.getStringProperty("name");
        if (StringTools.isEmpty(destName))
            return "Destination name not specified";
       
        if (!engine.localQueueExists(destName))
            return "Queue "+destName+" does not exist";
       
        engine.deleteQueue(destName);
       
        return null;
    }
   
    private String processDeleteTopic( Message msg ) throws JMSException
    {
        String destName = msg.getStringProperty("name");
        if (StringTools.isEmpty(destName))
            return "Destination name not specified";
       
        if (!engine.localTopicExists(destName))
            return "Topic "+destName+" does not exist";
       
        engine.deleteTopic(destName);
       
        return null;
    }
   
    private String processShutdown( Message msg )
    {
      // Shutdown the server
      if (server.isInRunnableMode())
        server.pleaseStop();
      else
      {
        // Run the shutdown sequence in a parallel thread to avoid deadlocks
        new Thread() {
          public void run() {
            server.shutdown();
          }
        }.start();
      }
     
        return null;
    }
   
    /**
     * Ask the thread to stop
     */
    public void pleaseStop()
    {
      if (stopRequired)
        return;
     
        stopRequired = true;
        try
        {
            if (receiver != null)
                receiver.close();
        }
        catch (JMSException e)
        {
          ErrorTools.log(e, log);
        }
    }
}
TOP

Related Classes of net.timewalker.ffmq3.admin.RemoteAdministrationThread

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.