6e86513c3a
Update for files that have been modified starting July 2008 Reviewed-by: ohair, tbell
338 lines
11 KiB
Java
338 lines
11 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 %M% %I%
|
|
* @bug 6323980
|
|
* @summary Test MBeans defined with @MBean
|
|
* @author Eamonn McManus
|
|
* @run main/othervm -ea AnnotatedMBeanTest
|
|
*/
|
|
|
|
import java.io.File;
|
|
import java.io.PrintWriter;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.Modifier;
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import javax.management.Attribute;
|
|
import javax.management.Descriptor;
|
|
import javax.management.DescriptorKey;
|
|
import javax.management.MBeanAttributeInfo;
|
|
import javax.management.MBeanInfo;
|
|
import javax.management.MBeanOperationInfo;
|
|
import javax.management.MBeanParameterInfo;
|
|
import javax.management.MBeanServer;
|
|
import javax.management.MBeanServerFactory;
|
|
import javax.management.MXBean;
|
|
import javax.management.MalformedObjectNameException;
|
|
import javax.management.ManagedAttribute;
|
|
import javax.management.ManagedOperation;
|
|
import javax.management.MBean;
|
|
import javax.management.ObjectName;
|
|
import javax.management.openmbean.CompositeData;
|
|
import javax.management.openmbean.CompositeType;
|
|
|
|
public class AnnotatedMBeanTest {
|
|
private static MBeanServer mbs;
|
|
private static final ObjectName objectName;
|
|
static {
|
|
try {
|
|
objectName = new ObjectName("test:type=Test");
|
|
} catch (MalformedObjectNameException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
if (!AnnotatedMBeanTest.class.desiredAssertionStatus())
|
|
throw new Exception("Test must be run with -ea");
|
|
|
|
File policyFile = File.createTempFile("jmxperms", ".policy");
|
|
policyFile.deleteOnExit();
|
|
PrintWriter pw = new PrintWriter(policyFile);
|
|
pw.println("grant {");
|
|
pw.println(" permission javax.management.MBeanPermission \"*\", \"*\";");
|
|
pw.println(" permission javax.management.MBeanServerPermission \"*\";");
|
|
pw.println(" permission javax.management.MBeanTrustPermission \"*\";");
|
|
pw.println("};");
|
|
pw.close();
|
|
|
|
System.setProperty("java.security.policy", policyFile.getAbsolutePath());
|
|
System.setSecurityManager(new SecurityManager());
|
|
|
|
String failure = null;
|
|
|
|
for (Method m : AnnotatedMBeanTest.class.getDeclaredMethods()) {
|
|
if (Modifier.isStatic(m.getModifiers()) &&
|
|
m.getName().startsWith("test") &&
|
|
m.getParameterTypes().length == 0) {
|
|
mbs = MBeanServerFactory.newMBeanServer();
|
|
try {
|
|
m.invoke(null);
|
|
System.out.println(m.getName() + " OK");
|
|
} catch (InvocationTargetException ite) {
|
|
System.out.println(m.getName() + " got exception:");
|
|
Throwable t = ite.getCause();
|
|
t.printStackTrace(System.out);
|
|
failure = m.getName() + ": " + t.toString();
|
|
}
|
|
}
|
|
}
|
|
if (failure == null)
|
|
System.out.println("TEST PASSED");
|
|
else
|
|
throw new Exception("TEST FAILED: " + failure);
|
|
}
|
|
|
|
public static class Stats {
|
|
private final int used;
|
|
private final int size;
|
|
private final boolean interesting;
|
|
|
|
public Stats(int used, int size, boolean interesting) {
|
|
this.used = used;
|
|
this.size = size;
|
|
this.interesting = interesting;
|
|
}
|
|
|
|
public int getUsed() {
|
|
return used;
|
|
}
|
|
|
|
public int getSize() {
|
|
return size;
|
|
}
|
|
|
|
public boolean isInteresting() {
|
|
return interesting;
|
|
}
|
|
}
|
|
|
|
@Retention(RetentionPolicy.RUNTIME)
|
|
public static @interface Units {
|
|
@DescriptorKey("units")
|
|
String value();
|
|
}
|
|
|
|
@MBean
|
|
public static class Cache {
|
|
private int used = 23;
|
|
private int size = 99;
|
|
|
|
@ManagedAttribute
|
|
@Units("bytes")
|
|
public int getUsed() {
|
|
return used;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public int getSize() {
|
|
return size;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public void setSize(int x) {
|
|
this.size = x;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public boolean isInteresting() {
|
|
return false;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public Stats getStats() {
|
|
return new Stats(used, size, false);
|
|
}
|
|
|
|
@ManagedOperation
|
|
public int dropOldest(int n) {
|
|
return 55;
|
|
}
|
|
|
|
private void irrelevantMethod() {}
|
|
private int getIrrelevant() {return 0;}
|
|
public int getIrrelevant2() {return 0;}
|
|
|
|
public int otherIrrelevantMethod() {return 5;}
|
|
}
|
|
|
|
public static class SubCache extends Cache {
|
|
// SubCache does not have the @MBean annotation
|
|
// but its parent does. It doesn't add any @ManagedAttribute or
|
|
// @ManagedOperation methods, so its management interface
|
|
// should be the same.
|
|
private void irrelevantMethod2() {}
|
|
public int otherIrrelevantMethod3() {return 0;}
|
|
|
|
public int getX() {return 0;}
|
|
public void setX(int x) {}
|
|
}
|
|
|
|
@MXBean
|
|
public static class CacheMX {
|
|
private int used = 23;
|
|
private int size = 99;
|
|
|
|
@ManagedAttribute
|
|
@Units("bytes")
|
|
public int getUsed() {
|
|
return used;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public int getSize() {
|
|
return size;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public void setSize(int x) {
|
|
this.size = x;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public boolean isInteresting() {
|
|
return false;
|
|
}
|
|
|
|
@ManagedAttribute
|
|
public Stats getStats() {
|
|
return new Stats(used, size, false);
|
|
}
|
|
|
|
@ManagedOperation
|
|
public int dropOldest(int n) {
|
|
return 55;
|
|
}
|
|
|
|
private void irrelevantMethod() {}
|
|
private int getIrrelevant() {return 0;}
|
|
public int getIrrelevant2() {return 0;}
|
|
|
|
public int otherIrrelevantMethod() {return 5;}
|
|
}
|
|
|
|
public static class SubCacheMX extends CacheMX {
|
|
private void irrelevantMethod2() {}
|
|
public int otherIrrelevantMethod3() {return 0;}
|
|
|
|
public int getX() {return 0;}
|
|
public void setX(int x) {}
|
|
}
|
|
|
|
private static void testSimpleManagedResource() throws Exception {
|
|
testResource(new Cache(), false);
|
|
}
|
|
|
|
private static void testSubclassManagedResource() throws Exception {
|
|
testResource(new SubCache(), false);
|
|
}
|
|
|
|
private static void testMXBeanResource() throws Exception {
|
|
testResource(new CacheMX(), true);
|
|
}
|
|
|
|
private static void testSubclassMXBeanResource() throws Exception {
|
|
testResource(new SubCacheMX(), true);
|
|
}
|
|
|
|
private static void testResource(Object resource, boolean mx) throws Exception {
|
|
mbs.registerMBean(resource, objectName);
|
|
|
|
MBeanInfo mbi = mbs.getMBeanInfo(objectName);
|
|
assert mbi.getDescriptor().getFieldValue("mxbean").equals(Boolean.toString(mx));
|
|
|
|
MBeanAttributeInfo[] mbais = mbi.getAttributes();
|
|
|
|
assert mbais.length == 4: mbais.length;
|
|
|
|
for (MBeanAttributeInfo mbai : mbais) {
|
|
String name = mbai.getName();
|
|
if (name.equals("Used")) {
|
|
assert mbai.isReadable();
|
|
assert !mbai.isWritable();
|
|
assert !mbai.isIs();
|
|
assert mbai.getType().equals("int");
|
|
assert "bytes".equals(mbai.getDescriptor().getFieldValue("units"));
|
|
} else if (name.equals("Size")) {
|
|
assert mbai.isReadable();
|
|
assert mbai.isWritable();
|
|
assert !mbai.isIs();
|
|
assert mbai.getType().equals("int");
|
|
} else if (name.equals("Interesting")) {
|
|
assert mbai.isReadable();
|
|
assert !mbai.isWritable();
|
|
assert mbai.isIs();
|
|
assert mbai.getType().equals("boolean");
|
|
} else if (name.equals("Stats")) {
|
|
assert mbai.isReadable();
|
|
assert !mbai.isWritable();
|
|
assert !mbai.isIs();
|
|
Descriptor d = mbai.getDescriptor();
|
|
if (mx) {
|
|
assert mbai.getType().equals(CompositeData.class.getName());
|
|
assert d.getFieldValue("originalType").equals(Stats.class.getName());
|
|
CompositeType ct = (CompositeType) d.getFieldValue("openType");
|
|
Set<String> names = new HashSet<String>(
|
|
Arrays.asList("used", "size", "interesting"));
|
|
assert ct.keySet().equals(names) : ct.keySet();
|
|
} else {
|
|
assert mbai.getType().equals(Stats.class.getName());
|
|
}
|
|
} else
|
|
assert false : name;
|
|
}
|
|
|
|
MBeanOperationInfo[] mbois = mbi.getOperations();
|
|
|
|
assert mbois.length == 1: mbois.length;
|
|
|
|
MBeanOperationInfo mboi = mbois[0];
|
|
assert mboi.getName().equals("dropOldest");
|
|
assert mboi.getReturnType().equals("int");
|
|
MBeanParameterInfo[] mbpis = mboi.getSignature();
|
|
assert mbpis.length == 1: mbpis.length;
|
|
assert mbpis[0].getType().equals("int");
|
|
|
|
assert mbs.getAttribute(objectName, "Used").equals(23);
|
|
|
|
assert mbs.getAttribute(objectName, "Size").equals(99);
|
|
mbs.setAttribute(objectName, new Attribute("Size", 55));
|
|
assert mbs.getAttribute(objectName, "Size").equals(55);
|
|
|
|
assert mbs.getAttribute(objectName, "Interesting").equals(false);
|
|
|
|
Object stats = mbs.getAttribute(objectName, "Stats");
|
|
assert (mx ? CompositeData.class : Stats.class).isInstance(stats) : stats.getClass();
|
|
|
|
int ret = (Integer) mbs.invoke(
|
|
objectName, "dropOldest", new Object[] {66}, new String[] {"int"});
|
|
assert ret == 55;
|
|
}
|
|
}
|