Package tigase.server

Source Code of tigase.server.MessageRouter

/*
* Tigase Jabber/XMPP Server
* Copyright (C) 2004-2007 "Artur Hefczyc" <artur.hefczyc@tigase.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://www.gnu.org/licenses/.
*
* $Rev: 1314 $
* Last modified by $Author: kobit $
* $Date: 2008-12-15 18:05:50 +0000 (Mon, 15 Dec 2008) $
*/

package tigase.server;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.LinkedHashSet;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.logging.Logger;
import java.util.logging.Level;
import tigase.xml.Element;
import tigase.util.JIDUtils;
import tigase.util.UpdatesChecker;
import tigase.xmpp.Authorization;
import tigase.xmpp.StanzaType;
import tigase.xmpp.PacketErrorTypeException;
import tigase.disco.XMPPService;
import tigase.disco.ServiceEntity;
import tigase.disco.ServiceIdentity;
import tigase.stats.StatRecord;

import static tigase.server.MessageRouterConfig.*;

/**
* Class MessageRouter
*
*
* Created: Tue Nov 22 07:07:11 2005
*
* @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a>
* @version $Rev: 1314 $
*/
public class MessageRouter extends AbstractMessageReceiver {
  //  implements XMPPService {

  public static final String INFO_XMLNS =
    "http://jabber.org/protocol/disco#info";
  public static final String ITEMS_XMLNS =
    "http://jabber.org/protocol/disco#items";

  private static final Logger log =
    Logger.getLogger("tigase.server.MessageRouter");

  //private static final long startupTime = System.currentTimeMillis();

//  private Set<String> localAddresses =  new CopyOnWriteArraySet<String>();
  private String disco_name = DISCO_NAME_PROP_VAL;
  private boolean disco_show_version = DISCO_SHOW_VERSION_PROP_VAL;

  private ComponentRegistrator config = null;
  private ServiceEntity serviceEntity = null;
  private UpdatesChecker updates_checker = null;

  private Map<String, XMPPService> xmppServices =
    new ConcurrentSkipListMap<String, XMPPService>();
  private Map<String, ServerComponent> components =
    new ConcurrentSkipListMap<String, ServerComponent>();
  private Map<String, ServerComponent> components_byId =
    new ConcurrentSkipListMap<String, ServerComponent>();
  private Map<String, ComponentRegistrator> registrators =
    new ConcurrentSkipListMap<String, ComponentRegistrator>();
  private Map<String, MessageReceiver> receivers =
    new ConcurrentSkipListMap<String, MessageReceiver>();

  public void processPacketMR(final Packet packet, final Queue<Packet> results) {
    if (packet.getPermissions() != Permissions.ADMIN) {
      try {
        Packet res = Authorization.NOT_AUTHORIZED.getResponseMessage(packet,
          "You are not authorized for this action.", true);
        results.offer(res);
        //processPacket(res);
      } catch (PacketErrorTypeException e) {
        log.warning("Packet processing exception: " + e);
      }
      return;
    }

    log.finest("Command received: " + packet.getStringData());
    switch (packet.getCommand()) {
    case OTHER:
      if (packet.getStrCommand() != null) {
        if (packet.getStrCommand().startsWith("controll/")) {
          String[] spl = packet.getStrCommand().split("/");
          String cmd = spl[1];
          if (cmd.equals("stop")) {
            Packet result = packet.commandResult("result");
            results.offer(result);
            //processPacket(result);
            new Timer("Stopping...", true).schedule(new TimerTask() {
                public void run() {
                  System.exit(0);
                }
              }, 2000);
          }
        }
      }
      break;
    default:
      break;
    }
  }

  @Override
  protected Integer getMaxQueueSize(int def) {
    return def*10;
  }

  private ServerComponent[] getServerComponentsForRegex(String id) {
    LinkedHashSet<ServerComponent> comps = new LinkedHashSet<ServerComponent>();
    for (MessageReceiver mr: receivers.values()) {
      if (mr.isInRegexRoutings(id)) {
        log.finest("Found receiver: " + mr.getName());
        comps.add(mr);
      }
    }
    if (comps.size() > 0) {
      return comps.toArray(new ServerComponent[comps.size()]);
    } else {
      return null;
    }
  }

