1 /*
   2  * Copyright (c) 2005, 2015, 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 6200031 8025206
  27  * @summary Test that the counter/gauge/string monitors emit a
  28  *          jmx.monitor.error.type notification when the attribute
  29  *          being monitored returns a null value.
  30  * @author Luis-Miguel Alventosa
  31  * @author Shanliang JIANG
  32  *
  33  * @run clean NullAttributeValueTest
  34  * @run build NullAttributeValueTest
  35  * @run main NullAttributeValueTest
  36  */
  37 
  38 import javax.management.*;
  39 import javax.management.monitor.*;
  40 
  41 public class NullAttributeValueTest implements NotificationListener {
  42 
  43     // Flag to notify that a message has been received
  44     private volatile boolean messageReceived = false;
  45 
  46     // MBean class
  47     public class ObservedObject implements ObservedObjectMBean {
  48         public Integer getIntegerAttribute() {
  49             return null;
  50         }
  51         public String getStringAttribute() {
  52             return null;
  53         }
  54     }
  55 
  56     // MBean interface
  57     public interface ObservedObjectMBean {
  58         public Integer getIntegerAttribute();
  59         public String getStringAttribute();
  60     }
  61 
  62     // Notification handler
  63     public void handleNotification(Notification notification,
  64                                    Object handback) {
  65         MonitorNotification n = (MonitorNotification) notification;
  66         echo("\tInside handleNotification...");
  67         String type = n.getType();
  68         try {
  69             if (type.equals(
  70                     MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR)) {
  71                 echo("\t\t" + n.getObservedAttribute() + " is null");
  72                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
  73                 echo("\t\tTrigger = " + n.getTrigger());
  74                 messageReceived = true;
  75             } else {
  76                 echo("\t\tSkipping notification of type: " + type);
  77             }
  78         } catch (Exception e) {
  79             echo("\tError in handleNotification!");
  80             e.printStackTrace(System.out);
  81         }
  82     }
  83 
  84     /**
  85      * Update the counter and check for notifications
  86      */
  87     public int counterMonitorNotification() throws Exception {
  88         CounterMonitor counterMonitor = null;
  89         try {
  90             MBeanServer server = MBeanServerFactory.newMBeanServer();
  91 
  92             String domain = server.getDefaultDomain();
  93 
  94             // Create a new CounterMonitor MBean and add it to the MBeanServer.
  95             //
  96             echo(">>> CREATE a new CounterMonitor MBean");
  97             ObjectName counterMonitorName = new ObjectName(
  98                             domain + ":type=" + CounterMonitor.class.getName());
  99             counterMonitor = new CounterMonitor();
 100             server.registerMBean(counterMonitor, counterMonitorName);
 101 
 102             echo(">>> ADD a listener to the CounterMonitor");
 103             counterMonitor.addNotificationListener(this, null, null);
 104 
 105             //
 106             // MANAGEMENT OF A STANDARD MBEAN
 107             //
 108 
 109             echo(">>> CREATE a new ObservedObject MBean");
 110 
 111             ObjectName obsObjName =
 112                 ObjectName.getInstance(domain + ":type=ObservedObject");
 113             ObservedObject obsObj = new ObservedObject();
 114             server.registerMBean(obsObj, obsObjName);
 115 
 116             echo(">>> SET the attributes of the CounterMonitor:");
 117 
 118             counterMonitor.addObservedObject(obsObjName);
 119             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 120 
 121             counterMonitor.setObservedAttribute("IntegerAttribute");
 122             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 123 
 124             counterMonitor.setNotify(true);
 125             echo("\tATTRIBUTE \"NotifyFlag\"        = true");
 126 
 127             Integer threshold = 2;
 128             counterMonitor.setInitThreshold(threshold);
 129             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
 130 
 131             int granularityperiod = 500;
 132             counterMonitor.setGranularityPeriod(granularityperiod);
 133             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 134 
 135             echo(">>> START the CounterMonitor");
 136             counterMonitor.start();
 137 
 138             return checkReceived(granularityperiod, "CounterMonitor");
 139         } finally {
 140             if (counterMonitor != null)
 141                 counterMonitor.stop();
 142         }
 143     }
 144 
 145     /**
 146      * Update the gauge and check for notifications
 147      */
 148     public int gaugeMonitorNotification() throws Exception {
 149         GaugeMonitor gaugeMonitor = null;
 150         try {
 151             MBeanServer server = MBeanServerFactory.newMBeanServer();
 152 
 153             String domain = server.getDefaultDomain();
 154 
 155             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
 156             //
 157             echo(">>> CREATE a new GaugeMonitor MBean");
 158             ObjectName gaugeMonitorName = new ObjectName(
 159                             domain + ":type=" + GaugeMonitor.class.getName());
 160             gaugeMonitor = new GaugeMonitor();
 161             server.registerMBean(gaugeMonitor, gaugeMonitorName);
 162 
 163             echo(">>> ADD a listener to the GaugeMonitor");
 164             gaugeMonitor.addNotificationListener(this, null, null);
 165 
 166             //
 167             // MANAGEMENT OF A STANDARD MBEAN
 168             //
 169 
 170             echo(">>> CREATE a new ObservedObject MBean");
 171 
 172             ObjectName obsObjName =
 173                 ObjectName.getInstance(domain + ":type=ObservedObject");
 174             ObservedObject obsObj = new ObservedObject();
 175             server.registerMBean(obsObj, obsObjName);
 176 
 177             echo(">>> SET the attributes of the GaugeMonitor:");
 178 
 179             gaugeMonitor.addObservedObject(obsObjName);
 180             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 181 
 182             gaugeMonitor.setObservedAttribute("IntegerAttribute");
 183             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 184 
 185             gaugeMonitor.setNotifyLow(false);
 186             gaugeMonitor.setNotifyHigh(true);
 187             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
 188             echo("\tATTRIBUTE \"Notify High Flag\"  = true");
 189 
 190             Double highThreshold = 3.0, lowThreshold = 2.5;
 191             gaugeMonitor.setThresholds(highThreshold, lowThreshold);
 192             echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
 193             echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
 194 
 195             int granularityperiod = 500;
 196             gaugeMonitor.setGranularityPeriod(granularityperiod);
 197             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 198 
 199             echo(">>> START the GaugeMonitor");
 200             gaugeMonitor.start();
 201 
 202             return checkReceived(granularityperiod, "GaugeMonitor");
 203         } finally {
 204             if (gaugeMonitor != null)
 205                 gaugeMonitor.stop();
 206         }
 207     }
 208 
 209     /**
 210      * Update the string and check for notifications
 211      */
 212     public int stringMonitorNotification() throws Exception {
 213         StringMonitor stringMonitor = null;
 214         try {
 215             MBeanServer server = MBeanServerFactory.newMBeanServer();
 216 
 217             String domain = server.getDefaultDomain();
 218 
 219             // Create a new StringMonitor MBean and add it to the MBeanServer.
 220             //
 221             echo(">>> CREATE a new StringMonitor MBean");
 222             ObjectName stringMonitorName = new ObjectName(
 223                             domain + ":type=" + StringMonitor.class.getName());
 224             stringMonitor = new StringMonitor();
 225             server.registerMBean(stringMonitor, stringMonitorName);
 226 
 227             echo(">>> ADD a listener to the StringMonitor");
 228             stringMonitor.addNotificationListener(this, null, null);
 229 
 230             //
 231             // MANAGEMENT OF A STANDARD MBEAN
 232             //
 233 
 234             echo(">>> CREATE a new ObservedObject MBean");
 235 
 236             ObjectName obsObjName =
 237                 ObjectName.getInstance(domain + ":type=ObservedObject");
 238             ObservedObject obsObj = new ObservedObject();
 239             server.registerMBean(obsObj, obsObjName);
 240 
 241             echo(">>> SET the attributes of the StringMonitor:");
 242 
 243             stringMonitor.addObservedObject(obsObjName);
 244             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 245 
 246             stringMonitor.setObservedAttribute("StringAttribute");
 247             echo("\tATTRIBUTE \"ObservedAttribute\" = StringAttribute");
 248 
 249             stringMonitor.setNotifyMatch(true);
 250             echo("\tATTRIBUTE \"NotifyMatch\"       = true");
 251 
 252             stringMonitor.setNotifyDiffer(false);
 253             echo("\tATTRIBUTE \"NotifyDiffer\"      = false");
 254 
 255             stringMonitor.setStringToCompare("do_match_now");
 256             echo("\tATTRIBUTE \"StringToCompare\"   = \"do_match_now\"");
 257 
 258             int granularityperiod = 500;
 259             stringMonitor.setGranularityPeriod(granularityperiod);
 260             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 261 
 262             echo(">>> START the StringMonitor");
 263             stringMonitor.start();
 264 
 265             return checkReceived(granularityperiod, "StringMonitor");
 266         } finally {
 267             if (stringMonitor != null)
 268                 stringMonitor.stop();
 269         }
 270     }
 271 
 272     /**
 273      * Test the monitor notifications.
 274      */
 275     public int monitorNotifications() throws Exception {
 276         echo(">>> ----------------------------------------");
 277         messageReceived = false;
 278         int error = counterMonitorNotification();
 279         echo(">>> ----------------------------------------");
 280         messageReceived = false;
 281         error += gaugeMonitorNotification();
 282         echo(">>> ----------------------------------------");
 283         messageReceived = false;
 284         error += stringMonitorNotification();
 285         echo(">>> ----------------------------------------");
 286         return error;
 287     }
 288 
 289     private int checkReceived(long granularityperiod, String caller) throws InterruptedException {
 290         int i = 100;
 291         do {
 292             Thread.sleep(granularityperiod);
 293         } while (!messageReceived && i-- > 0);
 294 
 295         if (messageReceived) {
 296             echo("\tOK: " + caller + " notification received");
 297         } else {
 298             echo("\tKO: " + caller + " notification missed or not emitted");
 299         }
 300 
 301         return messageReceived ? 0 : 1;
 302     }
 303 
 304     /*
 305      * Print message
 306      */
 307     private static void echo(String message) {
 308         System.out.println(message);
 309     }
 310 
 311     /*
 312      * Standalone entry point.
 313      *
 314      * Run the test and report to stdout.
 315      */
 316     public static void main (String args[]) throws Exception {
 317         NullAttributeValueTest test = new NullAttributeValueTest();
 318         int error = test.monitorNotifications();
 319         if (error > 0) {
 320             echo(">>> Unhappy Bye, Bye!");
 321             throw new IllegalStateException("Test FAILED: Didn't get all " +
 322                                             "the notifications that were " +
 323                                             "expected by the test!");
 324         } else {
 325             echo(">>> Happy Bye, Bye!");
 326         }
 327     }
 328 }