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 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  * @key intermittent
  31  * @modules java.management
  32  * @run clean ReflectionExceptionTest MBeanServerBuilderImpl
  33  *            MBeanServerForwarderInvocationHandler
  34  * @run build ReflectionExceptionTest MBeanServerBuilderImpl
  35  *            MBeanServerForwarderInvocationHandler
  36  * @run main ReflectionExceptionTest
  37  */
  38 
  39 import java.lang.reflect.Proxy;
  40 import javax.management.MBeanServer;
  41 import javax.management.MBeanServerFactory;
  42 import javax.management.Notification;
  43 import javax.management.NotificationListener;
  44 import javax.management.ObjectName;
  45 import javax.management.ReflectionException;
  46 import javax.management.monitor.CounterMonitor;
  47 import javax.management.monitor.GaugeMonitor;
  48 import javax.management.monitor.MonitorNotification;
  49 import javax.management.monitor.StringMonitor;
  50 
  51 public class ReflectionExceptionTest implements NotificationListener {
  52 
  53     // MBean class
  54     public class ObservedObject implements ObservedObjectMBean {
  55         public Integer getIntegerAttribute() {
  56             return i;
  57         }
  58         public void setIntegerAttribute(Integer i) {
  59             this.i = i;
  60         }
  61         public String getStringAttribute() {
  62             return s;
  63         }
  64         public void setStringAttribute(String s) {
  65             this.s = s;
  66         }
  67         private Integer i = 1;
  68         private String s = "dummy";
  69     }
  70 
  71     // MBean interface
  72     public interface ObservedObjectMBean {
  73         public Integer getIntegerAttribute();
  74         public void setIntegerAttribute(Integer i);
  75         public String getStringAttribute();
  76         public void setStringAttribute(String s);
  77     }
  78 
  79     // Notification handler
  80     public void handleNotification(Notification notification, Object handback) {
  81         echo(">>> Received notification: " + notification);
  82         if (notification instanceof MonitorNotification) {
  83             String type = notification.getType();
  84             if (type.equals(MonitorNotification.RUNTIME_ERROR)) {
  85                 MonitorNotification mn = (MonitorNotification) notification;
  86                 echo("\tType: " + mn.getType());
  87                 echo("\tTimeStamp: " + mn.getTimeStamp());
  88                 echo("\tObservedObject: " + mn.getObservedObject());
  89                 echo("\tObservedAttribute: " + mn.getObservedAttribute());
  90                 echo("\tDerivedGauge: " + mn.getDerivedGauge());
  91                 echo("\tTrigger: " + mn.getTrigger());
  92 
  93                 synchronized (this) {
  94                     messageReceived = true;
  95                     notifyAll();
  96                 }
  97             }
  98         }
  99     }
 100 
 101     /**
 102      * Update the counter and check for notifications
 103      */
 104     public int counterMonitorNotification() throws Exception {
 105 
 106         CounterMonitor counterMonitor = new CounterMonitor();
 107         try {
 108             // Create a new CounterMonitor MBean and add it to the MBeanServer.
 109             //
 110             echo(">>> CREATE a new CounterMonitor MBean");
 111             ObjectName counterMonitorName = new ObjectName(
 112                             domain + ":type=" + CounterMonitor.class.getName());
 113             server.registerMBean(counterMonitor, counterMonitorName);
 114 
 115             echo(">>> ADD a listener to the CounterMonitor");
 116             counterMonitor.addNotificationListener(this, null, null);
 117 
 118             //
 119             // MANAGEMENT OF A STANDARD MBEAN
 120             //
 121 
 122             echo(">>> SET the attributes of the CounterMonitor:");
 123 
 124             counterMonitor.addObservedObject(obsObjName);
 125             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 126 
 127             counterMonitor.setObservedAttribute("IntegerAttribute");
 128             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 129 
 130             counterMonitor.setNotify(false);
 131             echo("\tATTRIBUTE \"NotifyFlag\"        = false");
 132 
 133             Integer threshold = 2;
 134             counterMonitor.setInitThreshold(threshold);
 135             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
 136 
 137             int granularityperiod = 500;
 138             counterMonitor.setGranularityPeriod(granularityperiod);
 139             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 140 
 141             echo(">>> START the CounterMonitor");
 142             counterMonitor.start();
 143 
 144             // Check if notification was received
 145             //
 146             doWait();
 147             if (messageReceived) {
 148                 echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
 149             } else {
 150                 echo("\tKO: CounterMonitor did not get " +
 151                      "RUNTIME_ERROR notification!");
 152                 return 1;
 153             }
 154         } finally {
 155             messageReceived = false;
 156             if (counterMonitor != null)
 157                 counterMonitor.stop();
 158         }
 159 
 160         return 0;
 161     }
 162 
 163     /**
 164      * Update the gauge and check for notifications
 165      */
 166     public int gaugeMonitorNotification() throws Exception {
 167 
 168         GaugeMonitor gaugeMonitor = new GaugeMonitor();
 169         try {
 170             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
 171             //
 172             echo(">>> CREATE a new GaugeMonitor MBean");
 173             ObjectName gaugeMonitorName = new ObjectName(
 174                             domain + ":type=" + GaugeMonitor.class.getName());
 175             server.registerMBean(gaugeMonitor, gaugeMonitorName);
 176 
 177             echo(">>> ADD a listener to the GaugeMonitor");
 178             gaugeMonitor.addNotificationListener(this, null, null);
 179 
 180             //
 181             // MANAGEMENT OF A STANDARD MBEAN
 182             //
 183 
 184             echo(">>> SET the attributes of the GaugeMonitor:");
 185 
 186             gaugeMonitor.addObservedObject(obsObjName);
 187             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 188 
 189             gaugeMonitor.setObservedAttribute("IntegerAttribute");
 190             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 191 
 192             gaugeMonitor.setNotifyLow(false);
 193             gaugeMonitor.setNotifyHigh(false);
 194             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
 195             echo("\tATTRIBUTE \"Notify High Flag\"  = false");
 196 
 197             Integer highThreshold = 3, lowThreshold = 2;
 198             gaugeMonitor.setThresholds(highThreshold, lowThreshold);
 199             echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
 200             echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
 201 
 202             int granularityperiod = 500;
 203             gaugeMonitor.setGranularityPeriod(granularityperiod);
 204             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 205 
 206             echo(">>> START the GaugeMonitor");
 207             gaugeMonitor.start();
 208 
 209             // Check if notification was received
 210             //
 211             doWait();
 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             // Check if notification was received
 274             //
 275             doWait();
 276             if (messageReceived) {
 277                 echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
 278             } else {
 279                 echo("\tKO: StringMonitor did not get " +
 280                      "RUNTIME_ERROR notification!");
 281                 return 1;
 282             }
 283         } finally {
 284             messageReceived = false;
 285             if (stringMonitor != null)
 286                 stringMonitor.stop();
 287         }
 288 
 289         return 0;
 290     }
 291 
 292     /**
 293      * Test the monitor notifications.
 294      */
 295     public int monitorNotifications() throws Exception {
 296 
 297         server = MBeanServerFactory.newMBeanServer();
 298 
 299         MBeanServerForwarderInvocationHandler mbsfih =
 300             (MBeanServerForwarderInvocationHandler)
 301             Proxy.getInvocationHandler(server);
 302 
 303         mbsfih.setGetAttributeException(
 304             new ReflectionException(new RuntimeException(),
 305                                     "Test ReflectionException"));
 306 
 307         domain = server.getDefaultDomain();
 308 
 309         obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject");
 310         server.registerMBean(new ObservedObject(), obsObjName);
 311 
 312         echo(">>> ----------------------------------------");
 313         int error = counterMonitorNotification();
 314         echo(">>> ----------------------------------------");
 315         error += gaugeMonitorNotification();
 316         echo(">>> ----------------------------------------");
 317         error += stringMonitorNotification();
 318         echo(">>> ----------------------------------------");
 319         return error;
 320     }
 321 
 322     /*
 323      * Print message
 324      */
 325     private static void echo(String message) {
 326         System.out.println(message);
 327     }
 328 
 329     /*
 330      * Standalone entry point.
 331      *
 332      * Run the test and report to stdout.
 333      */
 334     public static void main (String args[]) throws Exception {
 335         System.setProperty("javax.management.builder.initial",
 336                            MBeanServerBuilderImpl.class.getName());
 337         ReflectionExceptionTest test = new ReflectionExceptionTest();
 338         int error = test.monitorNotifications();
 339         if (error > 0) {
 340             echo(">>> Unhappy Bye, Bye!");
 341             throw new IllegalStateException("Test FAILED: Didn't get all " +
 342                                             "the notifications that were " +
 343                                             "expected by the test!");
 344         } else {
 345             echo(">>> Happy Bye, Bye!");
 346         }
 347     }
 348 
 349     /*
 350      * Wait messageReceived to be true
 351      */
 352     synchronized void doWait() {
 353         while (!messageReceived) {
 354             try {
 355                 wait();
 356             } catch (InterruptedException e) {
 357                 System.err.println("Got unexpected exception: " + e);
 358                 e.printStackTrace();
 359                 break;
 360             }
 361         }
 362     }
 363 
 364     // Flag to notify that a message has been received
 365     private volatile boolean messageReceived = false;
 366 
 367     private MBeanServer server;
 368     private ObjectName obsObjName;
 369     private String domain;
 370 }