/* * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 6200391 * @summary Test that the jmx.monitor.error.runtime monitor notification * is emitted when getAttribute throws RuntimeException. * @author Luis-Miguel Alventosa * * @run clean RuntimeExceptionTest MBeanServerBuilderImpl * MBeanServerForwarderInvocationHandler * @run build RuntimeExceptionTest MBeanServerBuilderImpl * MBeanServerForwarderInvocationHandler * @run main RuntimeExceptionTest */ import java.lang.reflect.Proxy; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.Notification; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.monitor.CounterMonitor; import javax.management.monitor.GaugeMonitor; import javax.management.monitor.MonitorNotification; import javax.management.monitor.StringMonitor; public class RuntimeExceptionTest implements NotificationListener { // MBean class public class ObservedObject implements ObservedObjectMBean { public Integer getIntegerAttribute() { return i; } public void setIntegerAttribute(Integer i) { this.i = i; } public String getStringAttribute() { return s; } public void setStringAttribute(String s) { this.s = s; } private Integer i = 1; private String s = "dummy"; } // MBean interface public interface ObservedObjectMBean { public Integer getIntegerAttribute(); public void setIntegerAttribute(Integer i); public String getStringAttribute(); public void setStringAttribute(String s); } // Notification handler public void handleNotification(Notification notification, Object handback) { echo(">>> Received notification: " + notification); if (notification instanceof MonitorNotification) { String type = notification.getType(); if (type.equals(MonitorNotification.RUNTIME_ERROR)) { MonitorNotification mn = (MonitorNotification) notification; echo("\tType: " + mn.getType()); echo("\tTimeStamp: " + mn.getTimeStamp()); echo("\tObservedObject: " + mn.getObservedObject()); echo("\tObservedAttribute: " + mn.getObservedAttribute()); echo("\tDerivedGauge: " + mn.getDerivedGauge()); echo("\tTrigger: " + mn.getTrigger()); synchronized (this) { messageReceived = true; notifyAll(); } } } } /** * Update the counter and check for notifications */ public int counterMonitorNotification() throws Exception { CounterMonitor counterMonitor = new CounterMonitor(); try { // Create a new CounterMonitor MBean and add it to the MBeanServer. // echo(">>> CREATE a new CounterMonitor MBean"); ObjectName counterMonitorName = new ObjectName( domain + ":type=" + CounterMonitor.class.getName()); server.registerMBean(counterMonitor, counterMonitorName); echo(">>> ADD a listener to the CounterMonitor"); counterMonitor.addNotificationListener(this, null, null); // // MANAGEMENT OF A STANDARD MBEAN // echo(">>> SET the attributes of the CounterMonitor:"); counterMonitor.addObservedObject(obsObjName); echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); counterMonitor.setObservedAttribute("IntegerAttribute"); echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute"); counterMonitor.setNotify(false); echo("\tATTRIBUTE \"NotifyFlag\" = false"); Integer threshold = 2; counterMonitor.setInitThreshold(threshold); echo("\tATTRIBUTE \"Threshold\" = " + threshold); int granularityperiod = 500; counterMonitor.setGranularityPeriod(granularityperiod); echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); echo(">>> START the CounterMonitor"); counterMonitor.start(); // Check if notification was received // doWait(); if (messageReceived) { echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!"); } else { echo("\tKO: CounterMonitor did not get " + "RUNTIME_ERROR notification!"); return 1; } } finally { messageReceived = false; if (counterMonitor != null) counterMonitor.stop(); } return 0; } /** * Update the gauge and check for notifications */ public int gaugeMonitorNotification() throws Exception { GaugeMonitor gaugeMonitor = new GaugeMonitor(); try { // Create a new GaugeMonitor MBean and add it to the MBeanServer. // echo(">>> CREATE a new GaugeMonitor MBean"); ObjectName gaugeMonitorName = new ObjectName( domain + ":type=" + GaugeMonitor.class.getName()); server.registerMBean(gaugeMonitor, gaugeMonitorName); echo(">>> ADD a listener to the GaugeMonitor"); gaugeMonitor.addNotificationListener(this, null, null); // // MANAGEMENT OF A STANDARD MBEAN // echo(">>> SET the attributes of the GaugeMonitor:"); gaugeMonitor.addObservedObject(obsObjName); echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); gaugeMonitor.setObservedAttribute("IntegerAttribute"); echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute"); gaugeMonitor.setNotifyLow(false); gaugeMonitor.setNotifyHigh(false); echo("\tATTRIBUTE \"Notify Low Flag\" = false"); echo("\tATTRIBUTE \"Notify High Flag\" = false"); Integer highThreshold = 3, lowThreshold = 2; gaugeMonitor.setThresholds(highThreshold, lowThreshold); echo("\tATTRIBUTE \"Low Threshold\" = " + lowThreshold); echo("\tATTRIBUTE \"High Threshold\" = " + highThreshold); int granularityperiod = 500; gaugeMonitor.setGranularityPeriod(granularityperiod); echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); echo(">>> START the GaugeMonitor"); gaugeMonitor.start(); // Check if notification was received // doWait(); if (messageReceived) { echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!"); } else { echo("\tKO: GaugeMonitor did not get " + "RUNTIME_ERROR notification!"); return 1; } } finally { messageReceived = false; if (gaugeMonitor != null) gaugeMonitor.stop(); } return 0; } /** * Update the string and check for notifications */ public int stringMonitorNotification() throws Exception { StringMonitor stringMonitor = new StringMonitor(); try { // Create a new StringMonitor MBean and add it to the MBeanServer. // echo(">>> CREATE a new StringMonitor MBean"); ObjectName stringMonitorName = new ObjectName( domain + ":type=" + StringMonitor.class.getName()); server.registerMBean(stringMonitor, stringMonitorName); echo(">>> ADD a listener to the StringMonitor"); stringMonitor.addNotificationListener(this, null, null); // // MANAGEMENT OF A STANDARD MBEAN // echo(">>> SET the attributes of the StringMonitor:"); stringMonitor.addObservedObject(obsObjName); echo("\tATTRIBUTE \"ObservedObject\" = " + obsObjName); stringMonitor.setObservedAttribute("StringAttribute"); echo("\tATTRIBUTE \"ObservedAttribute\" = StringAttribute"); stringMonitor.setNotifyMatch(false); echo("\tATTRIBUTE \"NotifyMatch\" = false"); stringMonitor.setNotifyDiffer(false); echo("\tATTRIBUTE \"NotifyDiffer\" = false"); stringMonitor.setStringToCompare("dummy"); echo("\tATTRIBUTE \"StringToCompare\" = \"dummy\""); int granularityperiod = 500; stringMonitor.setGranularityPeriod(granularityperiod); echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod); echo(">>> START the StringMonitor"); stringMonitor.start(); // Check if notification was received // doWait(); if (messageReceived) { echo("\tOK: StringMonitor got RUNTIME_ERROR notification!"); } else { echo("\tKO: StringMonitor did not get " + "RUNTIME_ERROR notification!"); return 1; } } finally { messageReceived = false; if (stringMonitor != null) stringMonitor.stop(); } return 0; } /** * Test the monitor notifications. */ public int monitorNotifications() throws Exception { server = MBeanServerFactory.newMBeanServer(); MBeanServerForwarderInvocationHandler mbsfih = (MBeanServerForwarderInvocationHandler) Proxy.getInvocationHandler(server); mbsfih.setGetAttributeException( new RuntimeException("Test RuntimeException")); domain = server.getDefaultDomain(); obsObjName = ObjectName.getInstance(domain + ":type=ObservedObject"); server.registerMBean(new ObservedObject(), obsObjName); echo(">>> ----------------------------------------"); int error = counterMonitorNotification(); echo(">>> ----------------------------------------"); error += gaugeMonitorNotification(); echo(">>> ----------------------------------------"); error += stringMonitorNotification(); echo(">>> ----------------------------------------"); return error; } /* * Print message */ private static void echo(String message) { System.out.println(message); } /* * Standalone entry point. * * Run the test and report to stdout. */ public static void main (String args[]) throws Exception { System.setProperty("javax.management.builder.initial", MBeanServerBuilderImpl.class.getName()); RuntimeExceptionTest test = new RuntimeExceptionTest(); int error = test.monitorNotifications(); if (error > 0) { echo(">>> Unhappy Bye, Bye!"); throw new IllegalStateException("Test FAILED: Didn't get all " + "the notifications that were " + "expected by the test!"); } else { echo(">>> Happy Bye, Bye!"); } } /* * Wait messageReceived to be true */ synchronized void doWait() { while (!messageReceived) { try { wait(); } catch (InterruptedException e) { System.err.println("Got unexpected exception: " + e); e.printStackTrace(); break; } } } // Flag to notify that a message has been received private volatile boolean messageReceived = false; private MBeanServer server; private ObjectName obsObjName; private String domain; }