Package com.sun.messaging.jmq.jmsserver.core

Source Code of com.sun.messaging.jmq.jmsserver.core.BrokerMetricsMonitor

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

/*
* @(#)BrokerMonitor.java  1.31 06/28/07
*/

package com.sun.messaging.jmq.jmsserver.core;

import com.sun.messaging.jmq.util.DestType;
import com.sun.messaging.jmq.util.timer.*;
import com.sun.messaging.jmq.util.selector.*;
import com.sun.messaging.jmq.jmsserver.util.*;
import com.sun.messaging.jmq.util.log.*;
import com.sun.messaging.jmq.io.*;
import com.sun.messaging.jmq.jmsserver.Globals;
import com.sun.messaging.jmq.util.admin.MessageType;
import com.sun.messaging.jmq.jmsserver.config.ConfigListener;
import com.sun.messaging.jmq.jmsserver.resources.BrokerResources;
import com.sun.messaging.jmq.jmsserver.config.PropertyUpdateException;
import com.sun.messaging.jmq.jmsserver.config.BrokerConfig;
import java.util.*;
import java.io.*;
import java.net.*;



public class BrokerMonitor
{
    private static final long    DEFAULT_INTERVAL  = 60;
    private static final boolean  DEFAULT_PERSIST    = false;
    private static final long    DEFAULT_TTL    = 5 * DEFAULT_INTERVAL;
    private static final boolean  DEFAULT_ENABLED    = true;

    /*
     * Broker monitoring property names
     */
    private static String METRICS_PROP_PREFIX =
        Globals.IMQ + ".metrics.topic.";

    private static String METRICS_TIME_PROP =
  METRICS_PROP_PREFIX + "interval";

    private static String PERSIST_PROP =
  METRICS_PROP_PREFIX + "persist";

    private static String TTL_PROP =
  METRICS_PROP_PREFIX + "timetolive";

    private static String ENABLED_PROP =
  METRICS_PROP_PREFIX + "enabled";

    /*
     * Broker monitoring property values
     */
    public static long METRICS_TIME =
         Globals.getConfig().getLongProperty(
             METRICS_TIME_PROP,
             DEFAULT_INTERVAL) * 1000;

    public static boolean PERSIST =
         Globals.getConfig().getBooleanProperty(
             PERSIST_PROP, DEFAULT_PERSIST);

    public static long TTL =
         Globals.getConfig().getLongProperty(
             TTL_PROP, DEFAULT_TTL) * 1000;

    public static boolean ENABLED =
         Globals.getConfig().getBooleanProperty(
             ENABLED_PROP, DEFAULT_ENABLED);

    private static MQTimer timer = Globals.getTimer();

    Logger logger = Globals.getLogger();

    Monitor monitor = null;

    private static HashSet active = new HashSet();

    private static TimerTask task = null;

    boolean valid = true;
    boolean started = false;

    public static void shutdownMonitor() {
        if (task != null)
            task.cancel();
        active.clear();
  BrokerConfig cfg = Globals.getConfig();
  cfg.removeListener(METRICS_TIME_PROP, cl);
  cfg.removeListener(PERSIST_PROP, cl);
  cfg.removeListener(TTL_PROP, cl);
        cl = null;
    }

    private static ConfigListener cl = new ConfigListener()  {
        public void validate(String name, String value)
          throws PropertyUpdateException {
        }
           
        public boolean update(String name, String value) {
            BrokerConfig cfg = Globals.getConfig();

            if (name.equals(METRICS_TIME_PROP))  {
          METRICS_TIME = Globals.getConfig().getLongProperty(
                  METRICS_TIME_PROP, DEFAULT_INTERVAL) * 1000;

                synchronized (active) {
                    if (task != null) {
           task.cancel();
                       task = new NotificationTask();
                       try {
                           timer.schedule(task, METRICS_TIME, METRICS_TIME);
                       } catch (IllegalStateException ex) {
                           Globals.getLogger().log(Logger.INFO,"Internal Error: Shutting down metrics, timer has been canceled", ex);
                       }
                    }
                }
     
            } else if (name.equals(PERSIST_PROP))  {
                PERSIST = Globals.getConfig().getBooleanProperty(
                 PERSIST_PROP, DEFAULT_PERSIST);
            } else if (name.equals(TTL_PROP))  {
                TTL = Globals.getConfig().getLongProperty(
                 TTL_PROP, DEFAULT_TTL) * 1000;
            } else if (name.equals(ENABLED_PROP))  {
                ENABLED = Globals.getConfig().getBooleanProperty(
                 ENABLED_PROP, DEFAULT_ENABLED);
      }

            return true;
        }
    };
  
