org.mos.openfire.plugin.ServerInfoPlugin.java Source code

Java tutorial

Introduction

Here is the source code for org.mos.openfire.plugin.ServerInfoPlugin.java

Source

/**
 * $RCSfile: ServerInfo.java,v $
 * $Revision: 1 $
 * $Date: 2014-08-07 21:20:00 -0300 (Thu, 07 Aug 2014) $
 *
 * Copyright (C) 2014 Marcelo Hartmann Terres. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mos.openfire.plugin;

import java.net.*;
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.dom4j.Element;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.jivesoftware.util.Log;
import org.slf4j.LoggerFactory;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;

/**
* ServerInfo service plugin. It accepts messages and return the requested
* information. The address <tt>info@[serviceName].[server]</tt> is
* reserved for receiving the requests.
*
* @author Marcelo Hartmann Terres
*/
public class ServerInfoPlugin implements Plugin, Component, PropertyEventListener {

    private static final String SERVERINFOPORT = "plugin.serverinfo.port";
    private static final String SERVERINFOIP = "plugin.serverinfo.ip";

    private String serviceName;
    private SessionManager sessionManager;
    private ComponentManager componentManager;
    private PluginManager pluginManager;
    private UserManager userManager;

    private Socket socket = null;
    private ServerSocket server = null;
    private DataInputStream streamIn = null;
    private OFD_Server ofd_srv = new OFD_Server();
    public static Thread ofThread;
    public static Boolean NotExit = true;
    public static String serverInfoPort = JiveGlobals.getProperty(SERVERINFOPORT, "4455");
    public static String serverInfoIP = JiveGlobals.getProperty(SERVERINFOIP, "127.0.0.1");

    /**
    * Constructs a new serverinfo plugin.
    */
    public ServerInfoPlugin() {

        serviceName = JiveGlobals.getProperty("plugin.serverinfo.serviceName", "serverinfo");
    }

    // Plugin Interface

    public void initializePlugin(PluginManager manager, File pluginDirectory) {

        Log.info("ServerInfo - Starting plugin.");
        Log.debug("ServerInfo - Starting plugin.");

        pluginManager = manager;
        sessionManager = SessionManager.getInstance();
        String serverInfoPort = JiveGlobals.getProperty(SERVERINFOPORT, "4455");

        userManager = UserManager.getInstance();

        // Register as a component.
        componentManager = ComponentManagerFactory.getComponentManager();

        try {

            componentManager.addComponent(serviceName, this);
        } catch (Exception e) {

            Log.error(e.getMessage(), e);
        }

        PropertyEventDispatcher.addListener(this);

        Log.info("ServerInfo - Starting bind on port " + serverInfoPort + ".");
        Log.debug("ServerInfo - Starting bind on port " + serverInfoPort + ".");
        ofd_srv.startServer();
    }

    public void destroyPlugin() {

        Log.info("ServerInfo - Closing plugin.");
        Log.debug("ServerInfo - Closing plugin.");

        PropertyEventDispatcher.removeListener(this);
        // Unregister component.

        if (componentManager != null) {

            try {

                componentManager.removeComponent(serviceName);
            } catch (Exception e) {

                Log.error(e.getMessage(), e);
            }
        }

        serviceName = JiveGlobals.getProperty("plugin.serverinfo.serviceName", "");
        componentManager = null;
        userManager = null;
        pluginManager = null;
        sessionManager = null;

        Log.info("ServerInfo - Closing thread.");
        Log.debug("ServerInfo - Closing thread.");
        clientConnect();
        ServerInfoPlugin.NotExit = false;
        ServerInfoPlugin.ofThread.stop();
        Log.info("ServerInfo - Thread closed.");
        Log.debug("ServerInfo - Thread closed.");
    }

    public void setPort(String port) {
        JiveGlobals.setProperty(SERVERINFOPORT, port);
    }

    public String getPort() {
        return JiveGlobals.getProperty(SERVERINFOPORT, "4455");
    }

    public void setIP(String IP) {
        JiveGlobals.setProperty(SERVERINFOIP, IP);
    }

    public String getIP() {
        return JiveGlobals.getProperty(SERVERINFOIP, "127.0.0.1");
    }

    public void initialize(JID jid, ComponentManager componentManager) {
    }

    public void start() {
    }

    public void shutdown() {

        Log.info("ServerInfo - Shutdown thread.");
        Log.debug("ServerInfo - Shutdown thread.");
        clientConnect();
        ServerInfoPlugin.NotExit = false;
        ServerInfoPlugin.ofThread.stop();
        Log.info("ServerInfo - Thread closed.");
        Log.debug("ServerInfo - Thread closed.");
    }

