jdk/test/javax/management/MBeanServer/DynamicWrapperMBeanTest.java
changeset 1636 eb801ce73ac9
parent 1247 b4c26443dee5
equal deleted inserted replaced
1635:8ca7ecc0226d 1636:eb801ce73ac9
    21  * have any questions.
    21  * have any questions.
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test DynamicWrapperMBeanTest
    25  * @test DynamicWrapperMBeanTest
    26  * @bug 6624232
    26  * @bug 6624232 6776225
    27  * @summary Test the DynamicWrapperMBean interface
    27  * @summary Test the DynamicWrapperMBean interface
    28  * @author Eamonn McManus
    28  * @author Eamonn McManus
    29  */
    29  */
    30 
    30 
    31 import java.lang.management.ManagementFactory;
    31 import java.lang.management.ManagementFactory;
       
    32 import javax.annotation.Resource;
       
    33 import javax.management.JMX;
       
    34 import javax.management.ListenerNotFoundException;
       
    35 import javax.management.MBeanNotificationInfo;
    32 import javax.management.MBeanServer;
    36 import javax.management.MBeanServer;
       
    37 import javax.management.Notification;
       
    38 import javax.management.NotificationBroadcaster;
       
    39 import javax.management.NotificationBroadcasterSupport;
       
    40 import javax.management.NotificationEmitter;
       
    41 import javax.management.NotificationFilter;
       
    42 import javax.management.NotificationInfo;
       
    43 import javax.management.NotificationListener;
    33 import javax.management.ObjectName;
    44 import javax.management.ObjectName;
       
    45 import javax.management.SendNotification;
       
    46 import javax.management.StandardEmitterMBean;
    34 import javax.management.StandardMBean;
    47 import javax.management.StandardMBean;
    35 import javax.management.modelmbean.ModelMBeanInfo;
    48 import javax.management.modelmbean.ModelMBeanInfo;
    36 import javax.management.modelmbean.ModelMBeanInfoSupport;
    49 import javax.management.modelmbean.ModelMBeanInfoSupport;
    37 import javax.management.modelmbean.ModelMBeanOperationInfo;
    50 import javax.management.modelmbean.ModelMBeanOperationInfo;
    38 import javax.management.modelmbean.RequiredModelMBean;
    51 import javax.management.modelmbean.RequiredModelMBean;
    39 import static javax.management.StandardMBean.Options;
    52 import static javax.management.StandardMBean.Options;
    40 
    53 
    41 public class DynamicWrapperMBeanTest {
    54 public class DynamicWrapperMBeanTest {
       
    55     private static String failure;
       
    56 
       
    57     public static void main(String[] args) throws Exception {
       
    58         wrapTest();
       
    59         notifTest();
       
    60 
       
    61         if (failure == null)
       
    62             System.out.println("TEST PASSED");
       
    63         else
       
    64             throw new Exception("TEST FAILED: " + failure);
       
    65     }
       
    66 
       
    67     private static final Options wrappedVisOpts = new Options();
       
    68     private static final Options wrappedInvisOpts = new Options();
       
    69     static {
       
    70         wrappedVisOpts.setWrappedObjectVisible(true);
       
    71         wrappedInvisOpts.setWrappedObjectVisible(false);
       
    72     }
       
    73 
    42     public static interface WrappedMBean {
    74     public static interface WrappedMBean {
    43         public void sayHello();
    75         public void sayHello();
    44     }
    76     }
    45     public static class Wrapped implements WrappedMBean {
    77     public static class Wrapped implements WrappedMBean {
    46         public void sayHello() {
    78         public void sayHello() {
    47             System.out.println("Hello");
    79             System.out.println("Hello");
    48         }
    80         }
    49     }
    81     }
    50 
    82 
    51     private static String failure;
    83     private static void wrapTest() throws Exception {
    52 
       
    53     public static void main(String[] args) throws Exception {
       
    54         if (Wrapped.class.getClassLoader() ==
    84         if (Wrapped.class.getClassLoader() ==
    55                 StandardMBean.class.getClassLoader()) {
    85                 StandardMBean.class.getClassLoader()) {
    56             throw new Exception(
    86             throw new Exception(
    57                     "TEST ERROR: Resource and StandardMBean have same ClassLoader");
    87                     "TEST ERROR: Resource and StandardMBean have same ClassLoader");
    58         }
    88         }
    59 
    89 
    60         Options wrappedVisOpts = new Options();
       
    61         wrappedVisOpts.setWrappedObjectVisible(true);
       
    62         Options wrappedInvisOpts = new Options();
       
    63         wrappedInvisOpts.setWrappedObjectVisible(false);
       
    64         assertEquals("Options withWrappedObjectVisible(false)",
    90         assertEquals("Options withWrappedObjectVisible(false)",
    65                      new Options(), wrappedInvisOpts);
    91                      new Options(), wrappedInvisOpts);
    66 
    92 
    67         Wrapped resource = new Wrapped();
    93         Wrapped resource = new Wrapped();
    68 
    94 
   136         assertEquals("isInstanceOf(RequiredModelMBean) for visible resource",
   162         assertEquals("isInstanceOf(RequiredModelMBean) for visible resource",
   137                 false, mbs.isInstanceOf(visibleName, RequiredModelMBean.class.getName()));
   163                 false, mbs.isInstanceOf(visibleName, RequiredModelMBean.class.getName()));
   138         assertEquals("isInstanceOf(RequiredModelMBean) for invisible resource",
   164         assertEquals("isInstanceOf(RequiredModelMBean) for invisible resource",
   139                 true, mbs.isInstanceOf(invisibleName, RequiredModelMBean.class.getName()));
   165                 true, mbs.isInstanceOf(invisibleName, RequiredModelMBean.class.getName()));
   140 
   166 
   141         if (failure != null)
   167         mbs.unregisterMBean(visibleName);
   142             throw new Exception("TEST FAILED: " + failure);
   168         mbs.unregisterMBean(invisibleName);
       
   169     }
       
   170 
       
   171     private static enum WrapType {
       
   172         NBS("NotificationBroadcasterSupport"),
       
   173         INJ("@Resource SendNotification"),
       
   174         STD_MBEAN_NBS("StandardMBean delegating to NotificationBroadcasterSupport"),
       
   175         STD_MBEAN_INJ("StandardMBean delegating to @Resource SendNotification"),
       
   176         STD_MBEAN_SUB_NBS("StandardMBean subclass implementing NotificationBroadcaster"),
       
   177         STD_MBEAN_SUB_INJ("StandardMBean subclass with @Resource SendNotification"),
       
   178         STD_EMIT_MBEAN_NBS("StandardEmitterMBean delegating to NotificationBroadcasterSupport"),
       
   179         STD_EMIT_MBEAN_INJ("StandardEmitterMBean delegating to @Resource SendNotification"),
       
   180         STD_EMIT_MBEAN_SUB("StandardEmitterMBean subclass"),
       
   181         STD_EMIT_MBEAN_SUB_INJ("StandardEmitterMBean subclass with @Resource SendNotification");
       
   182 
       
   183         WrapType(String s) {
       
   184             this.s = s;
       
   185         }
       
   186 
       
   187         @Override
       
   188         public String toString() {
       
   189             return s;
       
   190         }
       
   191 
       
   192         private final String s;
       
   193     }
       
   194 
       
   195     @NotificationInfo(
       
   196         types = {"foo", "bar"}
       
   197     )
       
   198     public static interface BroadcasterMBean {
       
   199         public void send(Notification n);
       
   200     }
       
   201 
       
   202     public static class Broadcaster
       
   203             extends NotificationBroadcasterSupport implements BroadcasterMBean {
       
   204         public void send(Notification n) {
       
   205             super.sendNotification(n);
       
   206         }
       
   207     }
       
   208 
       
   209     public static interface SendNotifMBean extends BroadcasterMBean {
       
   210     }
       
   211 
       
   212     public static class SendNotif implements SendNotifMBean {
       
   213         @Resource
       
   214         private volatile SendNotification sendNotif;
       
   215 
       
   216         public void send(Notification n) {
       
   217             sendNotif.sendNotification(n);
       
   218         }
       
   219     }
       
   220 
       
   221     public static class StdBroadcaster
       
   222             extends StandardMBean
       
   223             implements BroadcasterMBean, NotificationBroadcaster {
       
   224         private final NotificationBroadcasterSupport nbs =
       
   225                 new NotificationBroadcasterSupport();
       
   226 
       
   227         public StdBroadcaster() throws Exception {
       
   228             super(BroadcasterMBean.class);
       
   229         }
       
   230 
       
   231         public void send(Notification n) {
       
   232             nbs.sendNotification(n);
       
   233         }
       
   234 
       
   235         public void addNotificationListener(NotificationListener listener,
       
   236                 NotificationFilter filter, Object handback) {
       
   237             nbs.addNotificationListener(listener, filter, handback);
       
   238         }
       
   239 
       
   240         public MBeanNotificationInfo[] getNotificationInfo() {
       
   241             return null;
       
   242         }
       
   243 
       
   244         public void removeNotificationListener(NotificationListener listener)
       
   245                 throws ListenerNotFoundException {
       
   246             nbs.removeNotificationListener(listener);
       
   247         }
       
   248     }
       
   249 
       
   250     public static class StdSendNotif
       
   251             extends StandardMBean implements SendNotifMBean {
       
   252         @Resource
       
   253         private volatile SendNotification sendNotif;
       
   254 
       
   255         public StdSendNotif() throws Exception {
       
   256             super(SendNotifMBean.class);
       
   257         }
       
   258 
       
   259         public void send(Notification n) {
       
   260             sendNotif.sendNotification(n);
       
   261         }
       
   262     }
       
   263 
       
   264     public static class StdEmitterBroadcaster // :-)
       
   265             extends StandardEmitterMBean
       
   266             implements BroadcasterMBean {
       
   267 
       
   268         public StdEmitterBroadcaster() throws Exception {
       
   269             super(BroadcasterMBean.class, null);
       
   270         }
       
   271 
       
   272         public void send(Notification n) {
       
   273             super.sendNotification(n);
       
   274         }
       
   275     }
       
   276 
       
   277     // This case is unlikely - if you're using @Resource SendNotification
       
   278     // then there's no point in using StandardEmitterMBean, since
       
   279     // StandardMBean would suffice.
       
   280     public static class StdEmitterSendNotif
       
   281             extends StandardEmitterMBean implements SendNotifMBean {
       
   282         @Resource
       
   283         private volatile SendNotification sendNotif;
       
   284 
       
   285         public StdEmitterSendNotif() {
       
   286             super(SendNotifMBean.class, null);
       
   287         }
       
   288 
       
   289         public void send(Notification n) {
       
   290             sendNotif.sendNotification(n);
       
   291         }
       
   292     }
       
   293 
       
   294     // Test that JMX.isNotificationSource and
       
   295     // mbs.isInstanceOf("NotificationBroadcaster") work correctly even when
       
   296     // the MBean is a broadcaster by virtue of its wrapped resource.
       
   297     // Test that we find the MBeanNotificationInfo[] from the @NotificationInfo
       
   298     // annotation on BroadcasterMBean.  We cover a large number of different
       
   299     // MBean types, but all ultimately implement that interface.
       
   300     private static void notifTest() throws Exception {
       
   301         System.out.println("===Testing notification senders===");
       
   302 
       
   303         for (WrapType wrapType : WrapType.values()) {
       
   304             System.out.println("---" + wrapType);
       
   305 
       
   306             final Object mbean;
       
   307 
       
   308             switch (wrapType) {
       
   309             case NBS:
       
   310                 // An MBean that extends NotificationBroadcasterSupport
       
   311                 mbean = new Broadcaster();
       
   312                 break;
       
   313             case INJ:
       
   314                 // An MBean that injects SendNotification
       
   315                 mbean = new SendNotif();
       
   316                 break;
       
   317             case STD_MBEAN_NBS:
       
   318                 // A StandardMBean that delegates to a NotificationBroadcasterSupport
       
   319                 mbean = new StandardMBean(
       
   320                         new Broadcaster(), BroadcasterMBean.class, wrappedVisOpts);
       
   321                 break;
       
   322             case STD_MBEAN_INJ:
       
   323                 // A StandardMBean that delegates to an object that injects
       
   324                 // SendNotification
       
   325                 mbean = new StandardMBean(
       
   326                         new SendNotif(), BroadcasterMBean.class, wrappedVisOpts);
       
   327                 break;
       
   328             case STD_EMIT_MBEAN_NBS: {
       
   329                 // A StandardEmitterMBean that delegates to a NotificationBroadcasterSupport
       
   330                 Broadcaster broadcaster = new Broadcaster();
       
   331                 mbean = new StandardEmitterMBean(
       
   332                         broadcaster, BroadcasterMBean.class, wrappedVisOpts,
       
   333                         broadcaster);
       
   334                 break;
       
   335             }
       
   336             case STD_EMIT_MBEAN_INJ: {
       
   337                 // A StandardEmitterMBean that delegates to an object that injects
       
   338                 // SendNotification
       
   339                 SendNotif sendNotif = new SendNotif();
       
   340                 mbean = new StandardEmitterMBean(
       
   341                         sendNotif, BroadcasterMBean.class, wrappedVisOpts,
       
   342                         null);
       
   343                 break;
       
   344             }
       
   345             case STD_MBEAN_SUB_NBS:
       
   346                 // A subclass of StandardMBean that implements NotificationBroadcaster
       
   347                 mbean = new StdBroadcaster();
       
   348                 break;
       
   349             case STD_MBEAN_SUB_INJ:
       
   350                 // A subclass of StandardMBean that injects SendNotification
       
   351                 mbean = new StdSendNotif();
       
   352                 break;
       
   353             case STD_EMIT_MBEAN_SUB:
       
   354                 // A subclass of StandardEmitterMBean
       
   355                 mbean = new StdEmitterBroadcaster();
       
   356                 break;
       
   357             case STD_EMIT_MBEAN_SUB_INJ:
       
   358                 // A subclass of StandardEmitterMBean that injects SendNotification
       
   359                 // (which is a rather strange thing to do and probably a user
       
   360                 // misunderstanding but we should do the right thing anyway).
       
   361                 mbean = new StdEmitterSendNotif();
       
   362                 break;
       
   363             default:
       
   364                 throw new AssertionError();
       
   365             }
       
   366 
       
   367             MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
       
   368 
       
   369             final ObjectName name = new ObjectName("a:type=Sender");
       
   370             mbs.registerMBean(mbean, name);
       
   371             boolean isBroadcaster = mbs.isInstanceOf(
       
   372                     name, NotificationBroadcaster.class.getName());
       
   373             assertEquals("JMX.isNotificationSource(mbean)",
       
   374                     true, JMX.isNotificationSource(mbean));
       
   375             assertEquals("isInstanceOf(NotificationBroadcaster)",
       
   376                     true, isBroadcaster);
       
   377             MBeanNotificationInfo[] mbnis =
       
   378                     mbs.getMBeanInfo(name).getNotifications();
       
   379             assertEquals("MBeanNotificationInfo not empty",
       
   380                     true, (mbnis.length > 0));
       
   381 
       
   382             mbs.unregisterMBean(name);
       
   383         }
   143     }
   384     }
   144 
   385 
   145     private static void assertEquals(String what, Object expect, Object actual) {
   386     private static void assertEquals(String what, Object expect, Object actual) {
   146         if (equal(expect, actual))
   387         if (equal(expect, actual))
   147             System.out.println("OK: " + what + " = " + expect);
   388             System.out.println("OK: " + what + " = " + expect);