    static class NotificationTask extends TimerTask
    {
        public void run() {
            Iterator itr = null;
            synchronized(active) {
                itr = (new HashSet(active)).iterator();
            }
            while (itr.hasNext()) {
                Monitor m = (Monitor)itr.next();
                m.run();
            }
        }
    }

    public static void init()  {
  /*
   * The static listener 'cl' updates the
   * static variables METRICS_TIME, PERSIST,
   * and TTL when their corresponding
   * properties are updated.
   */
  BrokerConfig cfg = Globals.getConfig();
  cfg.addListener(METRICS_TIME_PROP, cl);
  cfg.addListener(PERSIST_PROP, cl);
  cfg.addListener(TTL_PROP, cl);
  cfg.addListener(ENABLED_PROP, cl);
    }

    public BrokerMonitor(Destination d)
        throws IllegalArgumentException, BrokerException
    {
        monitor = createMonitor(d);
    }



    public static boolean isInternal(String dest)
    {
        return DestType.destNameIsInternal(dest);
    }


    public void start() {
        synchronized (this) {
            if (!valid)  {
                return;
            }
            if (!started) {
                started = true;
            } else {
                return;
            }
        }
        synchronized (active) {
            active.add(monitor);
            if (task == null) {
               task = new NotificationTask();
               try {
                   timer.schedule(task, METRICS_TIME, METRICS_TIME);
               } catch (IllegalStateException ex) {
                   logger.log(Logger.INFO,"InternalError: Shutting down metrics, timer has been canceled", ex);
               }
            }
        }
    }

    public void stop() {
        synchronized (this) {
            if (!valid) return;
            if (started) {
                started = false;
            } else {
                return;
            }
        }
        synchronized (active) {
            active.remove(monitor);
            if (active.size() == 0) {
               task.cancel();
               task = null;
            }
        }
    }

    public void destroy() {
        stop();
        synchronized(this) {
            valid = false;
            started = false;
            monitor = null;
        }
    }

    private Monitor createMonitor(Destination d)
        throws IllegalArgumentException, BrokerException
    {
        String destination = d.getDestinationName();

        //parse it
        if (!DestType.destNameIsInternal(destination)) {
            throw new IllegalArgumentException("Illegal Internal Name"
                 + destination);
        }
        String substring = destination.substring(
                  DestType.INTERNAL_DEST_PREFIX.length());

        StringTokenizer tk = new StringTokenizer(
                 substring, ".");

        if (!tk.hasMoreElements()) {
            throw new IllegalArgumentException("Missing type "
                + " for monitoring " + destination);
        }

        String type=(String)tk.nextElement();

        if (!type.equals("metrics")) {
            throw new IllegalArgumentException("Illegal type " + type
               + " for monitoring. Only Metrics is valid ["
                  + destination + "]");
        }
        if (!tk.hasMoreElements()) {
            throw new IllegalArgumentException("Missing area "
                + " for monitoring " + destination);
        }
        String area=(String)tk.nextElement();

        // parse
        if (area.equals("broker")) {
            if (tk.hasMoreElements()) {
                throw new IllegalArgumentException("Bad name "
                    + " for broker monitoring " + destination
                    + " should be " + DestType.INTERNAL_DEST_PREFIX
                    + "broker");
            }

            monitor = new BrokerMetricsMonitor(d);
           
        } else if (area.equals("jvm")) {
            if (tk.hasMoreElements()) {
                throw new IllegalArgumentException("Bad name "
                    + " for broker monitoring " + destination
                    + " should be " + DestType.INTERNAL_DEST_PREFIX
                    + "jvm");
            }
            monitor = new JVMMonitor(d);

        } else if (area.equals("destination")) {
            if (!tk.hasMoreElements()) {
                throw new IllegalArgumentException(
        "Missing destination type or list for broker destination monitoring "
      + destination);
            }

            String destArea=(String)tk.nextElement();

      if (destArea.equals("queue")) {
                if (!tk.hasMoreElements()) {
                    throw new IllegalArgumentException("Missing name "
                    + " for broker queue monitoring " + destination);
                }
                String prefix = "metrics.destination.queue.";
                String name = substring.substring(prefix.length());
                DestinationUID duid =DestinationUID.getUID(name, true);
                if (!Destination.canAutoCreate(true) &&
                     (Destination.getDestination(duid) == null)) {
                    throw new BrokerException(
                       Globals.getBrokerResources().getKString(
                           BrokerResources.E_MONITOR_DEST_DISALLOWED,
                           duid.getName(),
                           duid.getDestType()),Status.FORBIDDEN);
                }
              

                monitor = new DestMonitor(d, duid);

            } else if (destArea.equals("topic")) {
                if (!tk.hasMoreElements()) {
                    throw new IllegalArgumentException("Missing name "
                    + " for broker topic monitoring " + destination);
                }
                String prefix = "metrics.destination.topic.";
                String name = substring.substring(prefix.length());
                DestinationUID duid =DestinationUID.getUID(name, false);
                if (!Destination.canAutoCreate(false) &&
                     (Destination.getDestination(duid) == null)) {
                    throw new BrokerException(
                       Globals.getBrokerResources().getKString(
                           BrokerResources.E_MONITOR_DEST_DISALLOWED,
                           duid.getName(),
                           duid.getDestType()),Status.FORBIDDEN);
                }
                monitor = new DestMonitor(d, duid);
            }
        } else if (area.equals("destination_list")) {
                monitor = new DestListMonitor(d);
        } else {
            throw new IllegalArgumentException("Illegal area "
                + area + " for monitoring " + destination);
        }
        return monitor;

    }