    public void clientConnect() {

        try {
            Log.info("ServerInfo - Making local connection.");
            Log.debug("ServerInfo - Making local connection no port " + serverInfoPort + ".");
            Socket clientSocket = new Socket(serverInfoIP, Integer.parseInt(serverInfoPort));
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

            Log.debug("ServerInfo - Send disconnect commando to local server.");
            outToServer.writeBytes(".\n");
            clientSocket.close();
        } catch (UnknownHostException e) {

            Log.error(e.getMessage(), e);
        } catch (IOException e) {

            Log.error(e.getMessage(), e);
        }
    }

    // Component Interface

    public String getName() {

        // Get the name from the plugin.xml file.
        return pluginManager.getName(this);
    }

    public String getDescription() {

        // Get the description from the plugin.xml file.
        return pluginManager.getDescription(this);
    }

    public void processPacket(Packet packet) {

        boolean canProceed = false;
        String toNode = packet.getTo().getNode();
        boolean targetSrv = "info".equals(toNode);

        if (targetSrv) {

            JID address = new JID(packet.getFrom().toBareJID());
            canProceed = true;
        }

        if (packet instanceof Message) {

            // Respond to incoming messages
            Message message = (Message) packet;
            processMessage(message, targetSrv, canProceed);
        }

        else if (packet instanceof Presence) {

            // Respond to presence subscription request or presence probe
            Presence presence = (Presence) packet;
            processPresence(canProceed, presence);
        }

        else if (packet instanceof IQ) {

            // Handle disco packets
            IQ iq = (IQ) packet;
            // Ignore IQs of type ERROR or RESULT
            if (IQ.Type.error == iq.getType() || IQ.Type.result == iq.getType()) {

                return;
            }

            processIQ(iq, targetSrv, canProceed);
        }
    }

    private void processMessage(Message message, boolean targetSrv, boolean canProceed) {

        if (targetSrv) {

            String to = message.getFrom().toBareJID();
            String body = message.getBody();
            String xmppdomain = "@" + JiveGlobals.getProperty("xmpp.domain");

            Log.debug("ServerInfo - Message received");
            Log.debug("ServerInfo - Original message from: " + to);
            Log.debug("ServerInfo - Original message body: " + body);

            MyMessage_OF MyMsg = new MyMessage_OF();
            String text = MyMsg.returnMessage(body);

            Message newMessage = new Message();
            newMessage.setTo(to);
            newMessage.setFrom("info@serverinfo." + JiveGlobals.getProperty("xmpp.domain"));
            newMessage.setSubject("Resultado");
            newMessage.setBody(text);

            Log.debug("ServerInfo - Return message to: " + to);
            Log.debug("ServerInfo - Return message from: " + "info@serverinfo."
                    + JiveGlobals.getProperty("xmpp.domain"));
            Log.debug("ServerInfo - Return message body: " + text);

            try {

                componentManager.sendPacket(this, newMessage);
            } catch (Exception e) {

                Log.error(e.getMessage(), e);
            }
        }
    }

    private void processPresence(boolean canProceed, Presence presence) {

        try {

            if (Presence.Type.subscribe == presence.getType()) {

                // Accept all presence requests if user has permissions
                // Reply that the subscription request was approved or rejected
                Presence reply = new Presence();
                reply.setTo(presence.getFrom());
                reply.setFrom(presence.getTo());
                reply.setType(canProceed ? Presence.Type.subscribed : Presence.Type.unsubscribed);
                componentManager.sendPacket(this, reply);
            }

            else if (Presence.Type.unsubscribe == presence.getType()) {

                // Send confirmation of unsubscription
                Presence reply = new Presence();
                reply.setTo(presence.getFrom());
                reply.setFrom(presence.getTo());
                reply.setType(Presence.Type.unsubscribed);
                componentManager.sendPacket(this, reply);
            }

            else if (Presence.Type.probe == presence.getType()) {

                // Send that the service is available
                Presence reply = new Presence();
                reply.setTo(presence.getFrom());
                reply.setFrom(presence.getTo());
                componentManager.sendPacket(this, reply);
            }
        }

        catch (ComponentException e) {

            Log.error(e.getMessage(), e);
        }
    }

