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
38import javax.management.*;
39import javax.management.monitor.*;
40
41public 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 {
48        public Integer getIntegerAttribute() {
49            return null;
50        }
51        public String getStringAttribute() {
52            return null;
53        }
54    }
55
56    // MBean interface
57    public interface ObservedObjectMBean {
58        public Integer getIntegerAttribute();
59        public String getStringAttribute();
60    }
61
62    // Notification handler
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     */
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     */
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     */
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     */
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
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     */
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     */
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