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;
010:
011: import java.lang.reflect.Method;
012: import java.util.HashMap;
013: import javax.management.AttributeNotFoundException;
014: import javax.management.InstanceNotFoundException;
015: import javax.management.MBeanException;
016: import javax.management.MBeanRegistration;
017: import javax.management.MBeanServer;
018: import javax.management.MBeanServerBuilder;
019: import javax.management.MBeanServerDelegate;
020: import javax.management.ObjectName;
021: import javax.management.ReflectionException;
022:
023: import mx4j.server.ChainedMBeanServer;
024: import mx4j.server.ChainedMBeanServerBuilder;
025: import mx4j.server.MX4JMBeanServer;
026: import mx4j.server.MX4JMBeanServerBuilder;
027: import mx4j.server.MX4JMBeanServerDelegate;
028: import test.MX4JTestCase;
029:
030: /**
031: * @version $Revision: 1.6 $
032: */
033: public class MBeanServerBuilderTest extends MX4JTestCase {
034: private static final String INITIAL_BUILDER = "javax.management.builder.initial";
035:
036: public MBeanServerBuilderTest(String s) {
037: super (s);
038: }
039:
040: public void testDefaultBuilder() throws Exception {
041: System.getProperties().remove(INITIAL_BUILDER);
042: MBeanServer server = newMBeanServer();
043: if (!(server instanceof MX4JMBeanServer))
044: fail("Wrong default server implementation");
045: }
046:
047: public void testCustomBuilder() throws Exception {
048: try {
049: System.setProperty(INITIAL_BUILDER, CustomBuilder.class
050: .getName());
051: MBeanServer server = newMBeanServer();
052: if (!(server instanceof CustomMBeanServer))
053: fail("Wrong custom server implementation");
054: if (!server.isInstanceOf(new ObjectName("JMImplementation",
055: "type", "MBeanServerDelegate"),
056: CustomDelegate.class.getName()))
057: fail("wrong delegate implementation");
058: } finally {
059: System.getProperties().remove(INITIAL_BUILDER);
060: }
061: }
062:
063: public void testMX4JunderJMXRI() throws Exception {
064: ClassLoader jmxriLoader = createJMXRIWithMX4JImplClassLoader();
065:
066: Class jmxri_c_mBeanServerFactory = jmxriLoader
067: .loadClass("javax.management.MBeanServerFactory");
068: Method jmxri_m_newMBeanServer = jmxri_c_mBeanServerFactory
069: .getMethod("newMBeanServer", new Class[0]);
070:
071: System.getProperties().remove(INITIAL_BUILDER);
072: Object jmxri_MBeanServer = jmxri_m_newMBeanServer.invoke(null,
073: new Object[0]);
074:
075: boolean isJMXRImBeanServer = jmxri_MBeanServer.getClass()
076: .getName().startsWith("com.sun.jmx.");
077: if (!isJMXRImBeanServer)
078: fail("Failed to make use of JMXRI classes");
079:
080: final ClassLoader oldContextLoader = Thread.currentThread()
081: .getContextClassLoader();
082: try {
083: System.setProperty(INITIAL_BUILDER,
084: MX4JMBeanServerBuilder.class.getName());
085: Thread.currentThread().setContextClassLoader(jmxriLoader);
086: Object mx4j_MBeanServer = jmxri_m_newMBeanServer.invoke(
087: null, new Object[0]);
088: boolean isMX4JMBeanServer = mx4j_MBeanServer.getClass()
089: .getName().startsWith("mx4j.server.");
090: if (!isMX4JMBeanServer)
091: fail("Not using MX4J as specified by javax.management.builder.initial");
092: } finally {
093: System.getProperties().remove(INITIAL_BUILDER);
094: Thread.currentThread().setContextClassLoader(
095: oldContextLoader);
096: }
097: }
098:
099: public void testChainedMBeanServerBuilder() throws Exception {
100: try {
101: System.setProperty(INITIAL_BUILDER, ComplexBuilder.class
102: .getName());
103: MBeanServer server = newMBeanServer();
104: if (!(server instanceof LoggingMBeanServer))
105: fail();
106: server.registerMBean(new Simple(), new ObjectName(
107: ":mbean=simple"));
108: Object vendor = server.getAttribute(new ObjectName(
109: "JMImplementation", "type", "MBeanServerDelegate"),
110: "ImplementationVendor");
111: if (!(vendor instanceof HashMap))
112: fail();
113: if (((HashMap) vendor).size() != 4)
114: fail();
115: } finally {
116: System.getProperties().remove(INITIAL_BUILDER);
117: }
118: }
119:
120: // Support classes
121:
122: /**
123: * This is a simple terminal builder, that is a builder that creates a full MBeanServer implementation.
124: * It cannot be used to chain other builders, it can only be used as the last builder in the chain.
125: */
126: public static class CustomBuilder extends MBeanServerBuilder {
127: public MBeanServer newMBeanServer(String defaultDomain,
128: MBeanServer outer, MBeanServerDelegate delegate) {
129: return new CustomMBeanServer(defaultDomain, outer, delegate);
130: }
131:
132: public MBeanServerDelegate newMBeanServerDelegate() {
133: return new CustomDelegate();
134: }
135: }
136:
137: /**
138: * Custom delegate class, for testing.
139: */
140: public static class CustomDelegate extends MX4JMBeanServerDelegate {
141: }
142:
143: public static class CustomMBeanServer extends MX4JMBeanServer {
144: public CustomMBeanServer(String defaultDomain,
145: MBeanServer outer, MBeanServerDelegate delegate) {
146: super (defaultDomain, outer, delegate);
147: }
148: }
149:
150: public static class ComplexBuilder extends
151: ChainedMBeanServerBuilder {
152: public ComplexBuilder() {
153: super (new LoggingBuilder(new PerformanceBuilder(
154: new MX4JMBeanServerBuilder())));
155: }
156: }
157:
158: public static class LoggingBuilder extends
159: ChainedMBeanServerBuilder {
160: public LoggingBuilder(MBeanServerBuilder chain) {
161: super (chain);
162: }
163:
164: public MBeanServer newMBeanServer(String defaultDomain,
165: MBeanServer outer, MBeanServerDelegate delegate) {
166: LoggingMBeanServer external = new LoggingMBeanServer();
167: MBeanServer nested = getMBeanServerBuilder()
168: .newMBeanServer(defaultDomain,
169: outer == null ? external : outer, delegate);
170: external.setMBeanServer(nested);
171: return external;
172: }
173: }
174:
175: public static class PerformanceBuilder extends
176: ChainedMBeanServerBuilder {
177: public PerformanceBuilder(MBeanServerBuilder chain) {
178: super (chain);
179: }
180:
181: public MBeanServer newMBeanServer(String defaultDomain,
182: MBeanServer outer, MBeanServerDelegate delegate) {
183: TimingMBeanServer external = new TimingMBeanServer();
184: MBeanServer nested = getMBeanServerBuilder()
185: .newMBeanServer(defaultDomain,
186: outer == null ? external : outer, delegate);
187: external.setMBeanServer(new InvocationCounterMBeanServer(
188: nested));
189: return external;
190: }
191: }
192:
193: public static class LoggingMBeanServer extends ChainedMBeanServer {
194: protected void setMBeanServer(MBeanServer server) {
195: super .setMBeanServer(server);
196: }
197:
198: public Object getAttribute(ObjectName objectName,
199: String attribute) throws MBeanException,
200: AttributeNotFoundException, InstanceNotFoundException,
201: ReflectionException {
202: HashMap map = (HashMap) super .getAttribute(objectName,
203: attribute);
204: map.put("logged", "logged");
205: return map;
206: }
207: }
208:
209: public static class TimingMBeanServer extends ChainedMBeanServer {
210: protected void setMBeanServer(MBeanServer server) {
211: super .setMBeanServer(server);
212: }
213:
214: public Object getAttribute(ObjectName objectName,
215: String attribute) throws MBeanException,
216: AttributeNotFoundException, InstanceNotFoundException,
217: ReflectionException {
218: long start = System.currentTimeMillis();
219: HashMap ret = (HashMap) super .getAttribute(objectName,
220: attribute);
221: long end = System.currentTimeMillis();
222: long elapsed = end - start;
223: System.out.println("Elapsed: " + elapsed);
224: ret.put("elapsed", new Long(elapsed));
225: return ret;
226: }
227: }
228:
229: public static class InvocationCounterMBeanServer extends
230: ChainedMBeanServer {
231: private ThreadLocal getAttributeCount = new ThreadLocal() {
232: protected Object initialValue() {
233: return new Long(0);
234: }
235: };
236:
237: public InvocationCounterMBeanServer(MBeanServer server) {
238: super (server);
239: }
240:
241: public Object getAttribute(ObjectName objectName,
242: String attribute) throws MBeanException,
243: AttributeNotFoundException, InstanceNotFoundException,
244: ReflectionException {
245: Long count = (Long) getAttributeCount.get();
246: count = new Long(count.longValue() + 1);
247: getAttributeCount.set(count);
248: System.out.println("Counted: " + count);
249:
250: HashMap map = new HashMap();
251: map
252: .put("result", super .getAttribute(objectName,
253: attribute));
254: map.put("count", count);
255:
256: return map;
257: }
258: }
259:
260: public interface SimpleMBean {
261: }
262:
263: public static class Simple implements SimpleMBean,
264: MBeanRegistration {
265: public ObjectName preRegister(MBeanServer server,
266: ObjectName name) throws Exception {
267: if (!(server instanceof LoggingMBeanServer))
268: fail();
269: return name;
270: }
271:
272: public void postRegister(Boolean registrationDone) {
273: }
274:
275: public void preDeregister() throws Exception {
276: }
277:
278: public void postDeregister() {
279: }
280: }
281: }
|