1 /*
   2  * Copyright (c) 2004, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4981829
  27  * @summary Test that the counter monitor, when running in difference mode,
  28  *          emits a notification every time the threshold is exceeded.
  29  * @author Luis-Miguel Alventosa
  30  * @run clean CounterMonitorTest
  31  * @run build CounterMonitorTest
  32  * @run main CounterMonitorTest
  33  */
  34 
  35 import javax.management.*;
  36 import javax.management.monitor.*;
  37 
  38 public class CounterMonitorTest implements NotificationListener {
  39 
  40     // threshold number
  41     private Number threshold = new Integer(2);
  42 
  43     // modulus number
  44     private Number modulus = new Integer(7);
  45 
  46     // offset number
  47     private int offset = 0;
  48 
  49     // difference mode flag
  50     private boolean differenceModeFlag = true;
  51 
  52     // notify flag
  53     private boolean notifyFlag = true;
  54 
  55     // granularity period
  56     private int granularityperiod = 500;
  57 
  58     // counter values
  59     private int[] values = new int[] {4, 6, 9, 11};
  60 
  61     // time to wait for notification (in seconds)
  62     private int timeout = 5;
  63 
  64     // flag to notify that a message has been received
  65     private volatile boolean messageReceived = false;
  66 
  67     // MBean class
  68     public class StdObservedObject implements StdObservedObjectMBean {
  69         public Object getNbObjects() {
  70             return count;
  71         }
  72         public void setNbObjects(Object n) {
  73             count = n;
  74         }
  75         private Object count= null;
  76     }
  77 
  78     // MBean interface
  79     public interface StdObservedObjectMBean {
  80         public Object getNbObjects();
  81         public void setNbObjects(Object n);
  82     }
  83 
  84     // Notification handler
  85     public void handleNotification(Notification notification,
  86                                    Object handback) {
  87         MonitorNotification n = (MonitorNotification) notification;
  88         echo("\tInside handleNotification...");
  89         String type = n.getType();
  90         try {
  91             if (type.equals(MonitorNotification.THRESHOLD_VALUE_EXCEEDED)) {
  92                 echo("\t\t" + n.getObservedAttribute() +
  93                      " has reached or exceeded the threshold");
  94                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
  95                 messageReceived = true;
  96                 synchronized (this) {
  97                     notifyAll();
  98                 }
  99             } else {
 100                 echo("\t\tSkipping notification of type: " + type);
 101             }
 102         } catch (Exception e) {
 103             echo("\tError in handleNotification!");
 104             e.printStackTrace(System.out);
 105         }
 106     }
 107 
 108     /**
 109      * Update the counter and check for notifications
 110      */
 111     public void thresholdNotification() throws Exception {
 112 
 113         CounterMonitor counterMonitor = new CounterMonitor();
 114         try {
 115             MBeanServer server = MBeanServerFactory.newMBeanServer();
 116 
 117             String domain = server.getDefaultDomain();
 118 
 119             // Create a new CounterMonitor MBean and add it to the MBeanServer.
 120             //
 121             echo(">>> CREATE a new CounterMonitor MBean");
 122             ObjectName counterMonitorName = new ObjectName(
 123                             domain + ":type=" + CounterMonitor.class.getName());
 124             server.registerMBean(counterMonitor, counterMonitorName);
 125 
 126             echo(">>> ADD a listener to the CounterMonitor");
 127             counterMonitor.addNotificationListener(this, null, null);
 128 
 129             //
 130             // MANAGEMENT OF A STANDARD MBEAN
 131             //
 132 
 133             echo(">>> CREATE a new StdObservedObject MBean");
 134 
 135             ObjectName stdObsObjName =
 136                 new ObjectName(domain + ":type=StdObservedObject");
 137             StdObservedObject stdObsObj = new StdObservedObject();
 138             server.registerMBean(stdObsObj, stdObsObjName);
 139 
 140             echo(">>> SET the attributes of the CounterMonitor:");
 141 
 142             counterMonitor.addObservedObject(stdObsObjName);
 143             echo("\tATTRIBUTE \"ObservedObject\"    = " + stdObsObjName);
 144 
 145             counterMonitor.setObservedAttribute("NbObjects");
 146             echo("\tATTRIBUTE \"ObservedAttribute\" = NbObjects");
 147 
 148             counterMonitor.setNotify(notifyFlag);
 149             echo("\tATTRIBUTE \"Notify\"            = " + notifyFlag);
 150 
 151             counterMonitor.setInitThreshold(threshold);
 152             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
 153 
 154             counterMonitor.setGranularityPeriod(granularityperiod);
 155             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 156 
 157             counterMonitor.setModulus(modulus);
 158             echo("\tATTRIBUTE \"Modulus\"           = " + modulus);
 159 
 160             counterMonitor.setDifferenceMode(differenceModeFlag);
 161             echo("\tATTRIBUTE \"DifferenceMode\"    = " + differenceModeFlag);
 162 
 163             echo(">>> START the CounterMonitor");
 164             counterMonitor.start();
 165 
 166             // Set initial value
 167             //
 168             Integer data = new Integer(0);
 169             echo(">>> Set data = " + data.intValue());
 170 
 171             Attribute attrib = new Attribute("NbObjects", data);
 172             server.setAttribute(stdObsObjName, attrib);
 173 
 174             // Wait for granularity period (multiplied by 2 for sure)
 175             //
 176             Thread.sleep(granularityperiod * 2);
 177 
 178             // Loop through the values
 179             //
 180             for (int i = 0; i < values.length; i++) {
 181                 data = new Integer(values[i]);
 182                 echo(">>> Set data = " + data.intValue());
 183 
 184                 attrib = new Attribute("NbObjects", data);
 185                 server.setAttribute(stdObsObjName, attrib);
 186 
 187                 echo("\tdoWait in Counter Monitor");
 188                 doWait();
 189 
 190                 // Check if notification was received
 191                 //
 192                 if (messageReceived) {
 193                     echo("\tOKAY: Notification received");
 194                 } else {
 195                     echo("\tError: notification missed or not emitted");
 196                     throw new IllegalStateException("Notification lost");
 197                 }
 198                 messageReceived = false;
 199             }
 200         } finally {
 201             counterMonitor.stop();
 202         }
 203 
 204         echo(">>> Bye! Bye!");
 205     }
 206 
 207     /*
 208      * Wait until timeout reached
 209      */
 210     void doWait() {
 211         for (int i = 0; i < timeout; i++) {
 212             echo("\tdoWait: Waiting for " + timeout + " seconds. " +
 213                  "i = " + i + ", messageReceived = " + messageReceived);
 214             if (messageReceived) {
 215                 break;
 216             }
 217             try {
 218                 synchronized (this) {
 219                     wait(1000);
 220                 }
 221             } catch (InterruptedException e) {
 222                 // OK: Ignore...
 223             }
 224         }
 225     }
 226 
 227     /*
 228      * Print message
 229      */
 230     void echo(String message) {
 231         System.out.println(message);
 232     }
 233 
 234     /*
 235      * Standalone entry point.
 236      *
 237      * Run the test and report to stdout.
 238      */
 239     public static void main (String args[]) throws Exception {
 240         CounterMonitorTest test = new CounterMonitorTest();
 241         test.thresholdNotification();
 242     }
 243 }