1 /*
   2  * Copyright (c) 2005, 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 6205072
  27  * @summary Test that the jmx.monitor.error.runtime monitor notification
  28  *          is emitted when getAttribute throws ReflectionException.
  29  * @author Luis-Miguel Alventosa
  30  * @run clean ReflectionExceptionTest MBeanServerBuilderImpl
  31  *            MBeanServerForwarderInvocationHandler
  32  * @run build ReflectionExceptionTest MBeanServerBuilderImpl
  33  *            MBeanServerForwarderInvocationHandler
  34  * @run main ReflectionExceptionTest
  35  */
  36 
  37 import java.lang.reflect.Proxy;
  38 import javax.management.MBeanServer;
  39 import javax.management.MBeanServerFactory;
  40 import javax.management.Notification;
  41 import javax.management.NotificationListener;
  42 import javax.management.ObjectName;
  43 import javax.management.ReflectionException;
  44 import javax.management.monitor.CounterMonitor;
  45 import javax.management.monitor.GaugeMonitor;
  46 import javax.management.monitor.MonitorNotification;
  47 import javax.management.monitor.StringMonitor;
  48 
  49 public class ReflectionExceptionTest implements NotificationListener {
  50 
  51     // MBean class
  52     public class ObservedObject implements ObservedObjectMBean {
  53         public Integer getIntegerAttribute() {
  54             return i;
  55         }
  56         public void setIntegerAttribute(Integer i) {
  57             this.i = i;
  58         }
  59         public String getStringAttribute() {
  60             return s;
  61         }
  62         public void setStringAttribute(String s) {
  63             this.s = s;
  64         }
  65         private Integer i = 1;
  66         private String s = "dummy";
  67     }
  68 
  69     // MBean interface
  70     public interface ObservedObjectMBean {
  71         public Integer getIntegerAttribute();
  72         public void setIntegerAttribute(Integer i);
  73         public String getStringAttribute();
  74         public void setStringAttribute(String s);
  75     }
  76 
  77     // Notification handler
  78     public void handleNotification(Notification notification, Object handback) {
  79         echo(">>> Received notification: " + notification);
  80         if (notification instanceof MonitorNotification) {
  81             String type = notification.getType();
  82             if (type.equals(MonitorNotification.RUNTIME_ERROR)) {
  83                 MonitorNotification mn = (MonitorNotification) notification;
  84                 echo("\tType: " + mn.getType());
  85                 echo("\tTimeStamp: " + mn.getTimeStamp());
  86                 echo("\tObservedObject: " + mn.getObservedObject());
  87                 echo("\tObservedAttribute: " + mn.getObservedAttribute());
  88                 echo("\tDerivedGauge: " + mn.getDerivedGauge());
  89                 echo("\tTrigger: " + mn.getTrigger());
  90                 messageReceived = true;
  91             }
  92         }
  93     }
  94 
  95     /**
  96      * Update the counter and check for notifications
  97      */
  98     public int counterMonitorNotification() throws Exception {
  99 
 100         CounterMonitor counterMonitor = new CounterMonitor();
 101         try {
 102             // Create a new CounterMonitor MBean and add it to the MBeanServer.
 103             //
 104             echo(">>> CREATE a new CounterMonitor MBean");
 105             ObjectName counterMonitorName = new ObjectName(
 106                             domain + ":type=" + CounterMonitor.class.getName());
 107             server.registerMBean(counterMonitor, counterMonitorName);
 108 
 109             echo(">>> ADD a listener to the CounterMonitor");
 110             counterMonitor.addNotificationListener(this, null, null);
 111 
 112             //
 113             // MANAGEMENT OF A STANDARD MBEAN
 114             //
 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(false);
 125             echo("\tATTRIBUTE \"NotifyFlag\"        = false");
 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             // Wait for granularity period (multiplied by 2 for sure)
 139             //
 140             Thread.sleep(granularityperiod * 2);
 141 
 142             // Check if notification was received
 143             //
 144             if (messageReceived) {
 145                 echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
 146             } else {
 147                 echo("\tKO: CounterMonitor did not get " +
 148                      "RUNTIME_ERROR notification!");
 149                 return 1;
 150             }
 151         } finally {
 152             messageReceived = false;
 153             if (counterMonitor != null)
 154                 counterMonitor.stop();
 155         }
 156 
 157         return 0;
 158     }
 159 
 160     /**
 161      * Update the gauge and check for notifications
 162      */
 163     public int gaugeMonitorNotification() throws Exception {
 164 
 165         GaugeMonitor gaugeMonitor = new GaugeMonitor();
 166         try {
 167             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
 168             //
 169             echo(">>> CREATE a new GaugeMonitor MBean");
 170             ObjectName gaugeMonitorName = new ObjectName(
 171                             domain + ":type=" + GaugeMonitor.class.getName());
 172             server.registerMBean(gaugeMonitor, gaugeMonitorName);
 173 
 174             echo(">>> ADD a listener to the GaugeMonitor");
 175             gaugeMonitor.addNotificationListener(this, null, null);
 176 
 177             //
 178             // MANAGEMENT OF A STANDARD MBEAN
 179             //
 180 
 181             echo(">>> SET the attributes of the GaugeMonitor:");
 182 
 183             gaugeMonitor.addObservedObject(obsObjName);
 184             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 185 
 186             gaugeMonitor.setObservedAttribute("IntegerAttribute");
 187             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 188 
 189             gaugeMonitor.setNotifyLow(false);
 190             gaugeMonitor.setNotifyHigh(false);
 191             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
 192             echo("\tATTRIBUTE \"Notify High Flag\"  = false");
 193 
 194             Integer highThreshold = 3, lowThreshold = 2;
 195             gaugeMonitor.setThresholds(highThreshold, lowThreshold);
 196             echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
 197             echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
 198 
 199             int granularityperiod = 500;
 200             gaugeMonitor.setGranularityPeriod(granularityperiod);
 201             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 202 
 203             echo(">>> START the GaugeMonitor");
 204             gaugeMonitor.start();
 205 
 206             // Wait for granularity period (multiplied by 2 for sure)
 207             //
 208             Thread.sleep(granularityperiod * 2);
 209 
 210             // Check if notification was received
 211             //
 212             if (messageReceived) {
 213                 echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
 214             } else {
 215                 echo("\tKO: GaugeMonitor did not get " +
 216                      "RUNTIME_ERROR notification!");
 217                 return 1;
 218             }
 219         } finally {
 220             messageReceived = false;
 221             if (gaugeMonitor != null)
 222                 gaugeMonitor.stop();
 223         }
 224 
 225         return 0;
 226     }
 227 
 228     /**
 229      * Update the string and check for notifications
 230      */
 231     public int stringMonitorNotification() throws Exception {
 232 
 233         StringMonitor stringMonitor = new StringMonitor();
 234         try {
 235             // Create a new StringMonitor MBean and add it to the MBeanServer.
 236             //
 237             echo(">>> CREATE a new StringMonitor MBean");
 238             ObjectName stringMonitorName = new ObjectName(
 239                             domain + ":type=" + StringMonitor.class.getName());
 240             server.registerMBean(stringMonitor, stringMonitorName);
 241 
 242             echo(">>> ADD a listener to the StringMonitor");
 243             stringMonitor.addNotificationListener(this, null, null);
 244 
 245             //
 246             // MANAGEMENT OF A STANDARD MBEAN
 247             //
 248 
 249             echo(">>> SET the attributes of the StringMonitor:");
 250 
 251             stringMonitor.addObservedObject(obsObjName);
 252             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 253 
 254             stringMonitor.setObservedAttribute("StringAttribute");
 255             echo("\tATTRIBUTE \"ObservedAttribute\" = StringAttribute");
 256 
 257             stringMonitor.setNotifyMatch(false);
 258             echo("\tATTRIBUTE \"NotifyMatch\"       = false");
 259 
 260             stringMonitor.setNotifyDiffer(false);
 261             echo("\tATTRIBUTE \"NotifyDiffer\"      = false");
 262 
 263             stringMonitor.setStringToCompare("dummy");
 264             echo("\tATTRIBUTE \"StringToCompare\"   = \"dummy\"");
 265 
 266             int granularityperiod = 500;
 267             stringMonitor.setGranularityPeriod(granularityperiod);
 268             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 269 
 270             echo(">>> START the StringMonitor");
 271             stringMonitor.start();
 272 
 273             // Wait for granularity period (multiplied by 2 for sure)
 274             //
 275             Thread.sleep(granularityperiod * 2);
 276 
 277             // Check if notification was received
 278             //
 279             if (messageReceived) {
 280                 echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
 281             } else {
 282                 echo("\tKO: StringMonitor did not get " +
 283                      "RUNTIME_ERROR notification!");
 284                 return 1;
 285             }
 286         } finally {
 287             messageReceived = false;
 288             if (stringMonitor != null)
 289                 stringMonitor.stop();
 290         }
 291 
 292         return 0;
 293     }
 294 
 295     /**
 296      * Test the monitor notifications.
 297      */
 298     public int monitorNotifications() throws Exception {
 299 
 300         server = MBeanServerFactory.newMBeanServer();
 301 
 302         MBeanServerForwarderInvocationHandler mbsfih =
 303             (MBeanServerForwarderInvocationHandler)
 304             Proxy.getInvocationHandler(server);
 305 
 306         mbsfih.setGetAttributeException(
 307             new ReflectionException(new RuntimeException(),
 308                                     "Test ReflectionException"));
 309 
 310         domain = server.getDefaultDomain();
 311 
 312         obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject");
 313         server.registerMBean(new ObservedObject(), obsObjName);
 314 
 315         echo(">>> ----------------------------------------");
 316         int error = counterMonitorNotification();
 317         echo(">>> ----------------------------------------");
 318         error += gaugeMonitorNotification();
 319         echo(">>> ----------------------------------------");
 320         error += stringMonitorNotification();
 321         echo(">>> ----------------------------------------");
 322         return error;
 323     }
 324 
 325     /*
 326      * Print message
 327      */
 328     private static void echo(String message) {
 329         System.out.println(message);
 330     }
 331 
 332     /*
 333      * Standalone entry point.
 334      *
 335      * Run the test and report to stdout.
 336      */
 337     public static void main (String args[]) throws Exception {
 338         System.setProperty("javax.management.builder.initial",
 339                            MBeanServerBuilderImpl.class.getName());
 340         ReflectionExceptionTest test = new ReflectionExceptionTest();
 341         int error = test.monitorNotifications();
 342         if (error > 0) {
 343             echo(">>> Unhappy Bye, Bye!");
 344             throw new IllegalStateException("Test FAILED: Didn't get all " +
 345                                             "the notifications that were " +
 346                                             "expected by the test!");
 347         } else {
 348             echo(">>> Happy Bye, Bye!");
 349         }
 350     }
 351 
 352     // Flag to notify that a message has been received
 353     private boolean messageReceived = false;
 354 
 355     private MBeanServer server;
 356     private ObjectName obsObjName;
 357     private String domain;
 358 }