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 6200031 8025206
27  * @summary Test that the counter/gauge/string monitors emit a
28  *          jmx.monitor.error.type notification when the attribute
29  *          being monitored returns a null value.
30  * @author Luis-Miguel Alventosa
31  * @author Shanliang JIANG
32  *
33  * @run clean NullAttributeValueTest
34  * @run build NullAttributeValueTest
35  * @run main NullAttributeValueTest
36  */
37 
38 import javax.management.*;
39 import javax.management.monitor.*;
40 
41 public class NullAttributeValueTest implements NotificationListener {
42 
43     // Flag to notify that a message has been received
44     private volatile boolean messageReceived = false;
45 
46     // MBean class
47     public class ObservedObject implements ObservedObjectMBean {
getIntegerAttribute()48         public Integer getIntegerAttribute() {
49             return null;
50         }
getStringAttribute()51         public String getStringAttribute() {
52             return null;
53         }
54     }
55 
56     // MBean interface
57     public interface ObservedObjectMBean {
getIntegerAttribute()58         public Integer getIntegerAttribute();
getStringAttribute()59         public String getStringAttribute();
60     }
61 
62     // Notification handler
handleNotification(Notification notification, Object handback)63     public void handleNotification(Notification notification,
64                                    Object handback) {
65         MonitorNotification n = (MonitorNotification) notification;
66         echo("\tInside handleNotification...");
67         String type = n.getType();
68         try {
69             if (type.equals(
70                     MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR)) {
71                 echo("\t\t" + n.getObservedAttribute() + " is null");
72                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
73                 echo("\t\tTrigger = " + n.getTrigger());
74                 messageReceived = true;
75             } else {
76                 echo("\t\tSkipping notification of type: " + type);
77             }
78         } catch (Exception e) {
79             echo("\tError in handleNotification!");
80             e.printStackTrace(System.out);
81         }
82     }
83 
84     /**
85      * Update the counter and check for notifications
86      */
counterMonitorNotification()87     public int counterMonitorNotification() throws Exception {
88         CounterMonitor counterMonitor = null;
89         try {
90             MBeanServer server = MBeanServerFactory.newMBeanServer();
91 
92             String domain = server.getDefaultDomain();
93 
94             // Create a new CounterMonitor MBean and add it to the MBeanServer.
95             //
96             echo(">>> CREATE a new CounterMonitor MBean");
97             ObjectName counterMonitorName = new ObjectName(
98                             domain + ":type=" + CounterMonitor.class.getName());
99             counterMonitor = new CounterMonitor();
100             server.registerMBean(counterMonitor, counterMonitorName);
101 
102             echo(">>> ADD a listener to the CounterMonitor");
103             counterMonitor.addNotificationListener(this, null, null);
104 
105             //
106             // MANAGEMENT OF A STANDARD MBEAN
107             //
108 
109             echo(">>> CREATE a new ObservedObject MBean");
110 
111             ObjectName obsObjName =
112                 ObjectName.getInstance(domain + ":type=ObservedObject");
113             ObservedObject obsObj = new ObservedObject();
114             server.registerMBean(obsObj, obsObjName);
115 
116             echo(">>> SET the attributes of the CounterMonitor:");
117 
118             counterMonitor.addObservedObject(obsObjName);
119             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
120 
121             counterMonitor.setObservedAttribute("IntegerAttribute");
122             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
123 
124             counterMonitor.setNotify(true);
125             echo("\tATTRIBUTE \"NotifyFlag\"        = true");
126 
127             Integer threshold = 2;
128             counterMonitor.setInitThreshold(threshold);
129             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
130 
131             int granularityperiod = 500;
132             counterMonitor.setGranularityPeriod(granularityperiod);
133             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
134 
135             echo(">>> START the CounterMonitor");
136             counterMonitor.start();
137 
138             return checkReceived(granularityperiod, "CounterMonitor");
139         } finally {
140             if (counterMonitor != null)
141                 counterMonitor.stop();
142         }
143     }
144 
145     /**
146      * Update the gauge and check for notifications
147      */
gaugeMonitorNotification()148     public int gaugeMonitorNotification() throws Exception {
149         GaugeMonitor gaugeMonitor = null;
150         try {
151             MBeanServer server = MBeanServerFactory.newMBeanServer();
152 
153             String domain = server.getDefaultDomain();
154 
155             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
156             //
157             echo(">>> CREATE a new GaugeMonitor MBean");
158             ObjectName gaugeMonitorName = new ObjectName(
159                             domain + ":type=" + GaugeMonitor.class.getName());
160             gaugeMonitor = new GaugeMonitor();
161             server.registerMBean(gaugeMonitor, gaugeMonitorName);
162 
163             echo(">>> ADD a listener to the GaugeMonitor");
164             gaugeMonitor.addNotificationListener(this, null, null);
165 
166             //
167             // MANAGEMENT OF A STANDARD MBEAN
168             //
169 
170             echo(">>> CREATE a new ObservedObject MBean");
171 
172             ObjectName obsObjName =
173                 ObjectName.getInstance(domain + ":type=ObservedObject");
174             ObservedObject obsObj = new ObservedObject();
175             server.registerMBean(obsObj, obsObjName);
176 
177             echo(">>> SET the attributes of the GaugeMonitor:");
178 
179             gaugeMonitor.addObservedObject(obsObjName);
180             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
181 
182             gaugeMonitor.setObservedAttribute("IntegerAttribute");
183             echo("\tATTRIBUTE \"ObservedAttribute\" = IntegerAttribute");
184 
185             gaugeMonitor.setNotifyLow(false);
186             gaugeMonitor.setNotifyHigh(true);
187             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
188             echo("\tATTRIBUTE \"Notify High Flag\"  = true");
189 
190             Double highThreshold = 3.0, lowThreshold = 2.5;
191             gaugeMonitor.setThresholds(highThreshold, lowThreshold);
192             echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
193             echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
194 
195             int granularityperiod = 500;
196             gaugeMonitor.setGranularityPeriod(granularityperiod);
197             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
198 
199             echo(">>> START the GaugeMonitor");
200             gaugeMonitor.start();
201 
202             return checkReceived(granularityperiod, "GaugeMonitor");
203         } finally {
204             if (gaugeMonitor != null)
205                 gaugeMonitor.stop();
206         }
207     }
208 
209     /**
210      * Update the string and check for notifications
211      */
stringMonitorNotification()212     public int stringMonitorNotification() throws Exception {
213         StringMonitor stringMonitor = null;
214         try {
215             MBeanServer server = MBeanServerFactory.newMBeanServer();
216 
217             String domain = server.getDefaultDomain();
218 
219             // Create a new StringMonitor MBean and add it to the MBeanServer.
220             //
221             echo(">>> CREATE a new StringMonitor MBean");
222             ObjectName stringMonitorName = new ObjectName(
223                             domain + ":type=" + StringMonitor.class.getName());
224             stringMonitor = new StringMonitor();
225             server.registerMBean(stringMonitor, stringMonitorName);
226 
227             echo(">>> ADD a listener to the StringMonitor");
228             stringMonitor.addNotificationListener(this, null, null);
229 
230             //
231             // MANAGEMENT OF A STANDARD MBEAN
232             //
233 
234             echo(">>> CREATE a new ObservedObject MBean");
235 
236             ObjectName obsObjName =
237                 ObjectName.getInstance(domain + ":type=ObservedObject");
238             ObservedObject obsObj = new ObservedObject();
239             server.registerMBean(obsObj, obsObjName);
240 
241             echo(">>> SET the attributes of the StringMonitor:");
242 
243             stringMonitor.addObservedObject(obsObjName);
244             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
245 
246             stringMonitor.setObservedAttribute("StringAttribute");
247             echo("\tATTRIBUTE \"ObservedAttribute\" = StringAttribute");
248 
249             stringMonitor.setNotifyMatch(true);
250             echo("\tATTRIBUTE \"NotifyMatch\"       = true");
251 
252             stringMonitor.setNotifyDiffer(false);
253             echo("\tATTRIBUTE \"NotifyDiffer\"      = false");
254 
255             stringMonitor.setStringToCompare("do_match_now");
256             echo("\tATTRIBUTE \"StringToCompare\"   = \"do_match_now\"");
257 
258             int granularityperiod = 500;
259             stringMonitor.setGranularityPeriod(granularityperiod);
260             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
261 
262             echo(">>> START the StringMonitor");
263             stringMonitor.start();
264 
265             return checkReceived(granularityperiod, "StringMonitor");
266         } finally {
267             if (stringMonitor != null)
268                 stringMonitor.stop();
269         }
270     }
271 
272     /**
273      * Test the monitor notifications.
274      */
monitorNotifications()275     public int monitorNotifications() throws Exception {
276         echo(">>> ----------------------------------------");
277         messageReceived = false;
278         int error = counterMonitorNotification();
279         echo(">>> ----------------------------------------");
280         messageReceived = false;
281         error += gaugeMonitorNotification();
282         echo(">>> ----------------------------------------");
283         messageReceived = false;
284         error += stringMonitorNotification();
285         echo(">>> ----------------------------------------");
286         return error;
287     }
288 
checkReceived(long granularityperiod, String caller)289     private int checkReceived(long granularityperiod, String caller) throws InterruptedException {
290         int i = 100;
291         do {
292             Thread.sleep(granularityperiod);
293         } while (!messageReceived && i-- > 0);
294 
295         if (messageReceived) {
296             echo("\tOK: " + caller + " notification received");
297         } else {
298             echo("\tKO: " + caller + " notification missed or not emitted");
299         }
300 
301         return messageReceived ? 0 : 1;
302     }
303 
304     /*
305      * Print message
306      */
echo(String message)307     private static void echo(String message) {
308         System.out.println(message);
309     }
310 
311     /*
312      * Standalone entry point.
313      *
314      * Run the test and report to stdout.
315      */
main(String args[])316     public static void main (String args[]) throws Exception {
317         NullAttributeValueTest test = new NullAttributeValueTest();
318         int error = test.monitorNotifications();
319         if (error > 0) {
320             echo(">>> Unhappy Bye, Bye!");
321             throw new IllegalStateException("Test FAILED: Didn't get all " +
322                                             "the notifications that were " +
323                                             "expected by the test!");
324         } else {
325             echo(">>> Happy Bye, Bye!");
326         }
327     }
328 }
329