    private void processIQ(IQ iq, boolean targetSrv, boolean canProceed) {

        IQ reply = IQ.createResultIQ(iq);
        Element childElement = iq.getChildElement();
        String namespace = childElement.getNamespaceURI();
        Element childElementCopy = iq.getChildElement().createCopy();
        reply.setChildElement(childElementCopy);

        if ("http://jabber.org/protocol/disco#info".equals(namespace)) {

            if (iq.getTo().getNode() == null) {

                // Return service identity and features
                Element identity = childElementCopy.addElement("identity");
                identity.addAttribute("category", "component");
                identity.addAttribute("type", "generic");
                identity.addAttribute("name", "ServerInfo service");
                childElementCopy.addElement("feature").addAttribute("var", "http://jabber.org/protocol/disco#info");
                childElementCopy.addElement("feature").addAttribute("var",
                        "http://jabber.org/protocol/disco#items");
            }

            else {

                if (targetSrv) {

                    // Return identity and features of the "all" group
                    Element identity = childElementCopy.addElement("identity");
                    identity.addAttribute("category", "component");
                    identity.addAttribute("type", "generic");
                    identity.addAttribute("name", "Display requested server information");
                    childElementCopy.addElement("feature").addAttribute("var",
                            "http://jabber.org/protocol/disco#info");
                }
            }
        }

        try {

            componentManager.sendPacket(this, reply);
        } catch (Exception e) {

            Log.error(e.getMessage(), e);
        }
    }

    // Other Methods

    /**
    * Returns the service name of this component, which is "serverinfo" by default.
    *
    * @return the service name of this component.
    */
    public String getServiceName() {

        return serviceName;
    }

    /**
    * Sets the service name of this component, which is "serverinfo" by default.
    *
    * @param serviceName the service name of this component.
    */
    public void setServiceName(String serviceName) {

        JiveGlobals.setProperty("plugin.serverinfo.serviceName", serviceName);
    }

    // PropertyEventListener Methods

    public void propertySet(String property, Map<String, Object> params) {

        if (property.equals("plugin.serverinfo.serviceName")) {

            changeServiceName((String) params.get("value"));
        }
    }

    public void propertyDeleted(String property, Map<String, Object> params) {

        if (property.equals("plugin.serverinfo.serviceName")) {

            changeServiceName("serverinfo");
        }
    }

    public void xmlPropertySet(String property, Map<String, Object> params) {

        // Ignore.
    }

    public void xmlPropertyDeleted(String property, Map<String, Object> params) {

        // Ignore.
    }

    /**
    * Changes the service name to a new value.
    *
    * @param serviceName the service name.
    */
    private void changeServiceName(String serviceName) {

        if (serviceName == null) {

            throw new NullPointerException("Service name cannot be null");
        }

        if (this.serviceName.equals(serviceName)) {

            return;
        }

        // Re-register the service.
        try {

            componentManager.removeComponent(this.serviceName);
        } catch (Exception e) {

            Log.error(e.getMessage(), e);
        }

        try {

            componentManager.addComponent(serviceName, this);
        } catch (Exception e) {

            Log.error(e.getMessage(), e);
        }

        this.serviceName = serviceName;
    }
}

class OFD_Server {

    private static final String SERVERINFOPORT = "plugin.serverinfo.port";
    private static final String SERVERINFOIP = "plugin.serverinfo.ip";

    public static void main(String[] args) {

        Log.info("ServerInfo - Running startServer.");
        Log.debug("ServerInfo - Running startServer.");

        new OFD_Server().startServer();
    }

    public void startServer() {

        Runnable serverTask = new Runnable() {
            @Override
            public void run() {

                String serverInfoPort = JiveGlobals.getProperty(SERVERINFOPORT, "4455");
                String serverInfoIP = JiveGlobals.getProperty(SERVERINFOIP, "127.0.0.1");

                try {

                    Log.info("ServerInfo - Opening socket in IP " + serverInfoIP + " port " + serverInfoPort + ".");
                    Log.debug(
                            "ServerInfo - Opening socket in IP " + serverInfoIP + " port " + serverInfoPort + ".");
                    ServerSocket serverSocket = new ServerSocket(Integer.parseInt(serverInfoPort), 1,
                            InetAddress.getByName(serverInfoIP));
                    Log.info("ServerInfo - Waiting for connection.");
                    Log.debug("ServerInfo - Listen on IP " + serverInfoIP + " port " + serverInfoPort + ".");
                    Log.debug("Waiting for connection.");

                    while (ServerInfoPlugin.NotExit) {

                        Socket clientSocket = serverSocket.accept();
                        String input = "";
                        String line;

                        try {

                            // Get input from the client
                            DataInputStream in = new DataInputStream(clientSocket.getInputStream());
                            PrintStream out = new PrintStream(clientSocket.getOutputStream());

                            input = "";

                            while ((line = in.readLine()) != null && !line.equals(".")) {

                                input = input + line;
                                MyMessage_OF MyMsg = new MyMessage_OF();
                                Log.debug("ServerInfo - Receive socket message: " + input);
                                String text = MyMsg.returnMessage(input);

                                out.println(text);
                                input = "";

                                if (!ServerInfoPlugin.NotExit) {

                                    Log.info("ServerInfo - Receive signal to close thread.");
                                    Log.debug("ServerInfo - Receive signal to close thread.");
                                    break;
                                }
                            }

                            clientSocket.close();
                        } catch (IOException ioe) {

                            Log.error("ServerInfo - IOException on socket listen: " + ioe);
                            ioe.printStackTrace();
                        }

                    }

                    Log.info("ServerInfo - Thread closing.");
                    Log.debug("ServerInfo - Thread closing.");
                } catch (IOException e) {

                    Log.error("ServerInfo - Unable to process client request");
                    e.printStackTrace();
                }
            }
        };

        ServerInfoPlugin.ofThread = new Thread(serverTask);
        ServerInfoPlugin.ofThread.start();
        Log.info("ServerInfo - Thread Created.");
        Log.debug("ServerInfo - Thread Created.");

    }

}