    public void updateNewConsumer(Consumer c) {
        monitor.writeToSpecificMonitorConsumer(c);
    }
    

}



abstract class Monitor
{
    Destination d = null;

    public Monitor(Destination d)
    {
        this.d = d;
    }

    protected abstract Hashtable getMonitorData();


    public void run() {
        Packet p = new Packet(false);
  Hashtable entries = getMonitorData();

  if (entries == null)  {
      return;
  }

        if (writeMap(p, entries, d.getDestinationName())) {
          
            try {
                PacketReference ref = PacketReference.createReference(
                     p, null);
                d.queueMessage(ref, false);
                Set s = d.routeNewMessage(ref);
                d.forwardMessage(s, ref);
            } catch (BrokerException ex) {
                Globals.getLogger().log(Logger.DEBUG,"Unable to writeMap for "
               + " metrics" + d, ex);
            } catch (SelectorFormatException ex) {
                Globals.getLogger().log(Logger.DEBUG,"Internal Error ", ex);
            }
        } else {
            Globals.getLogger().log(Logger.DEBUG,"Unable to writeMap for "
               + " metrics" + d);
        }
    }

    public void writeToSpecificMonitorConsumer(Consumer c)
    {
        Packet p = new Packet(true);
  Hashtable entries = getMonitorData();

  if (entries == null)  {
      return;
  }
        if (c == null) {
            return;
        }

        if (writeMap(p, entries, d.getDestinationName())) {
            try {
                PacketReference ref = PacketReference.createReference(
                     p, null);
                d.queueMessage(ref, false);
                ArrayList arl = new ArrayList(1);
                arl.add(c);
                ref.store(arl);
                c.routeMessage(ref, false);
            } catch (BrokerException ex) {
                Globals.getLogger().log(Logger.DEBUG,"Unable to writeMap for "
               + " metrics " + d + " : targeted for " + c.getConsumerUID(), ex);
            }
        } else {
            Globals.getLogger().log(Logger.DEBUG,"Unable to writeMap for "
               + " metrics" + d+ " : targeted for " + c.getConsumerUID());
        }
    }

    private static boolean writeMap(Packet pkt, Hashtable entries,
             String destination)
    {
        try {

            // write header information
            Hashtable props = new Hashtable();
      Long curTime = new Long(System.currentTimeMillis());

            props.put("type",destination);
            props.put("timestamp", curTime);

      MQAddress addr = Globals.getMQAddress();
            props.put("brokerAddress", addr.toString());
            props.put("brokerHost", addr.getHostName());
            props.put("brokerPort", new Integer(addr.getPort()));

            pkt.setProperties(props);
            pkt.setPacketType(PacketType.MAP_MESSAGE);
            pkt.setDestination(destination);
            pkt.setPriority(5);
            pkt.setIP(InetAddress.getLocalHost().getAddress());
            pkt.updateSequenceNumber();
            pkt.updateTimestamp();
            pkt.generateSequenceNumber(false);
            pkt.generateTimestamp(false);

            // should also set port, but I'm not sure how
            pkt.setIsQueue(false);
            pkt.setTransactionID(0);
            pkt.setSendAcknowledge(false);
            pkt.setPersistent(BrokerMonitor.PERSIST);
            pkt.setExpiration(BrokerMonitor.TTL == 0 ? (long)0
                   : (curTime.longValue()
                      + BrokerMonitor.TTL));
                 

            ByteArrayOutputStream byteArrayOutputStream =
                    new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream =
                    new ObjectOutputStream(byteArrayOutputStream);

            objectOutputStream.writeObject(entries);
            objectOutputStream.flush();
            byteArrayOutputStream.flush();

            byte[] messageBody = byteArrayOutputStream.toByteArray();

            objectOutputStream.close();
            byteArrayOutputStream.close();
            pkt.setMessageBody(messageBody);

            return true;
        } catch (Exception e) {
            Globals.getLogger().log(Logger.ERROR,
               "Error sending metrics data",e);
            return false;
        }
    }

}