  private ServerComponent getLocalComponent(String jid) {
    ServerComponent comp = components_byId.get(jid);
    if (comp != null) {
      return comp;
    }
    String host = JIDUtils.getNodeHost(jid);
    String nick = JIDUtils.getNodeNick(jid);

    if (nick != null) {
      comp = components.get(nick);
      if (comp != null &&
              (isLocalDomain(host) || host.equals(getDefHostName()))) {
        return comp;
      }
    }
    int idx = host.indexOf('.');
    if (idx > 0) {
      String cmpName = host.substring(0, idx);
      String basename = host.substring(idx + 1);
      if (comp == null) {
        comp = components.get(cmpName);
      }
      if (comp != null &&
              (isLocalDomain(basename) || basename.equals(getDefHostName()))) {
        return comp;
      }
    }
    return null;
  }

//   private String isToLocalComponent(String jid) {
//     String nick = JIDUtils.getNodeNick(jid);
//     if (nick == null) {
//       return null;
//     }
//     String host = JIDUtils.getNodeHost(jid);
//     if (isLocalDomain(host) && components.get(nick) != null) {
//       return nick;
//     }
//     return null;
//   }

//  private boolean isLocalDomain(String domain) {
//    return localAddresses.contains(domain);
//  }

  public void processPacket(Packet packet) {

    if (packet.getTo() == null) {
      log.warning("Packet with TO attribute set to NULL: "
        +  packet.getStringData());
      return;
    } // end of if (packet.getTo() == null)

    // Intentionally comparing to static, final String
    if (packet.getTo() == NULL_ROUTING) {
      log.info("NULL routing, it is normal if server doesn't know how to"
        + " process packet: " + packet.toString());
      try {
        Packet error =
          Authorization.FEATURE_NOT_IMPLEMENTED.getResponseMessage(packet,
            "Feature not supported yet.", true);
        addOutPacketNB(error);
      } catch (PacketErrorTypeException e) {
        log.warning("Packet processing exception: " + e);
      }
      return;
    }

//     if (log.isLoggable(Level.FINER)) {
//       log.finer("Processing packet: " + packet.getElemName()
//         + ", type: " + packet.getType());
//     }
    if (log.isLoggable(Level.FINEST)) {
      log.finest("Processing packet: " + packet.toString());
    }

    // Detect inifinite loop if from == to
    // Maybe it is not needed anymore...
    // There is a need to process packets with the same from and to address
    // let't try to relax restriction and block all packets with error type
    // 2008-06-16
    if ((packet.getType() == StanzaType.error &&
            packet.getFrom() != null &&
            packet.getFrom().equals(packet.getTo())) ||
            (packet.getFrom() == NULL_ROUTING &&
            packet.getElemFrom() != null &&
            packet.getElemFrom().equals(packet.getTo()))) {
      log.warning("Possible infinite loop, dropping packet: "
        + packet.toString());
      return;
    }

    ServerComponent comp = packet.getElemTo() == null ? null
      : getLocalComponent(packet.getElemTo());
    if (packet.isServiceDisco() && packet.getType() != null &&
            packet.getType() == StanzaType.get &&
            ((comp != null && !(comp instanceof DisableDisco)) ||
            isLocalDomain(packet.getElemTo()))) {
      log.finest("Processing disco query by: " + getComponentId());
      Queue<Packet> results = new LinkedList<Packet>();
      processDiscoQuery(packet, results);
      if (results.size() > 0) {
        for (Packet res: results) {
          // No more recurrential calls!!
          addOutPacketNB(res);
        } // end of for ()
      }
      return;
    }
    String id =  JIDUtils.getNodeID(packet.getTo());
    comp = getLocalComponent(id);
    if (comp != null) {
      log.finest("Packet is processing by: " + comp.getComponentId());
      Queue<Packet> results = new LinkedList<Packet>();
      if (comp == this) {
        processPacketMR(packet, results);
      } else {
        comp.processPacket(packet, results);
      }
      if (results.size() > 0) {
        for (Packet res: results) {
          // No more recurrential calls!!
          addOutPacketNB(res);
          //          processPacket(res);
        } // end of for ()
      }
      return;
    }

    // Let's try to find message receiver quick way
    // In case if packet is handled internally:
//    String nick = JIDUtils.getNodeNick(packet.getTo());
    String host = JIDUtils.getNodeHost(packet.getTo());
//    MessageReceiver first = null;
    // Below code probably never get's executed anyway.
    // All components included in commented code below should
    // be picked up by code above.
//    if (nick != null) {
//      first = receivers.get(nick);
//    } // end of if (nick != null)
//    if (first != null && host.equals(getDefHostName())) {
//      log.finest("Found receiver: " + first.getName());
//      first.addPacketNB(packet);
//      return;
//    } // end of if (mr != null)
    // This packet is not processed localy, so let's find receiver
    // which will send it to correct destination:

    ServerComponent[] comps = getComponentsForLocalDomain(host);
    if (comps == null) {
      comps = getServerComponentsForRegex(id);
    }
    if (comps == null && !isLocalDomain(host)) {
      comps = getComponentsForNonLocalDomain(host);
    }
    if (comps != null) {
      Queue<Packet> results = new LinkedList<Packet>();
      for (ServerComponent serverComponent : comps) {
        log.finest("Packet processed by: " +
                serverComponent.getComponentId());
        serverComponent.processPacket(packet, results);
        if (results.size() > 0) {
          for (Packet res : results) {
            // No more recurrential calls!!
            addOutPacketNB(res);
          //          processPacket(res);
          } // end of for ()
        }
      }
    } else {
      log.finest("There is no component for the packet, sending it back");
      try {
        addOutPacketNB(
          Authorization.SERVICE_UNAVAILABLE.getResponseMessage(packet,
            "There is no service found to process your request.", true));
      } catch (PacketErrorTypeException e) {
        // This packet is to local domain, we don't want to send it out
        // drop packet :-(
        log.warning("Can't process packet to local domain, dropping..."
          + packet.toString());
      }
    }

//    MessageReceiver s2s = null;
//    for (MessageReceiver mr: receivers.values()) {
//      Set<String> routings = mr.getRoutings();
//      if (routings != null) {
//        log.finest(mr.getName() + ": Looking for host: " + host +
//          " in " + routings.toString());
//        if (routings.contains(host) || routings.contains(id)) {
//          log.finest("Found receiver: " + mr.getName());
//          mr.addPacketNB(packet);
//          return;
//        } // end of if (routings.contains())
//        // Resolve wildchars routings....
//        if (mr.isInRegexRoutings(id)) {
//          log.finest("Found receiver: " + mr.getName());
//          mr.addPacketNB(packet);
//          return;
//        }
//        if (routings.contains("*")) {
//          // I found s2s receiver, remember it for later....
//          s2s = mr;
//        } // end of if (routings.contains())
//      } // end of if (routings != null)
//      else {
//        log.severe("Routings are null for: " + mr.getName());
//      } // end of if (routings != null) else
//    } // end of for (MessageReceiver mr: receivers.values())
//    // It is not for any local host, so maybe it is for some
//    // remote server, let's try sending it through s2s service:
//    if (localAddresses.contains(host) || comp != null) {
//      try {
//        addOutPacketNB(
//          Authorization.FEATURE_NOT_IMPLEMENTED.getResponseMessage(packet,
//            "Your request can not be processed.", true));
//      } catch (PacketErrorTypeException e) {
//        // This packet is to local domain, we don't want to send it out
//        // drop packet :-(
//        log.warning("Can't process packet to local domain, dropping..."
//          + packet.toString());
//      }
//      return;
//    }
//    if (s2s != null) {
//      s2s.addPacketNB(packet);
//    } // end of if (s2s != null)
  }

