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 * @key intermittent 28 * @summary Test that the jmx.monitor.error.runtime monitor notification 29 * is emitted when getAttribute throws ReflectionException. 30 * @author Luis-Miguel Alventosa 31 * 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 }