class JVMMonitor extends Monitor
{
    public JVMMonitor(Destination d) {
        super(d);
    }

    protected Hashtable getMonitorData() {

        Hashtable mapMessage = new Hashtable();

        MetricManager mm = Globals.getMetricManager();
        MetricData md = mm.getMetrics();
        mapMessage.put("freeMemory",
               new Long(md.freeMemory));
        mapMessage.put("maxMemory",
               new Long(Runtime.getRuntime().maxMemory()));
        mapMessage.put("totalMemory",
               new Long(md.totalMemory));

        return mapMessage;
    }
}

class DestListMonitor extends Monitor
{
    public DestListMonitor(Destination d) {
         super(d);
    }

    protected Hashtable getMonitorData() {

        Hashtable mapMessages = new Hashtable();

  Iterator itr = Destination.getAllDestinations();
  while (itr.hasNext()) {
      Destination oneDest = (Destination)itr.next();
      Hashtable values;
      String key;

      if (oneDest.isInternal() ||
    oneDest.isAdmin() ||
          (oneDest.getDestinationName().equals(MessageType.JMQ_ADMIN_DEST)) ||
            (oneDest.getDestinationName().equals(MessageType.JMQ_BRIDGE_ADMIN_DEST)))  {
    continue;
      }

      values = new Hashtable();

      if (oneDest.isQueue())  {
          key = "mq.metrics.destination.queue." + oneDest.getDestinationName();
          values.put("type", "queue");
      } else  {
          key = "mq.metrics.destination.topic." + oneDest.getDestinationName();
          values.put("type", "topic");
      }

      values.put("name", oneDest.getDestinationName());
      values.put("isTemporary", Boolean.valueOf(oneDest.isTemporary()));
     
      mapMessages.put(key, values);
  }

        return mapMessages;
    }
}

class DestMonitor extends Monitor
{
    DestinationUID target = null;

    public DestMonitor(Destination d,
         DestinationUID target) {
         super(d);
         this.target = target;
    }

    protected Hashtable getMonitorData() {

  if (target == null)  {
      return (null);
  }

        Destination td = Destination.getDestination(target);

  if (td == null)  {
      return (null);
  }

        Hashtable values = new Hashtable(td.getMetrics());
        return values;
    }
       

}

class BrokerMetricsMonitor extends Monitor
{

    public BrokerMetricsMonitor(Destination d) {
        super(d);
    }

    protected Hashtable getMonitorData() {

        Hashtable mapMessage = new Hashtable();

        MetricManager mm = Globals.getMetricManager();
        MetricData md = mm.getMetrics();
        mapMessage.put("numConnections",
               new Long((long)md.nConnections));
        mapMessage.put("numMsgsIn",
               new Long((long)md.totals.messagesIn));
        mapMessage.put("numMsgsOut",
               new Long((long)md.totals.messagesOut));
        mapMessage.put("numMsgs",
               new Long((long)Destination.totalCount()));

        mapMessage.put("msgBytesIn",
               new Long((long)md.totals.messageBytesIn));
        mapMessage.put("msgBytesOut",
               new Long((long)md.totals.messageBytesOut));
        mapMessage.put("numPktsIn",
               new Long((long)md.totals.packetsIn));
        mapMessage.put("numPktsOut",
               new Long((long)md.totals.packetsOut));
        mapMessage.put("pktBytesIn",
               new Long((long)md.totals.packetBytesIn));
        mapMessage.put("pktBytesOut",
               new Long((long)md.totals.packetBytesOut));

        mapMessage.put("totalMsgBytes",
               new Long(Destination.totalBytes()));

  /*
   * Calculate number of destinations.
   * We cannot use Destination.destinationsSize() here because
   * that includes all destinations. We need to filter out
   * internal/admin destinations - basically what is returned
   * by DestListMonitor.
   */
  Iterator itr = Destination.getAllDestinations();
  long numDests = 0;
  while (itr.hasNext()) {
      Destination oneDest = (Destination)itr.next();

      if (oneDest.isInternal() ||
    oneDest.isAdmin() ||
          (oneDest.getDestinationName().equals(MessageType.JMQ_BRIDGE_ADMIN_DEST)) ||
          (oneDest.getDestinationName().equals(MessageType.JMQ_ADMIN_DEST)))  {
    continue;
      }
      numDests++;
  }

        mapMessage.put("numDestinations", new Long(numDests));

        return mapMessage;
    }
}
TOP

Related Classes of com.sun.messaging.jmq.jmsserver.core.BrokerMetricsMonitor

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.