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 6200391 27 * @summary Test that the jmx.monitor.error.runtime monitor notification 28 * is emitted when getAttribute throws RuntimeException. 29 * @author Luis-Miguel Alventosa 30 * 31 * @run clean RuntimeExceptionTest MBeanServerBuilderImpl 32 * MBeanServerForwarderInvocationHandler 33 * @run build RuntimeExceptionTest MBeanServerBuilderImpl 34 * MBeanServerForwarderInvocationHandler 35 * @run main RuntimeExceptionTest 36 */ 37 38 import java.lang.reflect.Proxy; 39 import javax.management.MBeanServer; 40 import javax.management.MBeanServerFactory; 41 import javax.management.Notification; 42 import javax.management.NotificationListener; 43 import javax.management.ObjectName; 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 RuntimeExceptionTest 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 RuntimeException("Test RuntimeException")); 303 304 domain = server.getDefaultDomain(); 305 306 obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject"); 307 server.registerMBean(new ObservedObject(), obsObjName); 308 309 echo(">>> ----------------------------------------"); 310 int error = counterMonitorNotification(); 311 echo(">>> ----------------------------------------"); 312 error += gaugeMonitorNotification(); 313 echo(">>> ----------------------------------------"); 314 error += stringMonitorNotification(); 315 echo(">>> ----------------------------------------"); 316 return error; 317 } 318 319 /* 320 * Print message 321 */ 322 private static void echo(String message) { 323 System.out.println(message); 324 } 325 326 /* 327 * Standalone entry point. 328 * 329 * Run the test and report to stdout. 330 */ 331 public static void main (String args[]) throws Exception { 332 System.setProperty("javax.management.builder.initial", 333 MBeanServerBuilderImpl.class.getName()); 334 RuntimeExceptionTest test = new RuntimeExceptionTest(); 335 int error = test.monitorNotifications(); 336 if (error > 0) { 337 echo(">>> Unhappy Bye, Bye!"); 338 throw new IllegalStateException("Test FAILED: Didn't get all " + 339 "the notifications that were " + 340 "expected by the test!"); 341 } else { 342 echo(">>> Happy Bye, Bye!"); 343 } 344 } 345 346 /* 347 * Wait messageReceived to be true 348 */ 349 synchronized void doWait() { 350 while (!messageReceived) { 351 try { 352 wait(); 353 } catch (InterruptedException e) { 354 System.err.println("Got unexpected exception: " + e); 355 e.printStackTrace(); 356 break; 357 } 358 } 359 } 360 361 // Flag to notify that a message has been received 362 private volatile boolean messageReceived = false; 363 364 private MBeanServer server; 365 private ObjectName obsObjName; 366 private String domain; 367 }