70624128b4
Reviewed-by: dfuchs, jfdenise
406 lines
16 KiB
Java
406 lines
16 KiB
Java
/*
|
|
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
* have any questions.
|
|
*/
|
|
|
|
/*
|
|
* @test DynamicWrapperMBeanTest
|
|
* @bug 6624232 6776225
|
|
* @summary Test the DynamicWrapperMBean interface
|
|
* @author Eamonn McManus
|
|
*/
|
|
|
|
import java.lang.management.ManagementFactory;
|
|
import javax.annotation.Resource;
|
|
import javax.management.JMX;
|
|
import javax.management.ListenerNotFoundException;
|
|
import javax.management.MBeanNotificationInfo;
|
|
import javax.management.MBeanServer;
|
|
import javax.management.Notification;
|
|
import javax.management.NotificationBroadcaster;
|
|
import javax.management.NotificationBroadcasterSupport;
|
|
import javax.management.NotificationEmitter;
|
|
import javax.management.NotificationFilter;
|
|
import javax.management.NotificationInfo;
|
|
import javax.management.NotificationListener;
|
|
import javax.management.ObjectName;
|
|
import javax.management.SendNotification;
|
|
import javax.management.StandardEmitterMBean;
|
|
import javax.management.StandardMBean;
|
|
import javax.management.modelmbean.ModelMBeanInfo;
|
|
import javax.management.modelmbean.ModelMBeanInfoSupport;
|
|
import javax.management.modelmbean.ModelMBeanOperationInfo;
|
|
import javax.management.modelmbean.RequiredModelMBean;
|
|
import static javax.management.StandardMBean.Options;
|
|
|
|
public class DynamicWrapperMBeanTest {
|
|
private static String failure;
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
wrapTest();
|
|
notifTest();
|
|
|
|
if (failure == null)
|
|
System.out.println("TEST PASSED");
|
|
else
|
|
throw new Exception("TEST FAILED: " + failure);
|
|
}
|
|
|
|
private static final Options wrappedVisOpts = new Options();
|
|
private static final Options wrappedInvisOpts = new Options();
|
|
static {
|
|
wrappedVisOpts.setWrappedObjectVisible(true);
|
|
wrappedInvisOpts.setWrappedObjectVisible(false);
|
|
}
|
|
|
|
public static interface WrappedMBean {
|
|
public void sayHello();
|
|
}
|
|
public static class Wrapped implements WrappedMBean {
|
|
public void sayHello() {
|
|
System.out.println("Hello");
|
|
}
|
|
}
|
|
|
|
private static void wrapTest() throws Exception {
|
|
if (Wrapped.class.getClassLoader() ==
|
|
StandardMBean.class.getClassLoader()) {
|
|
throw new Exception(
|
|
"TEST ERROR: Resource and StandardMBean have same ClassLoader");
|
|
}
|
|
|
|
assertEquals("Options withWrappedObjectVisible(false)",
|
|
new Options(), wrappedInvisOpts);
|
|
|
|
Wrapped resource = new Wrapped();
|
|
|
|
StandardMBean visible =
|
|
new StandardMBean(resource, WrappedMBean.class, wrappedVisOpts);
|
|
StandardMBean invisible =
|
|
new StandardMBean(resource, WrappedMBean.class, wrappedInvisOpts);
|
|
|
|
assertEquals("getResource withWrappedObjectVisible(true)",
|
|
resource, visible.getWrappedObject());
|
|
assertEquals("getResource withWrappedObjectVisible(false)",
|
|
invisible, invisible.getWrappedObject());
|
|
|
|
System.out.println("===Testing StandardMBean===");
|
|
|
|
ObjectName visibleName = new ObjectName("a:type=visible");
|
|
ObjectName invisibleName = new ObjectName("a:type=invisible");
|
|
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
|
mbs.registerMBean(visible, visibleName);
|
|
mbs.registerMBean(invisible, invisibleName);
|
|
|
|
assertEquals("ClassLoader for visible resource",
|
|
Wrapped.class.getClassLoader(),
|
|
mbs.getClassLoaderFor(visibleName));
|
|
assertEquals("ClassLoader for invisible resource",
|
|
StandardMBean.class.getClassLoader(),
|
|
mbs.getClassLoaderFor(invisibleName));
|
|
|
|
assertEquals("isInstanceOf(WrappedMBean) for visible wrapped",
|
|
true, mbs.isInstanceOf(visibleName, WrappedMBean.class.getName()));
|
|
assertEquals("isInstanceOf(WrappedMBean) for invisible wrapped",
|
|
false, mbs.isInstanceOf(invisibleName, WrappedMBean.class.getName()));
|
|
assertEquals("isInstanceOf(StandardMBean) for visible wrapped",
|
|
false, mbs.isInstanceOf(visibleName, StandardMBean.class.getName()));
|
|
assertEquals("isInstanceOf(StandardMBean) for invisible wrapped",
|
|
true, mbs.isInstanceOf(invisibleName, StandardMBean.class.getName()));
|
|
|
|
mbs.unregisterMBean(visibleName);
|
|
mbs.unregisterMBean(invisibleName);
|
|
|
|
System.out.println("===Testing RequiredModelMBean===");
|
|
|
|
// Godawful Model MBeans...
|
|
ModelMBeanOperationInfo mmboi = new ModelMBeanOperationInfo(
|
|
"say hello to the nice man", Wrapped.class.getMethod("sayHello"));
|
|
ModelMBeanInfo visibleMmbi = new ModelMBeanInfoSupport(
|
|
Wrapped.class.getName(), "Visible wrapped", null, null,
|
|
new ModelMBeanOperationInfo[] {mmboi}, null);
|
|
ModelMBeanInfo invisibleMmbi = new ModelMBeanInfoSupport(
|
|
Wrapped.class.getName(), "Invisible wrapped", null, null,
|
|
new ModelMBeanOperationInfo[] {mmboi}, null);
|
|
RequiredModelMBean visibleRmmb = new RequiredModelMBean(visibleMmbi);
|
|
RequiredModelMBean invisibleRmmb = new RequiredModelMBean(invisibleMmbi);
|
|
visibleRmmb.setManagedResource(resource, "VisibleObjectReference");
|
|
invisibleRmmb.setManagedResource(resource, "ObjectReference");
|
|
|
|
mbs.registerMBean(visibleRmmb, visibleName);
|
|
mbs.registerMBean(invisibleRmmb, invisibleName);
|
|
|
|
assertEquals("ClassLoader for visible wrapped",
|
|
Wrapped.class.getClassLoader(),
|
|
mbs.getClassLoaderFor(visibleName));
|
|
assertEquals("ClassLoader for invisible wrapped",
|
|
StandardMBean.class.getClassLoader(),
|
|
mbs.getClassLoaderFor(invisibleName));
|
|
|
|
assertEquals("isInstanceOf(WrappedMBean) for visible resource",
|
|
true, mbs.isInstanceOf(visibleName, WrappedMBean.class.getName()));
|
|
assertEquals("isInstanceOf(WrappedMBean) for invisible resource",
|
|
false, mbs.isInstanceOf(invisibleName, WrappedMBean.class.getName()));
|
|
assertEquals("isInstanceOf(RequiredModelMBean) for visible resource",
|
|
false, mbs.isInstanceOf(visibleName, RequiredModelMBean.class.getName()));
|
|
assertEquals("isInstanceOf(RequiredModelMBean) for invisible resource",
|
|
true, mbs.isInstanceOf(invisibleName, RequiredModelMBean.class.getName()));
|
|
|
|
mbs.unregisterMBean(visibleName);
|
|
mbs.unregisterMBean(invisibleName);
|
|
}
|
|
|
|
private static enum WrapType {
|
|
NBS("NotificationBroadcasterSupport"),
|
|
INJ("@Resource SendNotification"),
|
|
STD_MBEAN_NBS("StandardMBean delegating to NotificationBroadcasterSupport"),
|
|
STD_MBEAN_INJ("StandardMBean delegating to @Resource SendNotification"),
|
|
STD_MBEAN_SUB_NBS("StandardMBean subclass implementing NotificationBroadcaster"),
|
|
STD_MBEAN_SUB_INJ("StandardMBean subclass with @Resource SendNotification"),
|
|
STD_EMIT_MBEAN_NBS("StandardEmitterMBean delegating to NotificationBroadcasterSupport"),
|
|
STD_EMIT_MBEAN_INJ("StandardEmitterMBean delegating to @Resource SendNotification"),
|
|
STD_EMIT_MBEAN_SUB("StandardEmitterMBean subclass"),
|
|
STD_EMIT_MBEAN_SUB_INJ("StandardEmitterMBean subclass with @Resource SendNotification");
|
|
|
|
WrapType(String s) {
|
|
this.s = s;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return s;
|
|
}
|
|
|
|
private final String s;
|
|
}
|
|
|
|
@NotificationInfo(
|
|
types = {"foo", "bar"}
|
|
)
|
|
public static interface BroadcasterMBean {
|
|
public void send(Notification n);
|
|
}
|
|
|
|
public static class Broadcaster
|
|
extends NotificationBroadcasterSupport implements BroadcasterMBean {
|
|
public void send(Notification n) {
|
|
super.sendNotification(n);
|
|
}
|
|
}
|
|
|
|
public static interface SendNotifMBean extends BroadcasterMBean {
|
|
}
|
|
|
|
public static class SendNotif implements SendNotifMBean {
|
|
@Resource
|
|
private volatile SendNotification sendNotif;
|
|
|
|
public void send(Notification n) {
|
|
sendNotif.sendNotification(n);
|
|
}
|
|
}
|
|
|
|
public static class StdBroadcaster
|
|
extends StandardMBean
|
|
implements BroadcasterMBean, NotificationBroadcaster {
|
|
private final NotificationBroadcasterSupport nbs =
|
|
new NotificationBroadcasterSupport();
|
|
|
|
public StdBroadcaster() throws Exception {
|
|
super(BroadcasterMBean.class);
|
|
}
|
|
|
|
public void send(Notification n) {
|
|
nbs.sendNotification(n);
|
|
}
|
|
|
|
public void addNotificationListener(NotificationListener listener,
|
|
NotificationFilter filter, Object handback) {
|
|
nbs.addNotificationListener(listener, filter, handback);
|
|
}
|
|
|
|
public MBeanNotificationInfo[] getNotificationInfo() {
|
|
return null;
|
|
}
|
|
|
|
public void removeNotificationListener(NotificationListener listener)
|
|
throws ListenerNotFoundException {
|
|
nbs.removeNotificationListener(listener);
|
|
}
|
|
}
|
|
|
|
public static class StdSendNotif
|
|
extends StandardMBean implements SendNotifMBean {
|
|
@Resource
|
|
private volatile SendNotification sendNotif;
|
|
|
|
public StdSendNotif() throws Exception {
|
|
super(SendNotifMBean.class);
|
|
}
|
|
|
|
public void send(Notification n) {
|
|
sendNotif.sendNotification(n);
|
|
}
|
|
}
|
|
|
|
public static class StdEmitterBroadcaster // :-)
|
|
extends StandardEmitterMBean
|
|
implements BroadcasterMBean {
|
|
|
|
public StdEmitterBroadcaster() throws Exception {
|
|
super(BroadcasterMBean.class, null);
|
|
}
|
|
|
|
public void send(Notification n) {
|
|
super.sendNotification(n);
|
|
}
|
|
}
|
|
|
|
// This case is unlikely - if you're using @Resource SendNotification
|
|
// then there's no point in using StandardEmitterMBean, since
|
|
// StandardMBean would suffice.
|
|
public static class StdEmitterSendNotif
|
|
extends StandardEmitterMBean implements SendNotifMBean {
|
|
@Resource
|
|
private volatile SendNotification sendNotif;
|
|
|
|
public StdEmitterSendNotif() {
|
|
super(SendNotifMBean.class, null);
|
|
}
|
|
|
|
public void send(Notification n) {
|
|
sendNotif.sendNotification(n);
|
|
}
|
|
}
|
|
|
|
// Test that JMX.isNotificationSource and
|
|
// mbs.isInstanceOf("NotificationBroadcaster") work correctly even when
|
|
// the MBean is a broadcaster by virtue of its wrapped resource.
|
|
// Test that we find the MBeanNotificationInfo[] from the @NotificationInfo
|
|
// annotation on BroadcasterMBean. We cover a large number of different
|
|
// MBean types, but all ultimately implement that interface.
|
|
private static void notifTest() throws Exception {
|
|
System.out.println("===Testing notification senders===");
|
|
|
|
for (WrapType wrapType : WrapType.values()) {
|
|
System.out.println("---" + wrapType);
|
|
|
|
final Object mbean;
|
|
|
|
switch (wrapType) {
|
|
case NBS:
|
|
// An MBean that extends NotificationBroadcasterSupport
|
|
mbean = new Broadcaster();
|
|
break;
|
|
case INJ:
|
|
// An MBean that injects SendNotification
|
|
mbean = new SendNotif();
|
|
break;
|
|
case STD_MBEAN_NBS:
|
|
// A StandardMBean that delegates to a NotificationBroadcasterSupport
|
|
mbean = new StandardMBean(
|
|
new Broadcaster(), BroadcasterMBean.class, wrappedVisOpts);
|
|
break;
|
|
case STD_MBEAN_INJ:
|
|
// A StandardMBean that delegates to an object that injects
|
|
// SendNotification
|
|
mbean = new StandardMBean(
|
|
new SendNotif(), BroadcasterMBean.class, wrappedVisOpts);
|
|
break;
|
|
case STD_EMIT_MBEAN_NBS: {
|
|
// A StandardEmitterMBean that delegates to a NotificationBroadcasterSupport
|
|
Broadcaster broadcaster = new Broadcaster();
|
|
mbean = new StandardEmitterMBean(
|
|
broadcaster, BroadcasterMBean.class, wrappedVisOpts,
|
|
broadcaster);
|
|
break;
|
|
}
|
|
case STD_EMIT_MBEAN_INJ: {
|
|
// A StandardEmitterMBean that delegates to an object that injects
|
|
// SendNotification
|
|
SendNotif sendNotif = new SendNotif();
|
|
mbean = new StandardEmitterMBean(
|
|
sendNotif, BroadcasterMBean.class, wrappedVisOpts,
|
|
null);
|
|
break;
|
|
}
|
|
case STD_MBEAN_SUB_NBS:
|
|
// A subclass of StandardMBean that implements NotificationBroadcaster
|
|
mbean = new StdBroadcaster();
|
|
break;
|
|
case STD_MBEAN_SUB_INJ:
|
|
// A subclass of StandardMBean that injects SendNotification
|
|
mbean = new StdSendNotif();
|
|
break;
|
|
case STD_EMIT_MBEAN_SUB:
|
|
// A subclass of StandardEmitterMBean
|
|
mbean = new StdEmitterBroadcaster();
|
|
break;
|
|
case STD_EMIT_MBEAN_SUB_INJ:
|
|
// A subclass of StandardEmitterMBean that injects SendNotification
|
|
// (which is a rather strange thing to do and probably a user
|
|
// misunderstanding but we should do the right thing anyway).
|
|
mbean = new StdEmitterSendNotif();
|
|
break;
|
|
default:
|
|
throw new AssertionError();
|
|
}
|
|
|
|
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
|
|
|
final ObjectName name = new ObjectName("a:type=Sender");
|
|
mbs.registerMBean(mbean, name);
|
|
boolean isBroadcaster = mbs.isInstanceOf(
|
|
name, NotificationBroadcaster.class.getName());
|
|
assertEquals("JMX.isNotificationSource(mbean)",
|
|
true, JMX.isNotificationSource(mbean));
|
|
assertEquals("isInstanceOf(NotificationBroadcaster)",
|
|
true, isBroadcaster);
|
|
MBeanNotificationInfo[] mbnis =
|
|
mbs.getMBeanInfo(name).getNotifications();
|
|
assertEquals("MBeanNotificationInfo not empty",
|
|
true, (mbnis.length > 0));
|
|
|
|
mbs.unregisterMBean(name);
|
|
}
|
|
}
|
|
|
|
private static void assertEquals(String what, Object expect, Object actual) {
|
|
if (equal(expect, actual))
|
|
System.out.println("OK: " + what + " = " + expect);
|
|
else
|
|
fail(what + " should be " + expect + ", is " + actual);
|
|
}
|
|
|
|
private static boolean equal(Object x, Object y) {
|
|
if (x == y)
|
|
return true;
|
|
if (x == null || y == null)
|
|
return false;
|
|
return x.equals(y);
|
|
}
|
|
|
|
private static void fail(String why) {
|
|
failure = why;
|
|
System.out.println("FAIL: " + why);
|
|
}
|
|
}
|