  private ServerComponent[] getComponentsForLocalDomain(String domain) {
    return vHostManager.getComponentsForLocalDomain(domain);
  }

  private ServerComponent[] getComponentsForNonLocalDomain(String domain) {
    return vHostManager.getComponentsForNonLocalDomain(domain);
  }

  public void setConfig(ComponentRegistrator config) {
    components.put(getName(), this);
    this.config = config;
    addRegistrator(config);
  }

  public void addRegistrator(ComponentRegistrator registr) {
    log.info("Adding registrator: " + registr.getClass().getSimpleName());
    registrators.put(registr.getName(), registr);
    addComponent(registr);
    for (ServerComponent comp : components.values()) {
      //       if (comp != registr) {
      registr.addComponent(comp);
      //       } // end of if (comp != registr)
    } // end of for (ServerComponent comp : components)
  }

  public void addRouter(MessageReceiver receiver) {
    log.info("Adding receiver: " + receiver.getClass().getSimpleName());
    addComponent(receiver);
    receivers.put(receiver.getName(), receiver);
  }

  public void addComponent(ServerComponent component) {
    log.info("Adding component: " + component.getClass().getSimpleName());
    for (ComponentRegistrator registr : registrators.values()) {
      if (registr != component) {
        log.finer("Adding: " + component.getName() + " component to "
          + registr.getName() + " registrator.");
        registr.addComponent(component);
      } // end of if (reg != component)
    } // end of for ()
    components.put(component.getName(), component);
    components_byId.put(component.getComponentId(), component);
    if (component instanceof XMPPService) {
      xmppServices.put(component.getName(), (XMPPService)component);
    }
  }