class MyMessage_OF {

    private String msg = "";
    private int msgTot = 0;

    private UserManager userManager = UserManager.getInstance();
    private SessionManager sessionManager = SessionManager.getInstance();
    private XMPPServer xmppServer = XMPPServer.getInstance();
    private DecimalFormat mbFormat = new DecimalFormat("#0.00");
    private DecimalFormat mbIntFormat = new DecimalFormat("#0");

    public String returnMessage(String message) {

        msg = "Invalid command: " + message + ". Try again.";

        Log.debug("ServerInfo - Command: " + message + ".");

        if (message.equals("online users")) {

            msg = "";
            msgTot = sessionManager.getUserSessionsCount(true);
        }

        else if (message.equals("server sessions")) {

            msg = "";
            msgTot = sessionManager.getIncomingServerSessionsCount(true);

        }

        else if (message.equals("total users")) {

            msg = "";
            msgTot = 0;

            Collection<User> users = userManager.getUsers();

            for (User u : users) {
                msgTot = msgTot + 1;
            }

        }

        else if (message.equals("version")) {

            msg = "ServerInfo version 0.4";
        }

        else if (message.equals("openfire version")) {

            msg = "Openfire version: " + xmppServer.getServerInfo().getVersion().getVersionString();
        }

        else if (message.equals("openfire host")) {

            msg = "Openfire hostname: " + xmppServer.getServerInfo().getHostname();
        }

        else if (message.equals("openfire uptime")) {

            msg = "Openfire last started: " + xmppServer.getServerInfo().getLastStarted();
        }

        else if (message.equals("java version")) {

            msg = "Java " + System.getProperty("java.version") + " " + System.getProperty("java.vendor") + " "
                    + System.getProperty("java.vm.name");
        }

        else if (message.equals("total memory")) {

            msg = "Total available memory to the JVM: "
                    + mbFormat.format((((Runtime.getRuntime().totalMemory()) / 1024) / 1024)) + "MB";
        }

        else if (message.equals("total memory num")) {

            msg = mbIntFormat.format((((Runtime.getRuntime().totalMemory()) / 1024) / 1024));
        }

        else if (message.equals("free memory")) {

            msg = "Total free available memory to the JVM: "
                    + mbFormat.format((((Runtime.getRuntime().freeMemory()) / 1024) / 1024)) + "MB";
        }

        else if (message.equals("free memory num")) {

            msg = mbIntFormat.format((((Runtime.getRuntime().freeMemory()) / 1024) / 1024));
        }

        else if (message.equals("used memory")) {

            msg = "Total used memory by the JVM: " + mbFormat.format(
                    ((((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())) / 1024) / 1024))
                    + "MB";
        }

        else if (message.equals("used memory num")) {

            msg = mbIntFormat.format(
                    ((((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())) / 1024) / 1024));
        }

        else if (message.equals("max memory")) {

            msg = "Total maximum available memory to the JVM: "
                    + mbFormat.format((((Runtime.getRuntime().maxMemory()) / 1024) / 1024)) + "MB";
        }

        else if (message.equals("max memory num")) {

            msg = mbIntFormat.format((((Runtime.getRuntime().maxMemory()) / 1024) / 1024));
        }

        if (msg.equals("")) {

            Log.debug("ServerInfo - Return Message: " + Integer.toString(msgTot) + ".");
            return Integer.toString(msgTot);
        }

        else {

            Log.debug("ServerInfo - Return Message: " + msg + ".");
            return msg;
        }
    }
}