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 6222961
27  * @summary Test that the counter/gauge/string monitors
28  *          support attributes of arbitrary data types.
29  * @author Luis-Miguel Alventosa
30  * @modules java.desktop
31  *          java.management
32  * @run clean AttributeArbitraryDataTypeTest
33  * @run build AttributeArbitraryDataTypeTest
34  * @run main AttributeArbitraryDataTypeTest
35  */
36 
37 import java.beans.BeanInfo;
38 import java.beans.IntrospectionException;
39 import java.beans.PropertyDescriptor;
40 import java.beans.SimpleBeanInfo;
41 import java.lang.reflect.Array;
42 import java.lang.reflect.InvocationTargetException;
43 import javax.management.AttributeNotFoundException;
44 import javax.management.MBeanServer;
45 import javax.management.MBeanServerFactory;
46 import javax.management.Notification;
47 import javax.management.NotificationListener;
48 import javax.management.ObjectName;
49 import javax.management.monitor.CounterMonitor;
50 import javax.management.monitor.GaugeMonitor;
51 import javax.management.monitor.MonitorNotification;
52 import javax.management.monitor.StringMonitor;
53 import javax.management.openmbean.CompositeData;
54 import javax.management.openmbean.CompositeDataSupport;
55 import javax.management.openmbean.CompositeType;
56 import javax.management.openmbean.OpenDataException;
57 import javax.management.openmbean.OpenType;
58 import javax.management.openmbean.SimpleType;
59 
60 public class AttributeArbitraryDataTypeTest implements NotificationListener {
61 
62     // Flag to notify that a message has been received
63     private volatile boolean counterMessageReceived = false;
64     private volatile boolean gaugeMessageReceived = false;
65     private volatile boolean stringMessageReceived = false;
66 
67     // Match enum
68     public enum Match { do_not_match_0,
69                         do_not_match_1,
70                         do_not_match_2,
71                         do_match_now };
72 
73     // MatchBeanInfo class
74     public static class MatchBeanInfo extends SimpleBeanInfo {
getPropertyDescriptors()75         public PropertyDescriptor[] getPropertyDescriptors() {
76             try {
77                 return new PropertyDescriptor[] {
78                     new PropertyDescriptor("name", Match.class, "name", null) };
79             } catch (IntrospectionException e ) {
80                 e.printStackTrace();
81                 return null;
82             }
83         }
84     }
85 
86     // ComplexAttribute class
87     public class ComplexAttribute {
88 
getIntegerAttribute()89         public Integer getIntegerAttribute() {
90             return i;
91         }
92 
setIntegerAttribute(Integer i)93         public void setIntegerAttribute(Integer i) {
94             this.i = i;
95         }
96 
getDoubleAttribute()97         public Double getDoubleAttribute() {
98             return d;
99         }
100 
setDoubleAttribute(Double d)101         public void setDoubleAttribute(Double d) {
102             this.d = d;
103         }
104 
getStringAttribute()105         public String getStringAttribute() {
106             return s;
107         }
108 
setStringAttribute(String s)109         public void setStringAttribute(String s) {
110             this.s = s;
111         }
112 
getArrayAttribute()113         public Integer[] getArrayAttribute() {
114             return a;
115         }
116 
setArrayAttribute(Integer[] a)117         public void setArrayAttribute(Integer[] a) {
118             this.a = a;
119         }
120 
getEnumAttribute()121         public Match getEnumAttribute() {
122             return e;
123         }
124 
setEnumAttribute(Match e)125         public void setEnumAttribute(Match e) {
126             this.e = e;
127         }
128 
129         private Integer i;
130         private Double d;
131         private String s;
132         private Integer[] a;
133         private Match e;
134     }
135 
136     // MBean class
137     public class ObservedObject implements ObservedObjectMBean {
138 
139         // Simple type buried in complex getter
140         //
getComplexAttribute()141         public ComplexAttribute getComplexAttribute() {
142             return ca;
143         }
144 
setComplexAttribute(ComplexAttribute ca)145         public void setComplexAttribute(ComplexAttribute ca) {
146             this.ca = ca;
147         }
148 
149         private ComplexAttribute ca = null;
150 
151         // Simple type buried in CompositeData
152         //
getCompositeDataAttribute()153         public CompositeData getCompositeDataAttribute()
154             throws OpenDataException {
155             CompositeType ct = new CompositeType("CompositeDataAttribute",
156                                                  "Composite Data Attribute",
157                                                  itemNames,
158                                                  itemDescriptions,
159                                                  itemTypes);
160             Object itemValues[] = { ia, da, sa };
161             return new CompositeDataSupport(ct, itemNames, itemValues);
162         }
163 
164         public Integer ia;
165         public Double da;
166         public String sa;
167 
168         private String itemNames[] = { "IntegerAttribute",
169                                        "DoubleAttribute",
170                                        "StringAttribute" };
171         private String itemDescriptions[] = { "Integer Attribute",
172                                               "Double Attribute",
173                                               "String Attribute" };
174         private OpenType itemTypes[] = { SimpleType.INTEGER,
175                                          SimpleType.DOUBLE,
176                                          SimpleType.STRING };
177     }
178 
179     // MBean interface
180     public interface ObservedObjectMBean {
getComplexAttribute()181         public ComplexAttribute getComplexAttribute();
setComplexAttribute(ComplexAttribute ca)182         public void setComplexAttribute(ComplexAttribute ca);
getCompositeDataAttribute()183         public CompositeData getCompositeDataAttribute()
184             throws OpenDataException;
185     }
186 
187     // Notification handler
handleNotification(Notification notification, Object handback)188     public void handleNotification(Notification notification,
189                                    Object handback) {
190         MonitorNotification n = (MonitorNotification) notification;
191         echo("\tInside handleNotification...");
192         String type = n.getType();
193         try {
194             if (type.equals(MonitorNotification.
195                             THRESHOLD_VALUE_EXCEEDED)) {
196                 echo("\t\t" + n.getObservedAttribute() +
197                      " has reached or exceeded the threshold");
198                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
199                 echo("\t\tTrigger = " + n.getTrigger());
200 
201                 synchronized (this) {
202                     counterMessageReceived = true;
203                     notifyAll();
204                 }
205             } else if (type.equals(MonitorNotification.
206                                    THRESHOLD_HIGH_VALUE_EXCEEDED)) {
207                 echo("\t\t" + n.getObservedAttribute() +
208                      " has reached or exceeded the high threshold");
209                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
210                 echo("\t\tTrigger = " + n.getTrigger());
211 
212                 synchronized (this) {
213                     gaugeMessageReceived = true;
214                     notifyAll();
215                 }
216             } else if (type.equals(MonitorNotification.
217                                    STRING_TO_COMPARE_VALUE_MATCHED)) {
218                 echo("\t\t" + n.getObservedAttribute() +
219                      " matches the string-to-compare value");
220                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
221                 echo("\t\tTrigger = " + n.getTrigger());
222 
223                 synchronized (this) {
224                     stringMessageReceived = true;
225                     notifyAll();
226                 }
227             } else {
228                 echo("\t\tSkipping notification of type: " + type);
229             }
230         } catch (Exception e) {
231             echo("\tError in handleNotification!");
232             e.printStackTrace(System.out);
233         }
234     }
235 
236     /**
237      * Update the counter and check for notifications
238      */
counterMonitorNotification(int testCase)239     public int counterMonitorNotification(int testCase)
240         throws Exception {
241 
242         counterMessageReceived = false;
243         CounterMonitor counterMonitor = null;
244         try {
245             MBeanServer server = MBeanServerFactory.newMBeanServer();
246 
247             String domain = server.getDefaultDomain();
248 
249             // Create a new CounterMonitor MBean and add it to the MBeanServer.
250             //
251             echo(">>> CREATE a new CounterMonitor MBean");
252             ObjectName counterMonitorName = new ObjectName(
253                             domain + ":type=" + CounterMonitor.class.getName());
254             counterMonitor = new CounterMonitor();
255             server.registerMBean(counterMonitor, counterMonitorName);
256 
257             echo(">>> ADD a listener to the CounterMonitor");
258             counterMonitor.addNotificationListener(this, null, null);
259 
260             //
261             // MANAGEMENT OF A STANDARD MBEAN
262             //
263 
264             echo(">>> CREATE a new ObservedObject MBean");
265 
266             ObjectName obsObjName =
267                 ObjectName.getInstance(domain + ":type=ObservedObject");
268             ObservedObject obsObj = new ObservedObject();
269             ComplexAttribute ca = new ComplexAttribute();
270             switch (testCase) {
271                 case 1:
272                     obsObj.ia = 0;
273                     break;
274                 case 2:
275                     ca.setIntegerAttribute(0);
276                     obsObj.setComplexAttribute(ca);
277                     break;
278                 case 3:
279                     ca.setArrayAttribute(new Integer[0]);
280                     obsObj.setComplexAttribute(ca);
281                     break;
282             }
283             server.registerMBean(obsObj, obsObjName);
284 
285             echo(">>> SET the attributes of the CounterMonitor:");
286 
287             counterMonitor.addObservedObject(obsObjName);
288             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
289 
290             switch (testCase) {
291                 case 1:
292                     counterMonitor.setObservedAttribute(
293                          "CompositeDataAttribute.IntegerAttribute");
294                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
295                          "CompositeDataAttribute.IntegerAttribute");
296                     break;
297                 case 2:
298                     counterMonitor.setObservedAttribute(
299                          "ComplexAttribute.integerAttribute");
300                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
301                          "ComplexAttribute.integerAttribute");
302                     break;
303                 case 3:
304                     counterMonitor.setObservedAttribute(
305                          "ComplexAttribute.arrayAttribute.length");
306                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
307                          "ComplexAttribute.arrayAttribute.length");
308                     break;
309             }
310 
311             counterMonitor.setNotify(true);
312             echo("\tATTRIBUTE \"NotifyFlag\"        = true");
313 
314             Integer threshold = 2;
315             counterMonitor.setInitThreshold(threshold);
316             echo("\tATTRIBUTE \"Threshold\"         = " + threshold);
317 
318             int granularityperiod = 500;
319             counterMonitor.setGranularityPeriod(granularityperiod);
320             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
321 
322             echo(">>> START the CounterMonitor");
323             counterMonitor.start();
324 
325             // Wait for granularity period (multiplied by 2 for sure)
326             //
327             Thread.sleep(granularityperiod * 2);
328 
329             switch (testCase) {
330                 case 1:
331                     obsObj.ia = 1;
332                     break;
333                 case 2:
334                     ca.setIntegerAttribute(1);
335                     break;
336                 case 3:
337                     ca.setArrayAttribute(new Integer[1]);
338                     break;
339             }
340 
341             // Wait for granularity period (multiplied by 2 for sure)
342             //
343             Thread.sleep(granularityperiod * 2);
344 
345             switch (testCase) {
346                 case 1:
347                     obsObj.ia = 2;
348                     break;
349                 case 2:
350                     ca.setIntegerAttribute(2);
351                     break;
352                 case 3:
353                     ca.setArrayAttribute(new Integer[2]);
354                     break;
355             }
356 
357             // Wait for granularity period (multiplied by 2 for sure)
358             //
359             Thread.sleep(granularityperiod * 2);
360 
361             switch (testCase) {
362                 case 1:
363                     obsObj.ia = 3;
364                     break;
365                 case 2:
366                     ca.setIntegerAttribute(3);
367                     break;
368                 case 3:
369                     ca.setArrayAttribute(new Integer[3]);
370                     break;
371             }
372 
373             // Check if notification was received
374             //
375             synchronized (this) {
376                 while (!counterMessageReceived) {
377                     try {
378                         wait();
379                     } catch (InterruptedException e) {
380                         System.err.println("Got unexpected exception: " + e);
381                         e.printStackTrace();
382                         break;
383                     }
384                 }
385             }
386             if (counterMessageReceived) {
387                 echo("\tOK: CounterMonitor notification received");
388             } else {
389                 echo("\tKO: CounterMonitor notification missed or not emitted");
390                 return 1;
391             }
392         } finally {
393             if (counterMonitor != null)
394                 counterMonitor.stop();
395         }
396 
397         return 0;
398     }
399 
400     /**
401      * Update the gauge and check for notifications
402      */
gaugeMonitorNotification(int testCase)403     public int gaugeMonitorNotification(int testCase)
404         throws Exception {
405 
406         gaugeMessageReceived = false;
407         GaugeMonitor gaugeMonitor = null;
408         try {
409             MBeanServer server = MBeanServerFactory.newMBeanServer();
410 
411             String domain = server.getDefaultDomain();
412 
413             // Create a new GaugeMonitor MBean and add it to the MBeanServer.
414             //
415             echo(">>> CREATE a new GaugeMonitor MBean");
416             ObjectName gaugeMonitorName = new ObjectName(
417                             domain + ":type=" + GaugeMonitor.class.getName());
418             gaugeMonitor = new GaugeMonitor();
419             server.registerMBean(gaugeMonitor, gaugeMonitorName);
420 
421             echo(">>> ADD a listener to the GaugeMonitor");
422             gaugeMonitor.addNotificationListener(this, null, null);
423 
424             //
425             // MANAGEMENT OF A STANDARD MBEAN
426             //
427 
428             echo(">>> CREATE a new ObservedObject MBean");
429 
430             ObjectName obsObjName =
431                 ObjectName.getInstance(domain + ":type=ObservedObject");
432             ObservedObject obsObj = new ObservedObject();
433             ComplexAttribute ca = new ComplexAttribute();
434             switch (testCase) {
435                 case 1:
436                     obsObj.da = 0.0;
437                     break;
438                 case 2:
439                     ca.setDoubleAttribute(0.0);
440                     obsObj.setComplexAttribute(ca);
441                     break;
442                 case 3:
443                     ca.setArrayAttribute(new Integer[0]);
444                     obsObj.setComplexAttribute(ca);
445                     break;
446             }
447             server.registerMBean(obsObj, obsObjName);
448 
449             echo(">>> SET the attributes of the GaugeMonitor:");
450 
451             gaugeMonitor.addObservedObject(obsObjName);
452             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
453 
454             switch (testCase) {
455                 case 1:
456                     gaugeMonitor.setObservedAttribute(
457                          "CompositeDataAttribute.DoubleAttribute");
458                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
459                          "CompositeDataAttribute.DoubleAttribute");
460                     break;
461                 case 2:
462                     gaugeMonitor.setObservedAttribute(
463                          "ComplexAttribute.doubleAttribute");
464                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
465                          "ComplexAttribute.doubleAttribute");
466                     break;
467                 case 3:
468                     gaugeMonitor.setObservedAttribute(
469                          "ComplexAttribute.arrayAttribute.length");
470                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
471                          "ComplexAttribute.arrayAttribute.length");
472                     break;
473             }
474 
475             gaugeMonitor.setNotifyLow(false);
476             gaugeMonitor.setNotifyHigh(true);
477             echo("\tATTRIBUTE \"Notify Low  Flag\"  = false");
478             echo("\tATTRIBUTE \"Notify High Flag\"  = true");
479 
480             switch (testCase) {
481                 case 1:
482                 case 2:
483                     Double highThresholdD = 3.0, lowThresholdD = 2.5;
484                     gaugeMonitor.setThresholds(highThresholdD, lowThresholdD);
485                     echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThresholdD);
486                     echo("\tATTRIBUTE \"High Threshold\"    = " + highThresholdD);
487                     break;
488                 case 3:
489                     Integer highThreshold = 2, lowThreshold = 1;
490                     gaugeMonitor.setThresholds(highThreshold, lowThreshold);
491                     echo("\tATTRIBUTE \"Low  Threshold\"    = " + lowThreshold);
492                     echo("\tATTRIBUTE \"High Threshold\"    = " + highThreshold);
493                     break;
494             }
495 
496             int granularityperiod = 500;
497             gaugeMonitor.setGranularityPeriod(granularityperiod);
498             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
499 
500             echo(">>> START the GaugeMonitor");
501             gaugeMonitor.start();
502 
503             // Wait for granularity period (multiplied by 2 for sure)
504             //
505             Thread.sleep(granularityperiod * 2);
506 
507             switch (testCase) {
508                 case 1:
509                     obsObj.da = 2.0;
510                     break;
511                 case 2:
512                     ca.setDoubleAttribute(2.0);
513                     break;
514                 case 3:
515                     ca.setArrayAttribute(new Integer[2]);
516                     break;
517             }
518 
519             // Wait for granularity period (multiplied by 2 for sure)
520             //
521             Thread.sleep(granularityperiod * 2);
522 
523             switch (testCase) {
524                 case 1:
525                     obsObj.da = 4.0;
526                     break;
527                 case 2:
528                     ca.setDoubleAttribute(4.0);
529                     break;
530                 case 3:
531                     ca.setArrayAttribute(new Integer[4]);
532                     break;
533             }
534 
535             // Wait for granularity period (multiplied by 2 for sure)
536             //
537             Thread.sleep(granularityperiod * 2);
538 
539             switch (testCase) {
540                 case 1:
541                     obsObj.da = 6.0;
542                     break;
543                 case 2:
544                     ca.setDoubleAttribute(6.0);
545                     break;
546                 case 3:
547                     ca.setArrayAttribute(new Integer[6]);
548                     break;
549             }
550 
551             // Check if notification was received
552             //
553             synchronized (this) {
554                 while (!gaugeMessageReceived) {
555                     try {
556                         wait();
557                     } catch (InterruptedException e) {
558                         System.err.println("Got unexpected exception: " + e);
559                         e.printStackTrace();
560                         break;
561                     }
562                 }
563             }
564             if (gaugeMessageReceived) {
565                 echo("\tOK: GaugeMonitor notification received");
566             } else {
567                 echo("\tKO: GaugeMonitor notification missed or not emitted");
568                 return 1;
569             }
570         } finally {
571             if (gaugeMonitor != null)
572                 gaugeMonitor.stop();
573         }
574 
575         return 0;
576     }
577 
578     /**
579      * Update the string and check for notifications
580      */
stringMonitorNotification(int testCase)581     public int stringMonitorNotification(int testCase)
582         throws Exception {
583 
584         stringMessageReceived = false;
585         StringMonitor stringMonitor = null;
586         try {
587             MBeanServer server = MBeanServerFactory.newMBeanServer();
588 
589             String domain = server.getDefaultDomain();
590 
591             // Create a new StringMonitor MBean and add it to the MBeanServer.
592             //
593             echo(">>> CREATE a new StringMonitor MBean");
594             ObjectName stringMonitorName = new ObjectName(
595                             domain + ":type=" + StringMonitor.class.getName());
596             stringMonitor = new StringMonitor();
597             server.registerMBean(stringMonitor, stringMonitorName);
598 
599             echo(">>> ADD a listener to the StringMonitor");
600             stringMonitor.addNotificationListener(this, null, null);
601 
602             //
603             // MANAGEMENT OF A STANDARD MBEAN
604             //
605 
606             echo(">>> CREATE a new ObservedObject MBean");
607 
608             ObjectName obsObjName =
609                 ObjectName.getInstance(domain + ":type=ObservedObject");
610             ObservedObject obsObj = new ObservedObject();
611             ComplexAttribute ca = new ComplexAttribute();
612             switch (testCase) {
613                 case 1:
614                     obsObj.sa = "do_not_match_0";
615                     break;
616                 case 2:
617                     ca.setStringAttribute("do_not_match_0");
618                     obsObj.setComplexAttribute(ca);
619                     break;
620                 case 3:
621                     ca.setEnumAttribute(Match.do_not_match_0);
622                     obsObj.setComplexAttribute(ca);
623                     break;
624             }
625             server.registerMBean(obsObj, obsObjName);
626 
627             echo(">>> SET the attributes of the StringMonitor:");
628 
629             stringMonitor.addObservedObject(obsObjName);
630             echo("\tATTRIBUTE \"ObservedObject\"    = " + obsObjName);
631 
632             switch (testCase) {
633                 case 1:
634                     stringMonitor.setObservedAttribute(
635                          "CompositeDataAttribute.StringAttribute");
636                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
637                          "CompositeDataAttribute.StringAttribute");
638                     break;
639                 case 2:
640                     stringMonitor.setObservedAttribute(
641                          "ComplexAttribute.stringAttribute");
642                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
643                          "ComplexAttribute.stringAttribute");
644                     break;
645                 case 3:
646                     stringMonitor.setObservedAttribute(
647                          "ComplexAttribute.enumAttribute.name");
648                     echo("\tATTRIBUTE \"ObservedAttribute\" = " +
649                          "ComplexAttribute.enumAttribute.name");
650                     break;
651             }
652 
653             stringMonitor.setNotifyMatch(true);
654             echo("\tATTRIBUTE \"NotifyMatch\"       = true");
655 
656             stringMonitor.setNotifyDiffer(false);
657             echo("\tATTRIBUTE \"NotifyDiffer\"      = false");
658 
659             stringMonitor.setStringToCompare("do_match_now");
660             echo("\tATTRIBUTE \"StringToCompare\"   = \"do_match_now\"");
661 
662             int granularityperiod = 500;
663             stringMonitor.setGranularityPeriod(granularityperiod);
664             echo("\tATTRIBUTE \"GranularityPeriod\" = " + granularityperiod);
665 
666             echo(">>> START the StringMonitor");
667             stringMonitor.start();
668 
669             // Wait for granularity period (multiplied by 2 for sure)
670             //
671             Thread.sleep(granularityperiod * 2);
672 
673             switch (testCase) {
674                 case 1:
675                     obsObj.sa = "do_not_match_1";
676                     break;
677                 case 2:
678                     ca.setStringAttribute("do_not_match_1");
679                     break;
680                 case 3:
681                     ca.setEnumAttribute(Match.do_not_match_1);
682                     break;
683             }
684 
685             // Wait for granularity period (multiplied by 2 for sure)
686             //
687             Thread.sleep(granularityperiod * 2);
688 
689             switch (testCase) {
690                 case 1:
691                     obsObj.sa = "do_match_now";
692                     break;
693                 case 2:
694                     ca.setStringAttribute("do_match_now");
695                     break;
696                 case 3:
697                     ca.setEnumAttribute(Match.do_match_now);
698                     break;
699             }
700 
701             // Wait for granularity period (multiplied by 2 for sure)
702             //
703             Thread.sleep(granularityperiod * 2);
704 
705             switch (testCase) {
706                 case 1:
707                     obsObj.sa = "do_not_match_2";
708                     break;
709                 case 2:
710                     ca.setStringAttribute("do_not_match_2");
711                     break;
712                 case 3:
713                     ca.setEnumAttribute(Match.do_not_match_2);
714                     break;
715             }
716 
717             // Check if notification was received
718             //
719             synchronized (this) {
720                 while (!stringMessageReceived) {
721                     try {
722                         wait();
723                     } catch (InterruptedException e) {
724                         System.err.println("Got unexpected exception: " + e);
725                         e.printStackTrace();
726                         break;
727                     }
728                 }
729             }
730             if (stringMessageReceived) {
731                 echo("\tOK: StringMonitor notification received");
732             } else {
733                 echo("\tKO: StringMonitor notification missed or not emitted");
734                 return 1;
735             }
736         } finally {
737             if (stringMonitor != null)
738                 stringMonitor.stop();
739         }
740 
741         return 0;
742     }
743 
744     /**
745      * Test the monitor notifications.
746      */
monitorNotifications()747     public int monitorNotifications() throws Exception {
748         echo(">>> ----------------------------------------");
749         int error = counterMonitorNotification(1);
750         echo(">>> ----------------------------------------");
751         error += counterMonitorNotification(2);
752         echo(">>> ----------------------------------------");
753         error += counterMonitorNotification(3);
754         echo(">>> ----------------------------------------");
755         error += gaugeMonitorNotification(1);
756         echo(">>> ----------------------------------------");
757         error += gaugeMonitorNotification(2);
758         echo(">>> ----------------------------------------");
759         error += gaugeMonitorNotification(3);
760         echo(">>> ----------------------------------------");
761         error += stringMonitorNotification(1);
762         echo(">>> ----------------------------------------");
763         error += stringMonitorNotification(2);
764         echo(">>> ----------------------------------------");
765         error += stringMonitorNotification(3);
766         echo(">>> ----------------------------------------");
767         return error;
768     }
769 
770     /*
771      * Print message
772      */
echo(String message)773     private static void echo(String message) {
774         System.out.println(message);
775     }
776 
elementFromComplex(Object complex, String element)777     public static Object elementFromComplex(Object complex, String element)
778     throws AttributeNotFoundException {
779         try {
780             if (complex.getClass().isArray() && element.equals("length")) {
781                 return Array.getLength(complex);
782             } else if (complex instanceof CompositeData) {
783                 return ((CompositeData) complex).get(element);
784             } else {
785                 // Java Beans introspection
786                 //
787                 BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass());
788                 PropertyDescriptor[] pds = bi.getPropertyDescriptors();
789                 System.out.println("PDs: " + pds.length);
790                 for (PropertyDescriptor pd : pds) {
791                     System.out.println("Property: " + pd.getName());
792                     if (pd.getName().equals(element))
793                         return pd.getReadMethod().invoke(complex);
794                 }
795                 throw new AttributeNotFoundException(
796                     "Could not find the getter method for the property " +
797                     element + " using the Java Beans introspector");
798             }
799         } catch (InvocationTargetException e) {
800             throw new IllegalArgumentException(e);
801         } catch (AttributeNotFoundException e) {
802             throw e;
803         } catch (Exception e) {
804             AttributeNotFoundException anfe =
805                 new AttributeNotFoundException(e.getMessage());
806             anfe.initCause(e);
807             throw anfe;
808         }
809     }
810 
811     /*
812      * Standalone entry point.
813      *
814      * Run the test and report to stdout.
815      */
main(String args[])816     public static void main (String args[]) throws Exception {
817         Match match = Match.do_match_now;
818         String name = (String) elementFromComplex(match, "name");
819         System.out.println("name: " + name);
820         AttributeArbitraryDataTypeTest test =
821             new AttributeArbitraryDataTypeTest();
822         int error = test.monitorNotifications();
823         if (error > 0) {
824             echo(">>> Unhappy Bye, Bye!");
825             throw new IllegalStateException("Test FAILED: Didn't get all " +
826                                             "the notifications that were " +
827                                             "expected by the test!");
828         } else {
829             echo(">>> Happy Bye, Bye!");
830         }
831     }
832 }
833