  @Override
  public Map<String, Object> getDefaults(Map<String, Object> params) {
    Map<String, Object> defs = super.getDefaults(params);
    MessageRouterConfig.getDefaults(defs, params, getName());
    return defs;
  }

  private boolean inProperties = false;
  @Override
  public void setProperties(Map<String, Object> props) {

    if (inProperties) {
      return;
    } else {
      inProperties = true;
    } // end of if (inProperties) else

    disco_name = (String)props.get(DISCO_NAME_PROP_KEY);
    disco_show_version = (Boolean)props.get(DISCO_SHOW_VERSION_PROP_KEY);

    serviceEntity = new ServiceEntity("Tigase", "server", "Session manager");
    serviceEntity.addIdentities(new ServiceIdentity[] {
        new ServiceIdentity("server", "im", disco_name +
          (disco_show_version ?
            (" ver. " + tigase.server.XMPPServer.getImplementationVersion())
            : ""))});
    serviceEntity.addFeatures(XMPPService.DEF_FEATURES);

    try {
      super.setProperties(props);
//      String[] localAddresses = (String[])props.get(LOCAL_ADDRESSES_PROP_KEY);
//      this.localAddresses.clear();
//      if (localAddresses != null && localAddresses.length > 0) {
//        Collections.addAll(this.localAddresses, localAddresses);
//        this.localAddresses.add(getDefHostName());
//      }
      Map<String, ComponentRegistrator> tmp_reg = registrators;
      Map<String, MessageReceiver> tmp_rec = receivers;
      components = new TreeMap<String, ServerComponent>();
      registrators = new TreeMap<String, ComponentRegistrator>();
      receivers = new TreeMap<String, MessageReceiver>();
      setConfig(config);

      MessageRouterConfig conf = new MessageRouterConfig(props);
      String[] reg_names = conf.getRegistrNames();
      for (String name: reg_names) {
        ComponentRegistrator cr = tmp_reg.remove(name);
        String cls_name =
          (String)props.get(REGISTRATOR_PROP_KEY + name + ".class");
        try {
          if (cr == null || !cr.getClass().getName().equals(cls_name)) {
            if (cr != null) {
              cr.release();
            }
            cr = conf.getRegistrInstance(name);
            cr.setName(name);
          } // end of if (cr == null)
          addRegistrator(cr);
        } // end of try
        catch (Exception e) {
          e.printStackTrace();
        } // end of try-catch
      } // end of for (String name: reg_names)
      for (ComponentRegistrator cr: tmp_reg.values()) {
        cr.release();
      } // end of for ()
      tmp_reg.clear();

      String[] msgrcv_names = conf.getMsgRcvNames();
      for (String name: msgrcv_names) {
        log.finer("Loading and registering message receiver: " + name);
        ServerComponent mr = tmp_rec.remove(name);
        String cls_name =
          (String)props.get(MSG_RECEIVERS_PROP_KEY + name + ".class");
        try {
          if (mr == null || !mr.getClass().getName().equals(cls_name)) {
            if (mr != null) {
              mr.release();
            }
            mr = conf.getMsgRcvInstance(name);
            mr.setName(name);
            if (mr instanceof MessageReceiver) {
              ((MessageReceiver)mr).setParent(this);
              ((MessageReceiver)mr).start();
            }
          } // end of if (cr == null)
          if (mr instanceof MessageReceiver) {
            addRouter((MessageReceiver)mr);
          } else {
            addComponent(mr);
          }
        } // end of try
        catch (Exception e) {
          e.printStackTrace();
        } // end of try-catch
      } // end of for (String name: reg_names)
      for (MessageReceiver mr: tmp_rec.values()) {
        mr.release();
      } // end of for ()
      tmp_rec.clear();
      if ((Boolean)props.get(UPDATES_CHECKING_PROP_KEY)) {
        installUpdatesChecker((Long)props.get(UPDATES_CHECKING_INTERVAL_PROP_KEY));
      } else {
        stopUpdatesChecker();
      }
    } finally {
      inProperties = false;
    } // end of try-finally
    for (ServerComponent comp : components.values()) {
      log.info("Initialization completed.");
      comp.initializationCompleted();
    }
  }

