Home » openjdk-7 » javax » management » monitor » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.management.monitor;
   27   
   28   import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER;
   29   import java.util.logging.Level;
   30   import javax.management.ObjectName;
   31   import javax.management.MBeanNotificationInfo;
   32   import static javax.management.monitor.Monitor.NumericalType.*;
   33   import static javax.management.monitor.MonitorNotification.*;
   34   
   35   /**
   36    * Defines a monitor MBean designed to observe the values of a counter
   37    * attribute.
   38    *
   39    * <P> A counter monitor sends a {@link
   40    * MonitorNotification#THRESHOLD_VALUE_EXCEEDED threshold
   41    * notification} when the value of the counter reaches or exceeds a
   42    * threshold known as the comparison level.  The notify flag must be
   43    * set to <CODE>true</CODE>.
   44    *
   45    * <P> In addition, an offset mechanism enables particular counting
   46    * intervals to be detected.  If the offset value is not zero,
   47    * whenever the threshold is triggered by the counter value reaching a
   48    * comparison level, that comparison level is incremented by the
   49    * offset value.  This is regarded as taking place instantaneously,
   50    * that is, before the count is incremented.  Thus, for each level,
   51    * the threshold triggers an event notification every time the count
   52    * increases by an interval equal to the offset value.
   53    *
   54    * <P> If the counter can wrap around its maximum value, the modulus
   55    * needs to be specified.  The modulus is the value at which the
   56    * counter is reset to zero.
   57    *
   58    * <P> If the counter difference mode is used, the value of the
   59    * derived gauge is calculated as the difference between the observed
   60    * counter values for two successive observations.  If this difference
   61    * is negative, the value of the derived gauge is incremented by the
   62    * value of the modulus.  The derived gauge value (V[t]) is calculated
   63    * using the following method:
   64    *
   65    * <UL>
   66    * <LI>if (counter[t] - counter[t-GP]) is positive then
   67    * V[t] = counter[t] - counter[t-GP]
   68    * <LI>if (counter[t] - counter[t-GP]) is negative then
   69    * V[t] = counter[t] - counter[t-GP] + MODULUS
   70    * </UL>
   71    *
   72    * This implementation of the counter monitor requires the observed
   73    * attribute to be of the type integer (<CODE>Byte</CODE>,
   74    * <CODE>Integer</CODE>, <CODE>Short</CODE>, <CODE>Long</CODE>).
   75    *
   76    *
   77    * @since 1.5
   78    */
   79   public class CounterMonitor extends Monitor implements CounterMonitorMBean {
   80   
   81       /*
   82        * ------------------------------------------
   83        *  PACKAGE CLASSES
   84        * ------------------------------------------
   85        */
   86   
   87       static class CounterMonitorObservedObject extends ObservedObject {
   88   
   89           public CounterMonitorObservedObject(ObjectName observedObject) {
   90               super(observedObject);
   91           }
   92   
   93           public final synchronized Number getThreshold() {
   94               return threshold;
   95           }
   96           public final synchronized void setThreshold(Number threshold) {
   97               this.threshold = threshold;
   98           }
   99           public final synchronized Number getPreviousScanCounter() {
  100               return previousScanCounter;
  101           }
  102           public final synchronized void setPreviousScanCounter(
  103                                                     Number previousScanCounter) {
  104               this.previousScanCounter = previousScanCounter;
  105           }
  106           public final synchronized boolean getModulusExceeded() {
  107               return modulusExceeded;
  108           }
  109           public final synchronized void setModulusExceeded(
  110                                                    boolean modulusExceeded) {
  111               this.modulusExceeded = modulusExceeded;
  112           }
  113           public final synchronized Number getDerivedGaugeExceeded() {
  114               return derivedGaugeExceeded;
  115           }
  116           public final synchronized void setDerivedGaugeExceeded(
  117                                                    Number derivedGaugeExceeded) {
  118               this.derivedGaugeExceeded = derivedGaugeExceeded;
  119           }
  120           public final synchronized boolean getDerivedGaugeValid() {
  121               return derivedGaugeValid;
  122           }
  123           public final synchronized void setDerivedGaugeValid(
  124                                                    boolean derivedGaugeValid) {
  125               this.derivedGaugeValid = derivedGaugeValid;
  126           }
  127           public final synchronized boolean getEventAlreadyNotified() {
  128               return eventAlreadyNotified;
  129           }
  130           public final synchronized void setEventAlreadyNotified(
  131                                                  boolean eventAlreadyNotified) {
  132               this.eventAlreadyNotified = eventAlreadyNotified;
  133           }
  134           public final synchronized NumericalType getType() {
  135               return type;
  136           }
  137           public final synchronized void setType(NumericalType type) {
  138               this.type = type;
  139           }
  140   
  141           private Number threshold;
  142           private Number previousScanCounter;
  143           private boolean modulusExceeded;
  144           private Number derivedGaugeExceeded;
  145           private boolean derivedGaugeValid;
  146           private boolean eventAlreadyNotified;
  147           private NumericalType type;
  148       }
  149   
  150       /*
  151        * ------------------------------------------
  152        *  PRIVATE VARIABLES
  153        * ------------------------------------------
  154        */
  155   
  156       /**
  157        * Counter modulus.
  158        * <BR>The default value is a null Integer object.
  159        */
  160       private Number modulus = INTEGER_ZERO;
  161   
  162       /**
  163        * Counter offset.
  164        * <BR>The default value is a null Integer object.
  165        */
  166       private Number offset = INTEGER_ZERO;
  167   
  168       /**
  169        * Flag indicating if the counter monitor notifies when exceeding
  170        * the threshold.  The default value is set to
  171        * <CODE>false</CODE>.
  172        */
  173       private boolean notify = false;
  174   
  175       /**
  176        * Flag indicating if the counter difference mode is used.  If the
  177        * counter difference mode is used, the derived gauge is the
  178        * difference between two consecutive observed values.  Otherwise,
  179        * the derived gauge is directly the value of the observed
  180        * attribute.  The default value is set to <CODE>false</CODE>.
  181        */
  182       private boolean differenceMode = false;
  183   
  184       /**
  185        * Initial counter threshold.  This value is used to initialize
  186        * the threshold when a new object is added to the list and reset
  187        * the threshold to its initial value each time the counter
  188        * resets.
  189        */
  190       private Number initThreshold = INTEGER_ZERO;
  191   
  192       private static final String[] types = {
  193           RUNTIME_ERROR,
  194           OBSERVED_OBJECT_ERROR,
  195           OBSERVED_ATTRIBUTE_ERROR,
  196           OBSERVED_ATTRIBUTE_TYPE_ERROR,
  197           THRESHOLD_ERROR,
  198           THRESHOLD_VALUE_EXCEEDED
  199       };
  200   
  201       private static final MBeanNotificationInfo[] notifsInfo = {
  202           new MBeanNotificationInfo(
  203               types,
  204               "javax.management.monitor.MonitorNotification",
  205               "Notifications sent by the CounterMonitor MBean")
  206       };
  207   
  208       /*
  209        * ------------------------------------------
  210        *  CONSTRUCTORS
  211        * ------------------------------------------
  212        */
  213   
  214       /**
  215        * Default constructor.
  216        */
  217       public CounterMonitor() {
  218       }
  219   
  220       /*
  221        * ------------------------------------------
  222        *  PUBLIC METHODS
  223        * ------------------------------------------
  224        */
  225   
  226       /**
  227        * Starts the counter monitor.
  228        */
  229       public synchronized void start() {
  230           if (isActive()) {
  231               MONITOR_LOGGER.logp(Level.FINER, CounterMonitor.class.getName(),
  232                       "start", "the monitor is already active");
  233               return;
  234           }
  235           // Reset values.
  236           //
  237           for (ObservedObject o : observedObjects) {
  238               final CounterMonitorObservedObject cmo =
  239                   (CounterMonitorObservedObject) o;
  240               cmo.setThreshold(initThreshold);
  241               cmo.setModulusExceeded(false);
  242               cmo.setEventAlreadyNotified(false);
  243               cmo.setPreviousScanCounter(null);
  244           }
  245           doStart();
  246       }
  247   
  248       /**
  249        * Stops the counter monitor.
  250        */
  251       public synchronized void stop() {
  252           doStop();
  253       }
  254   
  255       // GETTERS AND SETTERS
  256       //--------------------
  257   
  258       /**
  259        * Gets the derived gauge of the specified object, if this object is
  260        * contained in the set of observed MBeans, or <code>null</code> otherwise.
  261        *
  262        * @param object the name of the object whose derived gauge is to
  263        * be returned.
  264        *
  265        * @return The derived gauge of the specified object.
  266        *
  267        */
  268       @Override
  269       public synchronized Number getDerivedGauge(ObjectName object) {
  270           return (Number) super.getDerivedGauge(object);
  271       }
  272   
  273       /**
  274        * Gets the derived gauge timestamp of the specified object, if
  275        * this object is contained in the set of observed MBeans, or
  276        * <code>0</code> otherwise.
  277        *
  278        * @param object the name of the object whose derived gauge
  279        * timestamp is to be returned.
  280        *
  281        * @return The derived gauge timestamp of the specified object.
  282        *
  283        */
  284       @Override
  285       public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
  286           return super.getDerivedGaugeTimeStamp(object);
  287       }
  288   
  289       /**
  290        * Gets the current threshold value of the specified object, if
  291        * this object is contained in the set of observed MBeans, or
  292        * <code>null</code> otherwise.
  293        *
  294        * @param object the name of the object whose threshold is to be
  295        * returned.
  296        *
  297        * @return The threshold value of the specified object.
  298        *
  299        */
  300       public synchronized Number getThreshold(ObjectName object) {
  301           final CounterMonitorObservedObject o =
  302               (CounterMonitorObservedObject) getObservedObject(object);
  303           if (o == null)
  304               return null;
  305   
  306           // If the counter that is monitored rolls over when it reaches a
  307           // maximum value, then the modulus value needs to be set to that
  308           // maximum value. The threshold will then also roll over whenever
  309           // it strictly exceeds the modulus value. When the threshold rolls
  310           // over, it is reset to the value that was specified through the
  311           // latest call to the monitor's setInitThreshold method, before
  312           // any offsets were applied.
  313           //
  314           if (offset.longValue() > 0L &&
  315               modulus.longValue() > 0L &&
  316               o.getThreshold().longValue() > modulus.longValue()) {
  317               return initThreshold;
  318           } else {
  319               return o.getThreshold();
  320           }
  321       }
  322   
  323       /**
  324        * Gets the initial threshold value common to all observed objects.
  325        *
  326        * @return The initial threshold.
  327        *
  328        * @see #setInitThreshold
  329        *
  330        */
  331       public synchronized Number getInitThreshold() {
  332           return initThreshold;
  333       }
  334   
  335       /**
  336        * Sets the initial threshold value common to all observed objects.
  337        *
  338        * <BR>The current threshold of every object in the set of
  339        * observed MBeans is updated consequently.
  340        *
  341        * @param value The initial threshold value.
  342        *
  343        * @exception IllegalArgumentException The specified
  344        * threshold is null or the threshold value is less than zero.
  345        *
  346        * @see #getInitThreshold
  347        *
  348        */
  349       public synchronized void setInitThreshold(Number value)
  350           throws IllegalArgumentException {
  351   
  352           if (value == null) {
  353               throw new IllegalArgumentException("Null threshold");
  354           }
  355           if (value.longValue() < 0L) {
  356               throw new IllegalArgumentException("Negative threshold");
  357           }
  358   
  359           if (initThreshold.equals(value))
  360               return;
  361           initThreshold = value;
  362   
  363           // Reset values.
  364           //
  365           int index = 0;
  366           for (ObservedObject o : observedObjects) {
  367               resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
  368               final CounterMonitorObservedObject cmo =
  369                   (CounterMonitorObservedObject) o;
  370               cmo.setThreshold(value);
  371               cmo.setModulusExceeded(false);
  372               cmo.setEventAlreadyNotified(false);
  373           }
  374       }
  375   
  376       /**
  377        * Returns the derived gauge of the first object in the set of
  378        * observed MBeans.
  379        *
  380        * @return The derived gauge.
  381        *
  382        * @deprecated As of JMX 1.2, replaced by
  383        * {@link #getDerivedGauge(ObjectName)}
  384        */
  385       @Deprecated
  386       public synchronized Number getDerivedGauge() {
  387           if (observedObjects.isEmpty()) {
  388               return null;
  389           } else {
  390               return (Number) observedObjects.get(0).getDerivedGauge();
  391           }
  392       }
  393   
  394       /**
  395        * Gets the derived gauge timestamp of the first object in the set
  396        * of observed MBeans.
  397        *
  398        * @return The derived gauge timestamp.
  399        *
  400        * @deprecated As of JMX 1.2, replaced by
  401        * {@link #getDerivedGaugeTimeStamp(ObjectName)}
  402        */
  403       @Deprecated
  404       public synchronized long getDerivedGaugeTimeStamp() {
  405           if (observedObjects.isEmpty()) {
  406               return 0;
  407           } else {
  408               return observedObjects.get(0).getDerivedGaugeTimeStamp();
  409           }
  410       }
  411   
  412       /**
  413        * Gets the threshold value of the first object in the set of
  414        * observed MBeans.
  415        *
  416        * @return The threshold value.
  417        *
  418        * @see #setThreshold
  419        *
  420        * @deprecated As of JMX 1.2, replaced by {@link #getThreshold(ObjectName)}
  421        */
  422       @Deprecated
  423       public synchronized Number getThreshold() {
  424           return getThreshold(getObservedObject());
  425       }
  426   
  427       /**
  428        * Sets the initial threshold value.
  429        *
  430        * @param value The initial threshold value.
  431        *
  432        * @exception IllegalArgumentException The specified threshold is
  433        * null or the threshold value is less than zero.
  434        *
  435        * @see #getThreshold()
  436        *
  437        * @deprecated As of JMX 1.2, replaced by {@link #setInitThreshold}
  438        */
  439       @Deprecated
  440       public synchronized void setThreshold(Number value)
  441           throws IllegalArgumentException {
  442           setInitThreshold(value);
  443       }
  444   
  445       /**
  446        * Gets the offset value common to all observed MBeans.
  447        *
  448        * @return The offset value.
  449        *
  450        * @see #setOffset
  451        */
  452       public synchronized Number getOffset() {
  453           return offset;
  454       }
  455   
  456       /**
  457        * Sets the offset value common to all observed MBeans.
  458        *
  459        * @param value The offset value.
  460        *
  461        * @exception IllegalArgumentException The specified
  462        * offset is null or the offset value is less than zero.
  463        *
  464        * @see #getOffset
  465        */
  466       public synchronized void setOffset(Number value)
  467           throws IllegalArgumentException {
  468   
  469           if (value == null) {
  470               throw new IllegalArgumentException("Null offset");
  471           }
  472           if (value.longValue() < 0L) {
  473               throw new IllegalArgumentException("Negative offset");
  474           }
  475   
  476           if (offset.equals(value))
  477               return;
  478           offset = value;
  479   
  480           int index = 0;
  481           for (ObservedObject o : observedObjects) {
  482               resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
  483           }
  484       }
  485   
  486       /**
  487        * Gets the modulus value common to all observed MBeans.
  488        *
  489        * @see #setModulus
  490        *
  491        * @return The modulus value.
  492        */
  493       public synchronized Number getModulus() {
  494           return modulus;
  495       }
  496   
  497       /**
  498        * Sets the modulus value common to all observed MBeans.
  499        *
  500        * @param value The modulus value.
  501        *
  502        * @exception IllegalArgumentException The specified
  503        * modulus is null or the modulus value is less than zero.
  504        *
  505        * @see #getModulus
  506        */
  507       public synchronized void setModulus(Number value)
  508           throws IllegalArgumentException {
  509   
  510           if (value == null) {
  511               throw new IllegalArgumentException("Null modulus");
  512           }
  513           if (value.longValue() < 0L) {
  514               throw new IllegalArgumentException("Negative modulus");
  515           }
  516   
  517           if (modulus.equals(value))
  518               return;
  519           modulus = value;
  520   
  521           // Reset values.
  522           //
  523           int index = 0;
  524           for (ObservedObject o : observedObjects) {
  525               resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
  526               final CounterMonitorObservedObject cmo =
  527                   (CounterMonitorObservedObject) o;
  528               cmo.setModulusExceeded(false);
  529           }
  530       }
  531   
  532       /**
  533        * Gets the notification's on/off switch value common to all
  534        * observed MBeans.
  535        *
  536        * @return <CODE>true</CODE> if the counter monitor notifies when
  537        * exceeding the threshold, <CODE>false</CODE> otherwise.
  538        *
  539        * @see #setNotify
  540        */
  541       public synchronized boolean getNotify() {
  542           return notify;
  543       }
  544   
  545       /**
  546        * Sets the notification's on/off switch value common to all
  547        * observed MBeans.
  548        *
  549        * @param value The notification's on/off switch value.
  550        *
  551        * @see #getNotify
  552        */
  553       public synchronized void setNotify(boolean value) {
  554           if (notify == value)
  555               return;
  556           notify = value;
  557       }
  558   
  559       /**
  560        * Gets the difference mode flag value common to all observed MBeans.
  561        *
  562        * @return <CODE>true</CODE> if the difference mode is used,
  563        * <CODE>false</CODE> otherwise.
  564        *
  565        * @see #setDifferenceMode
  566        */
  567       public synchronized boolean getDifferenceMode() {
  568           return differenceMode;
  569       }
  570   
  571       /**
  572        * Sets the difference mode flag value common to all observed MBeans.
  573        *
  574        * @param value The difference mode flag value.
  575        *
  576        * @see #getDifferenceMode
  577        */
  578       public synchronized void setDifferenceMode(boolean value) {
  579           if (differenceMode == value)
  580               return;
  581           differenceMode = value;
  582   
  583           // Reset values.
  584           //
  585           for (ObservedObject o : observedObjects) {
  586               final CounterMonitorObservedObject cmo =
  587                   (CounterMonitorObservedObject) o;
  588               cmo.setThreshold(initThreshold);
  589               cmo.setModulusExceeded(false);
  590               cmo.setEventAlreadyNotified(false);
  591               cmo.setPreviousScanCounter(null);
  592           }
  593       }
  594   
  595       /**
  596        * Returns a <CODE>NotificationInfo</CODE> object containing the
  597        * name of the Java class of the notification and the notification
  598        * types sent by the counter monitor.
  599        */
  600       @Override
  601       public MBeanNotificationInfo[] getNotificationInfo() {
  602           return notifsInfo.clone();
  603       }
  604   
  605       /*
  606        * ------------------------------------------
  607        *  PRIVATE METHODS
  608        * ------------------------------------------
  609        */
  610   
  611       /**
  612        * Updates the derived gauge attribute of the observed object.
  613        *
  614        * @param scanCounter The value of the observed attribute.
  615        * @param o The observed object.
  616        * @return <CODE>true</CODE> if the derived gauge value is valid,
  617        * <CODE>false</CODE> otherwise.  The derived gauge value is
  618        * invalid when the differenceMode flag is set to
  619        * <CODE>true</CODE> and it is the first notification (so we
  620        * haven't 2 consecutive values to update the derived gauge).
  621        */
  622       private synchronized boolean updateDerivedGauge(
  623           Object scanCounter, CounterMonitorObservedObject o) {
  624   
  625           boolean is_derived_gauge_valid;
  626   
  627           // The counter difference mode is used.
  628           //
  629           if (differenceMode) {
  630   
  631               // The previous scan counter has been initialized.
  632               //
  633               if (o.getPreviousScanCounter() != null) {
  634                   setDerivedGaugeWithDifference((Number)scanCounter, null, o);
  635   
  636                   // If derived gauge is negative it means that the
  637                   // counter has wrapped around and the value of the
  638                   // threshold needs to be reset to its initial value.
  639                   //
  640                   if (((Number)o.getDerivedGauge()).longValue() < 0L) {
  641                       if (modulus.longValue() > 0L) {
  642                           setDerivedGaugeWithDifference((Number)scanCounter,
  643                                                         modulus, o);
  644                       }
  645                       o.setThreshold(initThreshold);
  646                       o.setEventAlreadyNotified(false);
  647                   }
  648                   is_derived_gauge_valid = true;
  649               }
  650               // The previous scan counter has not been initialized.
  651               // We cannot update the derived gauge...
  652               //
  653               else {
  654                   is_derived_gauge_valid = false;
  655               }
  656               o.setPreviousScanCounter((Number)scanCounter);
  657           }
  658           // The counter difference mode is not used.
  659           //
  660           else {
  661               o.setDerivedGauge((Number)scanCounter);
  662               is_derived_gauge_valid = true;
  663           }
  664           return is_derived_gauge_valid;
  665       }
  666   
  667       /**
  668        * Updates the notification attribute of the observed object
  669        * and notifies the listeners only once if the notify flag
  670        * is set to <CODE>true</CODE>.
  671        * @param o The observed object.
  672        */
  673       private synchronized MonitorNotification updateNotifications(
  674           CounterMonitorObservedObject o) {
  675   
  676           MonitorNotification n = null;
  677   
  678           // Send notification if notify is true.
  679           //
  680           if (!o.getEventAlreadyNotified()) {
  681               if (((Number)o.getDerivedGauge()).longValue() >=
  682                   o.getThreshold().longValue()) {
  683                   if (notify) {
  684                       n = new MonitorNotification(THRESHOLD_VALUE_EXCEEDED,
  685                                                   this,
  686                                                   0,
  687                                                   0,
  688                                                   "",
  689                                                   null,
  690                                                   null,
  691                                                   null,
  692                                                   o.getThreshold());
  693                   }
  694                   if (!differenceMode) {
  695                       o.setEventAlreadyNotified(true);
  696                   }
  697               }
  698           } else {
  699               if (MONITOR_LOGGER.isLoggable(Level.FINER)) {
  700                   final StringBuilder strb = new StringBuilder()
  701                   .append("The notification:")
  702                   .append("\n\tNotification observed object = ")
  703                   .append(o.getObservedObject())
  704                   .append("\n\tNotification observed attribute = ")
  705                   .append(getObservedAttribute())
  706                   .append("\n\tNotification threshold level = ")
  707                   .append(o.getThreshold())
  708                   .append("\n\tNotification derived gauge = ")
  709                   .append(o.getDerivedGauge())
  710                   .append("\nhas already been sent");
  711                   MONITOR_LOGGER.logp(Level.FINER, CounterMonitor.class.getName(),
  712                           "updateNotifications", strb.toString());
  713               }
  714           }
  715   
  716           return n;
  717       }
  718   
  719       /**
  720        * Updates the threshold attribute of the observed object.
  721        * @param o The observed object.
  722        */
  723       private synchronized void updateThreshold(CounterMonitorObservedObject o) {
  724   
  725           // Calculate the new threshold value if the threshold has been
  726           // exceeded and if the offset value is greater than zero.
  727           //
  728           if (((Number)o.getDerivedGauge()).longValue() >=
  729               o.getThreshold().longValue()) {
  730   
  731               if (offset.longValue() > 0L) {
  732   
  733                   // Increment the threshold until its value is greater
  734                   // than the one for the current derived gauge.
  735                   //
  736                   long threshold_value = o.getThreshold().longValue();
  737                   while (((Number)o.getDerivedGauge()).longValue() >=
  738                          threshold_value) {
  739                       threshold_value += offset.longValue();
  740                   }
  741   
  742                   // Set threshold attribute.
  743                   //
  744                   switch (o.getType()) {
  745                       case INTEGER:
  746                           o.setThreshold(Integer.valueOf((int)threshold_value));
  747                           break;
  748                       case BYTE:
  749                           o.setThreshold(Byte.valueOf((byte)threshold_value));
  750                           break;
  751                       case SHORT:
  752                           o.setThreshold(Short.valueOf((short)threshold_value));
  753                           break;
  754                       case LONG:
  755                           o.setThreshold(Long.valueOf(threshold_value));
  756                           break;
  757                       default:
  758                           // Should never occur...
  759                           MONITOR_LOGGER.logp(Level.FINEST,
  760                                   CounterMonitor.class.getName(),
  761                                   "updateThreshold",
  762                                   "the threshold type is invalid");
  763                           break;
  764                   }
  765   
  766                   // If the counter can wrap around when it reaches
  767                   // its maximum and we are not dealing with counter
  768                   // differences then we need to reset the threshold
  769                   // to its initial value too.
  770                   //
  771                   if (!differenceMode) {
  772                       if (modulus.longValue() > 0L) {
  773                           if (o.getThreshold().longValue() >
  774                               modulus.longValue()) {
  775                               o.setModulusExceeded(true);
  776                               o.setDerivedGaugeExceeded(
  777                                   (Number) o.getDerivedGauge());
  778                           }
  779                       }
  780                   }
  781   
  782                   // Threshold value has been modified so we can notify again.
  783                   //
  784                   o.setEventAlreadyNotified(false);
  785               } else {
  786                   o.setModulusExceeded(true);
  787                   o.setDerivedGaugeExceeded((Number) o.getDerivedGauge());
  788               }
  789           }
  790       }
  791   
  792       /**
  793        * Sets the derived gauge of the specified observed object when the
  794        * differenceMode flag is set to <CODE>true</CODE>.  Integer types
  795        * only are allowed.
  796        *
  797        * @param scanCounter The value of the observed attribute.
  798        * @param mod The counter modulus value.
  799        * @param o The observed object.
  800        */
  801       private synchronized void setDerivedGaugeWithDifference(
  802           Number scanCounter, Number mod, CounterMonitorObservedObject o) {
  803           /* We do the arithmetic using longs here even though the
  804              result may end up in a smaller type.  Since
  805              l == (byte)l (mod 256) for any long l,
  806              (byte) ((byte)l1 + (byte)l2) == (byte) (l1 + l2),
  807              and likewise for subtraction.  So it's the same as if
  808              we had done the arithmetic in the smaller type.*/
  809   
  810           long derived =
  811               scanCounter.longValue() - o.getPreviousScanCounter().longValue();
  812           if (mod != null)
  813               derived += modulus.longValue();
  814   
  815           switch (o.getType()) {
  816           case INTEGER: o.setDerivedGauge(Integer.valueOf((int) derived)); break;
  817           case BYTE: o.setDerivedGauge(Byte.valueOf((byte) derived)); break;
  818           case SHORT: o.setDerivedGauge(Short.valueOf((short) derived)); break;
  819           case LONG: o.setDerivedGauge(Long.valueOf(derived)); break;
  820           default:
  821               // Should never occur...
  822               MONITOR_LOGGER.logp(Level.FINEST, CounterMonitor.class.getName(),
  823                       "setDerivedGaugeWithDifference",
  824                       "the threshold type is invalid");
  825               break;
  826           }
  827       }
  828   
  829       /*
  830        * ------------------------------------------
  831        *  PACKAGE METHODS
  832        * ------------------------------------------
  833        */
  834   
  835       /**
  836        * Factory method for ObservedObject creation.
  837        *
  838        * @since 1.6
  839        */
  840       @Override
  841       ObservedObject createObservedObject(ObjectName object) {
  842           final CounterMonitorObservedObject cmo =
  843               new CounterMonitorObservedObject(object);
  844           cmo.setThreshold(initThreshold);
  845           cmo.setModulusExceeded(false);
  846           cmo.setEventAlreadyNotified(false);
  847           cmo.setPreviousScanCounter(null);
  848           return cmo;
  849       }
  850   
  851       /**
  852        * This method globally sets the derived gauge type for the given
  853        * "object" and "attribute" after checking that the type of the
  854        * supplied observed attribute value is one of the value types
  855        * supported by this monitor.
  856        */
  857       @Override
  858       synchronized boolean isComparableTypeValid(ObjectName object,
  859                                                  String attribute,
  860                                                  Comparable<?> value) {
  861           final CounterMonitorObservedObject o =
  862               (CounterMonitorObservedObject) getObservedObject(object);
  863           if (o == null)
  864               return false;
  865   
  866           // Check that the observed attribute is of type "Integer".
  867           //
  868           if (value instanceof Integer) {
  869               o.setType(INTEGER);
  870           } else if (value instanceof Byte) {
  871               o.setType(BYTE);
  872           } else if (value instanceof Short) {
  873               o.setType(SHORT);
  874           } else if (value instanceof Long) {
  875               o.setType(LONG);
  876           } else {
  877               return false;
  878           }
  879           return true;
  880       }
  881   
  882       @Override
  883       synchronized Comparable<?> getDerivedGaugeFromComparable(
  884                                                     ObjectName object,
  885                                                     String attribute,
  886                                                     Comparable<?> value) {
  887           final CounterMonitorObservedObject o =
  888               (CounterMonitorObservedObject) getObservedObject(object);
  889           if (o == null)
  890               return null;
  891   
  892           // Check if counter has wrapped around.
  893           //
  894           if (o.getModulusExceeded()) {
  895               if (((Number)o.getDerivedGauge()).longValue() <
  896                   o.getDerivedGaugeExceeded().longValue()) {
  897                       o.setThreshold(initThreshold);
  898                       o.setModulusExceeded(false);
  899                       o.setEventAlreadyNotified(false);
  900               }
  901           }
  902   
  903           // Update the derived gauge attributes and check the
  904           // validity of the new value. The derived gauge value
  905           // is invalid when the differenceMode flag is set to
  906           // true and it is the first notification, i.e. we
  907           // haven't got 2 consecutive values to update the
  908           // derived gauge.
  909           //
  910           o.setDerivedGaugeValid(updateDerivedGauge(value, o));
  911   
  912           return (Comparable<?>) o.getDerivedGauge();
  913       }
  914   
  915       @Override
  916       synchronized void onErrorNotification(MonitorNotification notification) {
  917           final CounterMonitorObservedObject o = (CounterMonitorObservedObject)
  918               getObservedObject(notification.getObservedObject());
  919           if (o == null)
  920               return;
  921   
  922           // Reset values.
  923           //
  924           o.setModulusExceeded(false);
  925           o.setEventAlreadyNotified(false);
  926           o.setPreviousScanCounter(null);
  927       }
  928   
  929       @Override
  930       synchronized MonitorNotification buildAlarmNotification(
  931                                                  ObjectName object,
  932                                                  String attribute,
  933                                                  Comparable<?> value) {
  934           final CounterMonitorObservedObject o =
  935               (CounterMonitorObservedObject) getObservedObject(object);
  936           if (o == null)
  937               return null;
  938   
  939           // Notify the listeners and update the threshold if
  940           // the updated derived gauge value is valid.
  941           //
  942           final MonitorNotification alarm;
  943           if (o.getDerivedGaugeValid()) {
  944               alarm = updateNotifications(o);
  945               updateThreshold(o);
  946           } else {
  947               alarm = null;
  948           }
  949           return alarm;
  950       }
  951   
  952       /**
  953        * Tests if the threshold, offset and modulus of the specified observed
  954        * object are of the same type as the counter. Only integer types are
  955        * allowed.
  956        *
  957        * Note:
  958        *   If the optional offset or modulus have not been initialized, their
  959        *   default value is an Integer object with a value equal to zero.
  960        *
  961        * @param object The observed object.
  962        * @param attribute The observed attribute.
  963        * @param value The sample value.
  964        * @return <CODE>true</CODE> if type is the same,
  965        * <CODE>false</CODE> otherwise.
  966        */
  967       @Override
  968       synchronized boolean isThresholdTypeValid(ObjectName object,
  969                                                 String attribute,
  970                                                 Comparable<?> value) {
  971           final CounterMonitorObservedObject o =
  972               (CounterMonitorObservedObject) getObservedObject(object);
  973           if (o == null)
  974               return false;
  975   
  976           Class<? extends Number> c = classForType(o.getType());
  977           return (c.isInstance(o.getThreshold()) &&
  978                   isValidForType(offset, c) &&
  979                   isValidForType(modulus, c));
  980       }
  981   }

Home » openjdk-7 » javax » management » monitor » [javadoc | source]