001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package test.javax.management.remote;
010:
011: import java.io.IOException;
012: import java.net.MalformedURLException;
013: import java.util.Map;
014:
015: import javax.management.MBeanServer;
016: import javax.management.MBeanServerConnection;
017: import javax.management.MBeanServerNotification;
018: import javax.management.Notification;
019: import javax.management.NotificationBroadcasterSupport;
020: import javax.management.NotificationFilter;
021: import javax.management.NotificationFilterSupport;
022: import javax.management.NotificationListener;
023: import javax.management.ObjectName;
024: import javax.management.loading.MLet;
025: import javax.management.relation.MBeanServerNotificationFilter;
026: import javax.management.remote.JMXConnectionNotification;
027: import javax.management.remote.JMXConnector;
028: import javax.management.remote.JMXConnectorFactory;
029: import javax.management.remote.JMXConnectorServer;
030: import javax.management.remote.JMXConnectorServerFactory;
031: import javax.management.remote.JMXServiceURL;
032:
033: import mx4j.remote.MX4JRemoteConstants;
034: import test.MX4JTestCase;
035: import test.MutableBoolean;
036: import test.MutableInteger;
037: import test.MutableObject;
038:
039: /**
040: * @version $Revision: 1.10 $
041: */
042: public abstract class JMXNotificationsTestCase extends MX4JTestCase {
043: public JMXNotificationsTestCase(String name) {
044: super (name);
045: }
046:
047: protected void tearDown() throws Exception {
048: sleep(5000);
049: }
050:
051: public abstract JMXServiceURL createJMXConnectorServerAddress()
052: throws MalformedURLException;
053:
054: public abstract Map getEnvironment();
055:
056: public void testConnectionNotificationOpenedOnServer()
057: throws Exception {
058: JMXConnectorServer cntorServer = null;
059: try {
060: JMXServiceURL url = createJMXConnectorServerAddress();
061: cntorServer = JMXConnectorServerFactory
062: .newJMXConnectorServer(url, getEnvironment(),
063: newMBeanServer());
064: cntorServer.start();
065: sleep(5000);
066:
067: final MutableObject holder = new MutableObject(null);
068: cntorServer.addNotificationListener(
069: new NotificationListener() {
070: public void handleNotification(
071: Notification notification,
072: Object handback) {
073: holder.set(notification);
074: }
075: }, null, null);
076:
077: JMXConnectorFactory.connect(cntorServer.getAddress(),
078: getEnvironment());
079:
080: Notification notification = (Notification) holder.get();
081: if (!(notification instanceof JMXConnectionNotification))
082: fail();
083: assertEquals(notification.getType(),
084: JMXConnectionNotification.OPENED);
085: } catch (Exception x) {
086: x.printStackTrace();
087: throw x;
088: } finally {
089: if (cntorServer != null)
090: cntorServer.stop();
091: }
092: }
093:
094: public void testConnectionNotificationClosedOnServer()
095: throws Exception {
096: JMXConnectorServer cntorServer = null;
097: try {
098: JMXServiceURL url = createJMXConnectorServerAddress();
099: cntorServer = JMXConnectorServerFactory
100: .newJMXConnectorServer(url, getEnvironment(),
101: newMBeanServer());
102: cntorServer.start();
103: sleep(5000);
104:
105: final MutableObject holder = new MutableObject(null);
106: cntorServer.addNotificationListener(
107: new NotificationListener() {
108: public void handleNotification(
109: Notification notification,
110: Object handback) {
111: holder.set(notification);
112: }
113: }, null, null);
114:
115: JMXConnector cntor = JMXConnectorFactory.connect(
116: cntorServer.getAddress(), getEnvironment());
117: cntor.close();
118:
119: Notification notification = (Notification) holder.get();
120: if (!(notification instanceof JMXConnectionNotification))
121: fail();
122: assertEquals(notification.getType(),
123: JMXConnectionNotification.CLOSED);
124: } catch (Exception x) {
125: x.printStackTrace();
126: throw x;
127: } finally {
128: if (cntorServer != null)
129: cntorServer.stop();
130: }
131: }
132:
133: public void testConnectionNotificationOpenedOnClient()
134: throws Exception {
135: JMXConnectorServer cntorServer = null;
136: JMXConnector cntor = null;
137: try {
138: JMXServiceURL url = createJMXConnectorServerAddress();
139: MBeanServer server = newMBeanServer();
140: cntorServer = JMXConnectorServerFactory
141: .newJMXConnectorServer(url, getEnvironment(),
142: server);
143: cntorServer.start();
144: sleep(5000);
145:
146: final MutableObject holder = new MutableObject(null);
147: cntor = JMXConnectorFactory.newJMXConnector(cntorServer
148: .getAddress(), getEnvironment());
149: cntor.addConnectionNotificationListener(
150: new NotificationListener() {
151: public void handleNotification(
152: Notification notification,
153: Object handback) {
154: holder.set(notification);
155: }
156: }, null, null);
157:
158: cntor.connect(getEnvironment());
159:
160: JMXConnectionNotification notification = (JMXConnectionNotification) holder
161: .get();
162: assertEquals(notification.getType(),
163: JMXConnectionNotification.OPENED);
164: } catch (Exception x) {
165: x.printStackTrace();
166: throw x;
167: } finally {
168: if (cntor != null)
169: cntor.close();
170: if (cntorServer != null)
171: cntorServer.stop();
172: }
173: }
174:
175: public void testConnectionNotificationClosedOnClient()
176: throws Exception {
177: JMXConnectorServer cntorServer = null;
178: JMXConnector cntor = null;
179: try {
180: JMXServiceURL url = createJMXConnectorServerAddress();
181: MBeanServer server = newMBeanServer();
182: cntorServer = JMXConnectorServerFactory
183: .newJMXConnectorServer(url, getEnvironment(),
184: server);
185: cntorServer.start();
186: sleep(5000);
187:
188: final MutableObject holder = new MutableObject(null);
189: cntor = JMXConnectorFactory.newJMXConnector(cntorServer
190: .getAddress(), getEnvironment());
191: cntor.addConnectionNotificationListener(
192: new NotificationListener() {
193: public void handleNotification(
194: Notification notification,
195: Object handback) {
196: holder.set(notification);
197: }
198: }, null, null);
199:
200: cntor.connect(getEnvironment());
201: cntor.close();
202:
203: JMXConnectionNotification notification = (JMXConnectionNotification) holder
204: .get();
205: assertEquals(notification.getType(),
206: JMXConnectionNotification.CLOSED);
207: } catch (Exception x) {
208: x.printStackTrace();
209: throw x;
210: } finally {
211: if (cntor != null)
212: cntor.close();
213: if (cntorServer != null)
214: cntorServer.stop();
215: }
216: }
217:
218: public void testConnectionNotificationFailedOnClient()
219: throws Exception {
220: JMXServiceURL url = createJMXConnectorServerAddress();
221: MBeanServer server = newMBeanServer();
222: JMXConnectorServer cntorServer = JMXConnectorServerFactory
223: .newJMXConnectorServer(url, getEnvironment(), server);
224:
225: cntorServer.start();
226: sleep(5000);
227:
228: final MutableObject holder = new MutableObject(null);
229: long period = 1000;
230: int retries = 3;
231: try {
232: JMXConnector cntor = JMXConnectorFactory.newJMXConnector(
233: cntorServer.getAddress(), getEnvironment());
234: cntor.addConnectionNotificationListener(
235: new NotificationListener() {
236: public void handleNotification(
237: Notification notification,
238: Object handback) {
239: holder.set(notification);
240: }
241: }, null, null);
242:
243: Map clientEnv = getEnvironment();
244: clientEnv.put(
245: MX4JRemoteConstants.CONNECTION_HEARTBEAT_PERIOD,
246: new Long(period));
247: clientEnv.put(
248: MX4JRemoteConstants.CONNECTION_HEARTBEAT_RETRIES,
249: new Integer(retries));
250: cntor.connect(clientEnv);
251:
252: JMXConnectionNotification notification = (JMXConnectionNotification) holder
253: .get();
254: assertEquals(notification.getType(),
255: JMXConnectionNotification.OPENED);
256: holder.set(null);
257: } catch (Exception x) {
258: x.printStackTrace();
259: throw x;
260: } finally {
261: cntorServer.stop();
262: sleep(5000);
263: }
264:
265: // Wait for the heartbeat to send the failed notification
266: sleep((retries * 3) * period);
267:
268: JMXConnectionNotification notification = (JMXConnectionNotification) holder
269: .get();
270: assertNotNull(notification);
271: assertEquals(notification.getType(),
272: JMXConnectionNotification.FAILED);
273: }
274:
275: public void testRemoteNotificationListener() throws Exception {
276: JMXConnectorServer cntorServer = null;
277: JMXConnector cntor = null;
278: try {
279: MBeanServer server = newMBeanServer();
280:
281: JMXServiceURL url = createJMXConnectorServerAddress();
282: cntorServer = JMXConnectorServerFactory
283: .newJMXConnectorServer(url, getEnvironment(),
284: server);
285: cntorServer.start();
286: sleep(5000);
287:
288: cntor = JMXConnectorFactory.connect(cntorServer
289: .getAddress(), getEnvironment());
290: MBeanServerConnection mbsc = cntor
291: .getMBeanServerConnection();
292: ObjectName delegate = new ObjectName(
293: "JMImplementation:type=MBeanServerDelegate");
294:
295: final MutableObject holder = new MutableObject(null);
296: mbsc.addNotificationListener(delegate,
297: new NotificationListener() {
298: public void handleNotification(
299: Notification notification,
300: Object handback) {
301: holder.set(notification);
302: }
303: }, null, null);
304:
305: // Wait for notifications threads to start
306: sleep(1000);
307:
308: // Register a new MBean, it will generate a notification
309: MLet mlet = new MLet();
310: ObjectName name = new ObjectName(":mbean=mlet");
311: server.registerMBean(mlet, name);
312:
313: // Wait for notifications to arrive
314: sleep(1000);
315:
316: Notification notification = (Notification) holder.get();
317: assertEquals(notification.getType(),
318: MBeanServerNotification.REGISTRATION_NOTIFICATION);
319: holder.set(null);
320:
321: // Unregister the MBean
322: server.unregisterMBean(name);
323:
324: // Wait for notifications to arrive
325: sleep(1000);
326:
327: notification = (Notification) holder.get();
328: assertEquals(notification.getType(),
329: MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
330: holder.set(null);
331: } catch (Exception x) {
332: x.printStackTrace();
333: throw x;
334: } finally {
335: if (cntor != null)
336: cntor.close();
337: if (cntorServer != null)
338: cntorServer.stop();
339: }
340: }
341:
342: public void testNonSerializableNotifications() throws Exception {
343: JMXConnectorServer cntorServer = null;
344: JMXConnector cntor = null;
345: try {
346: MBeanServer server = newMBeanServer();
347:
348: // Register an MBean Emitter
349: ObjectName emitterName = ObjectName
350: .getInstance(":mbean=emitter");
351: MBeanEmitter emitter = new MBeanEmitter();
352: server.registerMBean(emitter, emitterName);
353:
354: JMXServiceURL url = createJMXConnectorServerAddress();
355: cntorServer = JMXConnectorServerFactory
356: .newJMXConnectorServer(url, getEnvironment(), null);
357: ObjectName cntorName = ObjectName
358: .getInstance("connector:protocol=rmi");
359: server.registerMBean(cntorServer, cntorName);
360: cntorServer.start();
361: sleep(5000);
362:
363: cntor = JMXConnectorFactory.connect(cntorServer
364: .getAddress(), getEnvironment());
365: MBeanServerConnection mbsc = cntor
366: .getMBeanServerConnection();
367: final MutableObject plainNotification = new MutableObject(
368: null);
369: mbsc.addNotificationListener(emitterName,
370: new NotificationListener() {
371: public void handleNotification(
372: Notification notification,
373: Object handback) {
374: plainNotification.set(notification);
375: }
376: }, null, null);
377:
378: final MutableObject connectionNotification = new MutableObject(
379: null);
380: cntor.addConnectionNotificationListener(
381: new NotificationListener() {
382: public void handleNotification(
383: Notification notification,
384: Object handback) {
385: connectionNotification.set(notification);
386: }
387: }, null, null);
388:
389: // Wait for notifications threads to start
390: sleep(1000);
391:
392: String type = "notification.type";
393: Notification notification = new Notification(type, this , 0);
394: // Make it non-serializable
395: notification.setUserData(this );
396: emitter.emit(notification);
397:
398: // Wait for notifications to arrive
399: sleep(1000);
400:
401: assertNull(plainNotification.get());
402: assertNotNull(connectionNotification.get());
403: assertEquals(((Notification) connectionNotification.get())
404: .getType(), JMXConnectionNotification.NOTIFS_LOST);
405: } catch (Exception x) {
406: x.printStackTrace();
407: throw x;
408: } finally {
409: if (cntor != null)
410: cntor.close();
411: if (cntorServer != null)
412: cntorServer.stop();
413: }
414: }
415:
416: public void testAddRemoveMBeanListener() throws Exception {
417: JMXConnectorServer cntorServer = null;
418: JMXConnector cntor = null;
419: try {
420: MBeanServer server = newMBeanServer();
421:
422: // Register an MBean Emitter
423: ObjectName emitterName = ObjectName
424: .getInstance(":mbean=emitter");
425: MBeanEmitter emitter = new MBeanEmitter();
426: server.registerMBean(emitter, emitterName);
427:
428: // Register an MBean Listener
429: MutableObject notificationHolder = new MutableObject(null);
430: MutableObject handbackHolder = new MutableObject(null);
431: ObjectName listenerName = ObjectName
432: .getInstance(":mbean=listener");
433: MBeanListener listener = new MBeanListener(
434: notificationHolder, handbackHolder);
435: server.registerMBean(listener, listenerName);
436:
437: JMXServiceURL url = createJMXConnectorServerAddress();
438: cntorServer = JMXConnectorServerFactory
439: .newJMXConnectorServer(url, getEnvironment(),
440: server);
441: cntorServer.start();
442: sleep(5000);
443:
444: cntor = JMXConnectorFactory.connect(cntorServer
445: .getAddress(), getEnvironment());
446: MBeanServerConnection mbsc = cntor
447: .getMBeanServerConnection();
448:
449: // Non-serializable filter
450: try {
451: mbsc.addNotificationListener(emitterName, listenerName,
452: new NotificationFilter() {
453: public boolean isNotificationEnabled(
454: Notification notification) {
455: return false;
456: }
457: }, null);
458: fail();
459: } catch (IOException x) {
460: }
461:
462: // Non-serializable handback
463: try {
464: mbsc.addNotificationListener(emitterName, listenerName,
465: null, new Object());
466: fail();
467: } catch (IOException x) {
468: }
469:
470: // Non-serializable filter and non serializable handback
471: try {
472: mbsc.addNotificationListener(emitterName, listenerName,
473: new NotificationFilter() {
474: public boolean isNotificationEnabled(
475: Notification notification) {
476: return false;
477: }
478: }, new Object());
479: fail();
480: } catch (IOException x) {
481: }
482:
483: // Everything is serializable
484: ObjectName name = ObjectName.getInstance(":mbean=dummy");
485: MBeanServerNotificationFilter filter = new MBeanServerNotificationFilter();
486: filter.disableObjectName(name);
487: Object handback = new Integer(13);
488: mbsc.addNotificationListener(emitterName, listenerName,
489: filter, handback);
490:
491: // Wait for notifications threads to start
492: sleep(1000);
493:
494: Notification notification = new MBeanServerNotification(
495: MBeanServerNotification.REGISTRATION_NOTIFICATION,
496: this , 0, name);
497: emitter.emit(notification);
498:
499: // Wait for notification to arrive
500: sleep(1000);
501:
502: // Be sure the notification has been filtered
503: assertNull(notificationHolder.get());
504: assertNull(handbackHolder.get());
505:
506: // Disable filtering
507: filter.enableAllObjectNames();
508: // Remove and readd: on server side there is a serialized copy of the filter
509: mbsc.removeNotificationListener(emitterName, listenerName);
510: mbsc.addNotificationListener(emitterName, listenerName,
511: filter, handback);
512:
513: // Wait for notifications threads to start
514: sleep(1000);
515:
516: emitter.emit(notification);
517:
518: // Wait for notification to arrive
519: sleep(1000);
520:
521: // Be sure we got it
522: assertEquals(handbackHolder.get(), handback);
523: Notification emitted = (Notification) notificationHolder
524: .get();
525: assertNotNull(emitted);
526: if (!(notification instanceof MBeanServerNotification))
527: fail();
528: assertEquals(((MBeanServerNotification) emitted)
529: .getMBeanName(), name);
530: notificationHolder.set(null);
531: handbackHolder.set(null);
532:
533: mbsc.removeNotificationListener(emitterName, listenerName,
534: filter, handback);
535:
536: // Be sure we don't get notifications anymore
537: emitter.emit(notification);
538:
539: // Wait for notification to arrive
540: sleep(1000);
541:
542: assertNull(notificationHolder.get());
543: assertNull(handbackHolder.get());
544: } catch (Exception x) {
545: x.printStackTrace();
546: throw x;
547: } finally {
548: if (cntor != null)
549: cntor.close();
550: if (cntorServer != null)
551: cntorServer.stop();
552: }
553: }
554:
555: public void testAddRemoveListenerWithNonSerializableFilter()
556: throws Exception {
557: JMXConnectorServer cntorServer = null;
558: JMXConnector cntor = null;
559: try {
560: MBeanServer server = newMBeanServer();
561:
562: // Register an MBean Emitter
563: ObjectName emitterName = ObjectName
564: .getInstance(":mbean=emitter");
565: MBeanEmitter emitter = new MBeanEmitter();
566: server.registerMBean(emitter, emitterName);
567:
568: MutableObject notificationHolder = new MutableObject(null);
569: MutableObject handbackHolder = new MutableObject(null);
570: MBeanListener listener = new MBeanListener(
571: notificationHolder, handbackHolder);
572:
573: JMXServiceURL url = createJMXConnectorServerAddress();
574: cntorServer = JMXConnectorServerFactory
575: .newJMXConnectorServer(url, getEnvironment(),
576: server);
577: cntorServer.start();
578: sleep(5000);
579:
580: cntor = JMXConnectorFactory.connect(cntorServer
581: .getAddress(), getEnvironment());
582: MBeanServerConnection mbsc = cntor
583: .getMBeanServerConnection();
584:
585: // Non-serializable filter, should run on client side
586: final MutableBoolean enable = new MutableBoolean(false);
587: NotificationFilter filter = new NotificationFilter() {
588: public boolean isNotificationEnabled(
589: Notification notification) {
590: return enable.get();
591: }
592: };
593: mbsc.addNotificationListener(emitterName, listener, filter,
594: null);
595:
596: // Wait for notification threads to start
597: sleep(1000);
598:
599: String type = "notification.type";
600: Notification notification = new Notification(type, this , 0);
601: emitter.emit(notification);
602:
603: // Wait for notification to arrive
604: sleep(1000);
605:
606: // Be sure the notification has been filtered
607: assertNull(notificationHolder.get());
608: assertNull(handbackHolder.get());
609:
610: // Disable the filter
611: enable.set(true);
612:
613: emitter.emit(notification);
614:
615: // Wait for notification to arrive
616: sleep(1000);
617:
618: // Be sure we got the notification
619: assertNull(handbackHolder.get());
620: Notification emitted = (Notification) notificationHolder
621: .get();
622: assertNotNull(emitted);
623: notificationHolder.set(null);
624: handbackHolder.set(null);
625:
626: mbsc.removeNotificationListener(emitterName, listener,
627: filter, null);
628:
629: // Be sure we don't get notifications anymore
630: emitter.emit(notification);
631:
632: // Wait for notification to arrive
633: sleep(1000);
634:
635: assertNull(notificationHolder.get());
636: assertNull(handbackHolder.get());
637: } catch (Exception x) {
638: x.printStackTrace();
639: throw x;
640: } finally {
641: if (cntor != null)
642: cntor.close();
643: if (cntorServer != null)
644: cntorServer.stop();
645: }
646: }
647:
648: public void testAddRemoveListenerWithNonSerializableHandback()
649: throws Exception {
650: JMXConnectorServer cntorServer = null;
651: JMXConnector cntor = null;
652: try {
653: MBeanServer server = newMBeanServer();
654:
655: // Register an MBean Emitter
656: ObjectName emitterName = ObjectName
657: .getInstance(":mbean=emitter");
658: MBeanEmitter emitter = new MBeanEmitter();
659: server.registerMBean(emitter, emitterName);
660:
661: MutableObject notificationHolder = new MutableObject(null);
662: MutableObject handbackHolder = new MutableObject(null);
663: MBeanListener listener = new MBeanListener(
664: notificationHolder, handbackHolder);
665:
666: JMXServiceURL url = createJMXConnectorServerAddress();
667: cntorServer = JMXConnectorServerFactory
668: .newJMXConnectorServer(url, getEnvironment(),
669: server);
670: cntorServer.start();
671: sleep(5000);
672:
673: cntor = JMXConnectorFactory.connect(cntorServer
674: .getAddress(), getEnvironment());
675: MBeanServerConnection mbsc = cntor
676: .getMBeanServerConnection();
677:
678: // Non-serializable handback, should stay on client side
679: Object handback = new Object();
680: mbsc.addNotificationListener(emitterName, listener, null,
681: handback);
682:
683: // Wait for notification threads to start
684: sleep(1000);
685:
686: String type = "notification.type";
687: Notification notification = new Notification(type, this , 0);
688: emitter.emit(notification);
689:
690: // Wait for notification to arrive
691: sleep(1000);
692:
693: // Be sure we got the notification
694: assertSame(handbackHolder.get(), handback);
695: Notification emitted = (Notification) notificationHolder
696: .get();
697: assertNotNull(emitted);
698: notificationHolder.set(null);
699: handbackHolder.set(null);
700:
701: mbsc.removeNotificationListener(emitterName, listener,
702: null, handback);
703:
704: // Be sure we don't get notifications anymore
705: emitter.emit(notification);
706:
707: // Wait for notification to arrive
708: sleep(1000);
709:
710: assertNull(notificationHolder.get());
711: assertNull(handbackHolder.get());
712: } catch (Exception x) {
713: x.printStackTrace();
714: throw x;
715: } finally {
716: if (cntor != null)
717: cntor.close();
718: if (cntorServer != null)
719: cntorServer.stop();
720: }
721: }
722:
723: public void testAddRemoveSameListenerMultipleTimesWithDifferentFiltersAndHandbacks()
724: throws Exception {
725: JMXConnectorServer cntorServer = null;
726: JMXConnector cntor = null;
727: try {
728: MBeanServer server = newMBeanServer();
729:
730: // Register an MBean Emitter
731: ObjectName emitterName = ObjectName
732: .getInstance(":mbean=emitter");
733: MBeanEmitter emitter = new MBeanEmitter();
734: server.registerMBean(emitter, emitterName);
735:
736: final MutableInteger counter1 = new MutableInteger(0);
737: NotificationListener listener1 = new NotificationListener() {
738: public void handleNotification(
739: Notification notification, Object handback) {
740: counter1.set(counter1.get() + 1);
741: }
742: };
743: final MutableInteger counter2 = new MutableInteger(0);
744: NotificationListener listener2 = new NotificationListener() {
745: public void handleNotification(
746: Notification notification, Object handback) {
747: counter2.set(counter2.get() + 1);
748: }
749: };
750:
751: JMXServiceURL url = createJMXConnectorServerAddress();
752: cntorServer = JMXConnectorServerFactory
753: .newJMXConnectorServer(url, getEnvironment(),
754: server);
755: cntorServer.start();
756: sleep(5000);
757:
758: cntor = JMXConnectorFactory.connect(cntorServer
759: .getAddress(), getEnvironment());
760: MBeanServerConnection mbsc = cntor
761: .getMBeanServerConnection();
762:
763: String type = "notification.type";
764:
765: // First listener
766: mbsc.addNotificationListener(emitterName, listener1, null,
767: null);
768: // Second listener
769: NotificationFilterSupport filter = new NotificationFilterSupport();
770: filter.enableType(type);
771: mbsc.addNotificationListener(emitterName, listener1,
772: filter, null);
773: // Third listener
774: Object handback = new Object();
775: mbsc.addNotificationListener(emitterName, listener1, null,
776: handback);
777: // Fourth listener
778: mbsc.addNotificationListener(emitterName, listener2, null,
779: null);
780:
781: // Wait for notification threads to start
782: sleep(1000);
783:
784: Notification notification = new Notification(type, this , 0);
785: emitter.emit(notification);
786: // Wait for notification to arrive
787: sleep(1000);
788:
789: // Be sure we got all notifications
790: assertEquals(counter1.get(), 3);
791: assertEquals(counter2.get(), 1);
792: counter1.set(0);
793: counter2.set(0);
794:
795: // Remove one listener
796: mbsc.removeNotificationListener(emitterName, listener1,
797: null, handback);
798:
799: emitter.emit(notification);
800: // Wait for notification to arrive
801: sleep(1000);
802:
803: assertEquals(counter1.get(), 2);
804: assertEquals(counter2.get(), 1);
805: counter1.set(0);
806: counter2.set(0);
807:
808: // Remove all listeners
809: mbsc.removeNotificationListener(emitterName, listener1);
810:
811: emitter.emit(notification);
812: // Wait for notification to arrive
813: sleep(1000);
814:
815: assertEquals(counter1.get(), 0);
816: assertEquals(counter2.get(), 1);
817: counter1.set(0);
818: counter2.set(0);
819:
820: mbsc.removeNotificationListener(emitterName, listener2);
821:
822: emitter.emit(notification);
823: // Wait for notification to arrive
824: sleep(1000);
825:
826: assertEquals(counter1.get(), 0);
827: assertEquals(counter2.get(), 0);
828: } catch (Exception x) {
829: x.printStackTrace();
830: throw x;
831: } finally {
832: if (cntor != null)
833: cntor.close();
834: if (cntorServer != null)
835: cntorServer.stop();
836: }
837: }
838:
839: public void testTwoMBeanServerConnectionsHaveSameListener()
840: throws Exception {
841: JMXConnectorServer cntorServer = null;
842: JMXConnector cntor = null;
843: try {
844: MBeanServer server = newMBeanServer();
845:
846: // Register an MBean Emitter
847: ObjectName emitterName = ObjectName
848: .getInstance(":mbean=emitter");
849: MBeanEmitter emitter = new MBeanEmitter();
850: server.registerMBean(emitter, emitterName);
851:
852: final MutableInteger counter = new MutableInteger(0);
853: NotificationListener listener = new NotificationListener() {
854: public void handleNotification(
855: Notification notification, Object handback) {
856: counter.set(counter.get() + 1);
857: }
858: };
859:
860: JMXServiceURL url = createJMXConnectorServerAddress();
861: cntorServer = JMXConnectorServerFactory
862: .newJMXConnectorServer(url, getEnvironment(),
863: server);
864: cntorServer.start();
865: sleep(5000);
866:
867: cntor = JMXConnectorFactory.connect(cntorServer
868: .getAddress(), getEnvironment());
869: MBeanServerConnection mbsc1 = cntor
870: .getMBeanServerConnection();
871:
872: mbsc1.addNotificationListener(emitterName, listener, null,
873: null);
874: // Wait for notification threads to start
875: sleep(1000);
876:
877: Notification notification = new Notification("type",
878: emitter, 0);
879: emitter.emit(notification);
880:
881: // Wait for the notification to arrive
882: sleep(1000);
883:
884: // Be sure it's received
885: assertEquals(counter.get(), 1);
886:
887: // Be sure I can remove the same listener from another MBeanServerConnection
888: MBeanServerConnection mbsc2 = cntor
889: .getMBeanServerConnection();
890: mbsc2.removeNotificationListener(emitterName, listener,
891: null, null);
892:
893: emitter.emit(notification);
894:
895: // Be sure no listeners anymore
896: assertEquals(counter.get(), 1);
897: } catch (Exception x) {
898: x.printStackTrace();
899: throw x;
900: } finally {
901: if (cntor != null)
902: cntor.close();
903: if (cntorServer != null)
904: cntorServer.stop();
905: }
906: }
907:
908: public interface MBeanListenerMBean {
909: }
910:
911: public static class MBeanListener implements NotificationListener,
912: MBeanListenerMBean {
913: private MutableObject notificationHolder;
914: private MutableObject handbackHolder;
915:
916: public MBeanListener(MutableObject notificationHolder,
917: MutableObject handbackHolder) {
918: this .notificationHolder = notificationHolder;
919: this .handbackHolder = handbackHolder;
920: }
921:
922: public void handleNotification(Notification notification,
923: Object handback) {
924: notificationHolder.set(notification);
925: handbackHolder.set(handback);
926: }
927: }
928:
929: public interface MBeanEmitterMBean {
930: public void emit(Notification notification);
931: }
932:
933: public static class MBeanEmitter extends
934: NotificationBroadcasterSupport implements MBeanEmitterMBean {
935: public void emit(Notification notification) {
936: sendNotification(notification);
937: }
938: }
939: }
|