  private void stopUpdatesChecker() {
    if (updates_checker != null) {
      updates_checker.interrupt();
      updates_checker = null;
    }
  }

  private void installUpdatesChecker(long interval) {
    stopUpdatesChecker();
    updates_checker = new UpdatesChecker(interval, this,
      "This is automated message generated by updates checking module.\n"
      + " You can disable this function changing configuration option: "
      + "'/" + getName() + "/" + UPDATES_CHECKING_PROP_KEY + "' or adjust"
      + " updates checking interval time changing option: "
      + "'/" + getName() + "/" + UPDATES_CHECKING_INTERVAL_PROP_KEY + "' which"
      + " now set to " + interval + " days.");
    updates_checker.start();
  }

  private void processDiscoQuery(final Packet packet,
    final Queue<Packet> results) {
      String jid = packet.getElemTo();
      String nick = JIDUtils.getNodeNick(jid);
      String node = packet.getAttribute("/iq/query", "node");
      Element query = packet.getElement().getChild("query").clone();

      if (packet.isXMLNS("/iq/query", INFO_XMLNS)) {
        if (isLocalDomain(jid)) {
          query = getDiscoInfo(node, jid);
          for (XMPPService comp: xmppServices.values()) {
            List<Element> features = comp.getDiscoFeatures();
            if (features != null) {
              query.addChildren(features);
            }
          } // end of for ()
        } else {
          for (XMPPService comp: xmppServices.values()) {
            //            if (jid.startsWith(comp.getName() + ".")) {
              Element resp = comp.getDiscoInfo(node, jid);
              if (resp != null) {
                query = resp;
                break;
              }
              //            }
          } // end of for ()
        }
      }

      if (packet.isXMLNS("/iq/query", ITEMS_XMLNS)) {
        boolean localDomain = isLocalDomain(jid);
        if (localDomain) {
          for (XMPPService comp: xmppServices.values()) {
            //  if (localDomain || (nick != null && comp.getName().equals(nick))) {
            List<Element> items =  comp.getDiscoItems(node, jid);
            log.finest("DiscoItems processed by: " + comp.getComponentId()
              + ", items: " + (items == null ? null : items.toString()));
            if (items != null && items.size() > 0) {
              query.addChildren(items);
            }
          } // end of for ()
        } else {
          ServerComponent comp = getLocalComponent(packet.getElemTo());
          if (comp != null && comp instanceof XMPPService) {
            List<Element> items = ((XMPPService)comp).getDiscoItems(node, jid);
            log.finest("DiscoItems processed by: " + comp.getComponentId()
              + ", items: " + (items == null ? null : items.toString()));
            if (items != null && items.size() > 0) {
              query.addChildren(items);
            }
          }
        }
      }
      results.offer(packet.okResult(query, 0));
  }


