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 
  91                 synchronized (this) {
  92                     messageReceived = true;
  93                     notifyAll();
  94                 }
  95             }
  96         }
  97     }
  98 
  99     /**
 100      * Update the counter and check for notifications
 101      */
 102     public int counterMonitorNotification() throws Exception {
 103 
 104         CounterMonitor counterMonitor = new CounterMonitor();
 105         try {
 106             // Create a new CounterMonitor MBean and add it to the MBeanServer.
 107             //
 108             echo(">>> CREATE a new CounterMonitor MBean");
 109             ObjectName counterMonitorName = new ObjectName(
 110                             domain + ":type=" + CounterMonitor.class.getName());
 111             server.registerMBean(counterMonitor, counterMonitorName);
 112 
 113             echo(">>> ADD a listener to the CounterMonitor");
 114             counterMonitor.addNotificationListener(this, null, null);
 115 
 116             //
 117             // MANAGEMENT OF A STANDARD MBEAN
 118             //
 119 
 120             echo(">>> SET the attributes of the CounterMonitor:");
 121 
 122             counterMonitor.addObservedObject(obsObjName);
 123             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 124 
 125             counterMonitor.setObservedAttribute("IntegerAttribute");
 126             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 127 
 128             counterMonitor.setNotify(false);
 129             echo("\tATTRIBUTE \"NotifyFlag\"        = false");
 130 
 131             Integer threshold = 2;
 132             counterMonitor.setInitThreshold(threshold);
 133             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
 134 
 135             int granularityperiod = 500;
 136             counterMonitor.setGranularityPeriod(granularityperiod);
 137             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 138 
 139             echo(">>> START the CounterMonitor");
 140             counterMonitor.start();
 141 
 142             // Check if notification was received
 143             //
 144             doWait();
 145             if (messageReceived) {
 146                 echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
 147             } else {
 148                 echo("\tKO: CounterMonitor did not get " +
 149                      "RUNTIME_ERROR notification!");
 150                 return 1;
 151             }
 152         } finally {
 153             messageReceived = false;
 154             if (counterMonitor != null)
 155                 counterMonitor.stop();
 156         }
 157 
 158         return 0;
 159     }
 160 
 161     /**
 162      * Update the gauge and check for notifications
 163      */
 164     public int gaugeMonitorNotification() throws Exception {
 165 
 166         GaugeMonitor gaugeMonitor = new GaugeMonitor();
 167         try {
 168             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
 169             //
 170             echo(">>> CREATE a new GaugeMonitor MBean");
 171             ObjectName gaugeMonitorName = new ObjectName(
 172                             domain + ":type=" + GaugeMonitor.class.getName());
 173             server.registerMBean(gaugeMonitor, gaugeMonitorName);
 174 
 175             echo(">>> ADD a listener to the GaugeMonitor");
 176             gaugeMonitor.addNotificationListener(this, null, null);
 177 
 178             //
 179             // MANAGEMENT OF A STANDARD MBEAN
 180             //
 181 
 182             echo(">>> SET the attributes of the GaugeMonitor:");
 183 
 184             gaugeMonitor.addObservedObject(obsObjName);
 185             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 186 
 187             gaugeMonitor.setObservedAttribute("IntegerAttribute");
 188             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
 189 
 190             gaugeMonitor.setNotifyLow(false);
 191             gaugeMonitor.setNotifyHigh(false);
 192             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
 193             echo("\tATTRIBUTE \"Notify High Flag\"  = false");
 194 
 195             Integer highThreshold = 3, lowThreshold = 2;
 196             gaugeMonitor.setThresholds(highThreshold, lowThreshold);
 197             echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
 198             echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
 199 
 200             int granularityperiod = 500;
 201             gaugeMonitor.setGranularityPeriod(granularityperiod);
 202             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 203 
 204             echo(">>> START the GaugeMonitor");
 205             gaugeMonitor.start();
 206 
 207             // Check if notification was received
 208             //
 209             doWait();
 210             if (messageReceived) {
 211                 echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
 212             } else {
 213                 echo("\tKO: GaugeMonitor did not get " +
 214                      "RUNTIME_ERROR notification!");
 215                 return 1;
 216             }
 217         } finally {
 218             messageReceived = false;
 219             if (gaugeMonitor != null)
 220                 gaugeMonitor.stop();
 221         }
 222 
 223         return 0;
 224     }
 225 
 226     /**
 227      * Update the string and check for notifications
 228      */
 229     public int stringMonitorNotification() throws Exception {
 230 
 231         StringMonitor stringMonitor = new StringMonitor();
 232         try {
 233             // Create a new StringMonitor MBean and add it to the MBeanServer.
 234             //
 235             echo(">>> CREATE a new StringMonitor MBean");
 236             ObjectName stringMonitorName = new ObjectName(
 237                             domain + ":type=" + StringMonitor.class.getName());
 238             server.registerMBean(stringMonitor, stringMonitorName);
 239 
 240             echo(">>> ADD a listener to the StringMonitor");
 241             stringMonitor.addNotificationListener(this, null, null);
 242 
 243             //
 244             // MANAGEMENT OF A STANDARD MBEAN
 245             //
 246 
 247             echo(">>> SET the attributes of the StringMonitor:");
 248 
 249             stringMonitor.addObservedObject(obsObjName);
 250             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
 251 
 252             stringMonitor.setObservedAttribute("StringAttribute");
 253             echo("\tATTRIBUTE \"ObservedAttribute\" = StringAttribute");
 254 
 255             stringMonitor.setNotifyMatch(false);
 256             echo("\tATTRIBUTE \"NotifyMatch\"       = false");
 257 
 258             stringMonitor.setNotifyDiffer(false);
 259             echo("\tATTRIBUTE \"NotifyDiffer\"      = false");
 260 
 261             stringMonitor.setStringToCompare("dummy");
 262             echo("\tATTRIBUTE \"StringToCompare\"   = \"dummy\"");
 263 
 264             int granularityperiod = 500;
 265             stringMonitor.setGranularityPeriod(granularityperiod);
 266             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
 267 
 268             echo(">>> START the StringMonitor");
 269             stringMonitor.start();
 270 
 271             // Check if notification was received
 272             //
 273             doWait();
 274             if (messageReceived) {
 275                 echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
 276             } else {
 277                 echo("\tKO: StringMonitor did not get " +
 278                      "RUNTIME_ERROR notification!");
 279                 return 1;
 280             }
 281         } finally {
 282             messageReceived = false;
 283             if (stringMonitor != null)
 284                 stringMonitor.stop();
 285         }
 286 
 287         return 0;
 288     }
 289 
 290     /**
 291      * Test the monitor notifications.
 292      */
 293     public int monitorNotifications() throws Exception {
 294 
 295         server = MBeanServerFactory.newMBeanServer();
 296 
 297         MBeanServerForwarderInvocationHandler mbsfih =
 298             (MBeanServerForwarderInvocationHandler)
 299             Proxy.getInvocationHandler(server);
 300 
 301         mbsfih.setGetAttributeException(
 302             new ReflectionException(new RuntimeException(),
 303                                     "Test ReflectionException"));
 304 
 305         domain = server.getDefaultDomain();
 306 
 307         obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject");
 308         server.registerMBean(new ObservedObject(), obsObjName);
 309 
 310         echo(">>> ----------------------------------------");
 311         int error = counterMonitorNotification();
 312         echo(">>> ----------------------------------------");
 313         error += gaugeMonitorNotification();
 314         echo(">>> ----------------------------------------");
 315         error += stringMonitorNotification();
 316         echo(">>> ----------------------------------------");
 317         return error;
 318     }
 319 
 320     /*
 321      * Print message
 322      */
 323     private static void echo(String message) {
 324         System.out.println(message);
 325     }
 326 
 327     /*
 328      * Standalone entry point.
 329      *
 330      * Run the test and report to stdout.
 331      */
 332     public static void main (String args[]) throws Exception {
 333         System.setProperty("javax.management.builder.initial",
 334                            MBeanServerBuilderImpl.class.getName());
 335         ReflectionExceptionTest test = new ReflectionExceptionTest();
 336         int error = test.monitorNotifications();
 337         if (error > 0) {
 338             echo(">>> Unhappy Bye, Bye!");
 339             throw new IllegalStateException("Test FAILED: Didn't get all " +
 340                                             "the notifications that were " +
 341                                             "expected by the test!");
 342         } else {
 343             echo(">>> Happy Bye, Bye!");
 344         }
 345     }
 346 
 347     /*
 348      * Wait messageReceived to be true
 349      */
 350     synchronized void doWait() {
 351         while (!messageReceived) {
 352             try {
 353                 wait();
 354             } catch (InterruptedException e) {
 355                 System.err.println("Got unexpected exception: " + e);
 356                 e.printStackTrace();
 357                 break;
 358             }
 359         }
 360     }
 361 
 362     // Flag to notify that a message has been received
 363     private volatile boolean messageReceived = false;
 364 
 365     private MBeanServer server;
 366     private ObjectName obsObjName;
 367     private String domain;
 368 }