  public Element getDiscoInfo(String node, String jid) {
    Element query = serviceEntity.getDiscoInfo(null);
    log.finest("Returing disco-info: " + query.toString());
    return query;
  }

  public List<Element> getDiscoItems(String node, String jid) {
    return null;
  }

  @Override
  public List<StatRecord> getStatistics() {
    List<StatRecord> stats = super.getStatistics();
    long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
    long days = uptime / (24 * HOUR);
    long hours = (uptime - (days * 24 * HOUR)) / HOUR;
    long minutes = (uptime - (days * 24 * HOUR + hours * HOUR)) / MINUTE;
    long seconds =
      (uptime - (days * 24 * HOUR + hours * HOUR + minutes * MINUTE)) / SECOND;
    //    StringBuilder sb = new StringBuilder();
    stats.add(new StatRecord(getName(), "Uptime", "time"""
        + (days > 0 ? days + " day, " : "")
        + (hours > 0 ? hours + " hour, " : "")
        + (minutes > 0 ? minutes + " min, " : "")
        + (seconds > 0 ? seconds + " sec" : "")
        , Level.INFO));
//    Runtime runtime = Runtime.getRuntime();
    // Run GC for more accurate memory readings
    //runtime.gc();
//    long maxMem = runtime.maxMemory();
//    long totalMem = runtime.totalMemory();
//    long freeMem = runtime.freeMemory();
//    stats.add(new StatRecord(getName(), "Max JVM mem", "long", maxMem,
//        Level.FINEST));
//    stats.add(new StatRecord(getName(), "Total JVM mem", "long", totalMem,
//        Level.FINEST));
//    stats.add(new StatRecord(getName(), "Free JVM mem", "long", freeMem,
//        Level.FINEST));

    OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
    NumberFormat format = NumberFormat.getNumberInstance();
    format.setMaximumFractionDigits(4);
    stats.add(new StatRecord(getName(), "Load average", "double",
            format.format(osBean.getSystemLoadAverage()), Level.INFO));
    stats.add(new StatRecord(getName(), "CPUs no", "int",
            osBean.getAvailableProcessors(), Level.FINEST));

    ThreadMXBean thBean = ManagementFactory.getThreadMXBean();
    stats.add(new StatRecord(getName(), "Threads count", "int",
            thBean.getThreadCount(), Level.FINEST));
    long cpuTime = 0;
    for (long thid : thBean.getAllThreadIds()) {
      cpuTime += thBean.getThreadCpuTime(thid);
    }
//    stats.add(new StatRecord(getName(), "Threads CPU time", "long", cpuTime,
//        Level.FINEST));
    double cpuUsage = (new Long(cpuTime).doubleValue() / 1000000) / new Long(
            uptime).doubleValue();
    format = NumberFormat.getPercentInstance();
    format.setMaximumFractionDigits(2);
    stats.add(new StatRecord(getName(), "CPU usage", "double",
            format.format(cpuUsage), Level.INFO));
    MemoryUsage heap = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
    MemoryUsage nonHeap =
            ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();

    format = NumberFormat.getIntegerInstance();
    if (format instanceof DecimalFormat) {
      DecimalFormat decf = (DecimalFormat)format;
      decf.applyPattern(decf.toPattern()+" KB");
    }
    stats.add(new StatRecord(getName(), "Max Heap mem", "long",
            format.format(heap.getMax()/1024), Level.INFO));
    stats.add(new StatRecord(getName(), "Used Heap", "long",
            format.format(heap.getUsed()/1024), Level.INFO));
    stats.add(new StatRecord(getName(), "Free Heap", "long",
            format.format((heap.getMax() - heap.getUsed())/1024), Level.INFO));
    stats.add(new StatRecord(getName(), "Max NonHeap mem", "long",
            format.format(nonHeap.getMax()/1024), Level.INFO));
    stats.add(new StatRecord(getName(), "Used NonHeap", "long",
            format.format(nonHeap.getUsed()/1024), Level.INFO));
    stats.add(new StatRecord(getName(), "Free NonHeap", "long",
            format.format((nonHeap.getMax() - nonHeap.getUsed())/1024), Level.INFO));

    return stats;
  }

}
TOP

Related Classes of tigase.server.MessageRouter

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.