001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package test.implementation.util;
023:
024: import java.util.Set;
025:
026: import java.lang.reflect.Method;
027:
028: import javax.management.Attribute;
029: import javax.management.AttributeNotFoundException;
030: import javax.management.DynamicMBean;
031: import javax.management.InstanceNotFoundException;
032: import javax.management.MBeanServer;
033: import javax.management.MBeanServerFactory;
034: import javax.management.ObjectInstance;
035: import javax.management.ObjectName;
036:
037: import javax.management.modelmbean.ModelMBean;
038: import javax.management.modelmbean.RequiredModelMBean;
039:
040: import test.implementation.util.support.Trivial;
041: import test.implementation.util.support.TrivialMBean;
042: import test.implementation.util.support.Trivial2;
043: import test.implementation.util.support.Trivial2MBean;
044: import test.implementation.util.support.ExtendedResource;
045: import test.implementation.util.support.MyInterface;
046: import test.implementation.util.support.MyInterface2;
047: import test.implementation.util.support.Resource;
048: import test.implementation.util.support.ResourceOverride;
049: import test.implementation.util.support.ResourceIncorrectInfo;
050:
051: import junit.framework.TestCase;
052:
053: import org.jboss.mx.util.AgentID;
054: import org.jboss.mx.util.DefaultExceptionHandler;
055: import org.jboss.mx.util.MBeanProxy;
056: import org.jboss.mx.util.ProxyContext;
057:
058: import org.jboss.mx.modelmbean.XMBean;
059:
060: /**
061: * Tests for mbean proxy
062: *
063: * @author <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
064: * @version $Revision: 57200 $
065: */
066: public class MBeanProxyTEST extends TestCase {
067: public MBeanProxyTEST(String s) {
068: super (s);
069: }
070:
071: public void testGetWithServer() throws Exception {
072: MBeanServer server = MBeanServerFactory.createMBeanServer();
073: ObjectName oname = new ObjectName("test:name=test");
074:
075: server.registerMBean(new Trivial(), oname);
076:
077: TrivialMBean mbean = (TrivialMBean) MBeanProxy.get(
078: TrivialMBean.class, oname, server);
079:
080: mbean.doOperation();
081: }
082:
083: public void testGetWithAgentID() throws Exception {
084: MBeanServer server = MBeanServerFactory.createMBeanServer();
085: String agentID = AgentID.get(server);
086: ObjectName oname = new ObjectName("test:name=test");
087:
088: server.registerMBean(new Trivial(), oname);
089:
090: TrivialMBean mbean = (TrivialMBean) MBeanProxy.get(
091: TrivialMBean.class, oname, agentID);
092:
093: mbean.doOperation();
094: }
095:
096: public void testCreateWithServer() throws Exception {
097: MBeanServer server = MBeanServerFactory.createMBeanServer();
098: ObjectName oname = new ObjectName("test:test=test");
099:
100: TrivialMBean mbean = (TrivialMBean) MBeanProxy.create(
101: Trivial.class, TrivialMBean.class, oname, server);
102:
103: mbean.doOperation();
104: }
105:
106: public void testCreateWithAgentID() throws Exception {
107: MBeanServer server = MBeanServerFactory.createMBeanServer();
108: ObjectName oname = new ObjectName("test:test=test");
109: String agentID = AgentID.get(server);
110:
111: TrivialMBean mbean = (TrivialMBean) MBeanProxy.create(
112: Trivial.class, TrivialMBean.class, oname, agentID);
113:
114: mbean.doOperation();
115: }
116:
117: public void testProxyInvocations() throws Exception {
118: MBeanServer server = MBeanServerFactory.createMBeanServer();
119: ObjectName oname = new ObjectName("test:name=test");
120:
121: server.registerMBean(new Trivial(), oname);
122:
123: TrivialMBean mbean = (TrivialMBean) MBeanProxy.get(
124: TrivialMBean.class, oname, AgentID.get(server));
125:
126: mbean.doOperation();
127: mbean.setSomething("JBossMX");
128:
129: assertEquals("JBossMX", mbean.getSomething());
130: }
131:
132: public void testProxyInvocationWithConflictingMBeanAndContextMethods()
133: throws Exception {
134: MBeanServer server = MBeanServerFactory.createMBeanServer();
135: ObjectName oname = new ObjectName("test:test=test");
136:
137: server.registerMBean(new Trivial(), oname);
138:
139: TrivialMBean mbean = (TrivialMBean) MBeanProxy.get(
140: TrivialMBean.class, oname, AgentID.get(server));
141:
142: mbean.getMBeanServer();
143: assertTrue(mbean.isGMSInvoked());
144: }
145:
146: public void testContextAccess() throws Exception {
147: MBeanServer server = MBeanServerFactory.createMBeanServer();
148: ObjectName oname = new ObjectName("test:test=test");
149:
150: Trivial2MBean mbean = (Trivial2MBean) MBeanProxy.create(
151: Trivial2.class, Trivial2MBean.class, oname, server);
152:
153: ProxyContext ctx = (ProxyContext) mbean;
154:
155: ctx.getMBeanServer();
156: }
157:
158: public void testProxyInvocationBetweenServers() throws Exception {
159: MBeanServer server1 = MBeanServerFactory.createMBeanServer();
160: MBeanServer server2 = MBeanServerFactory.createMBeanServer();
161: ObjectName oname1 = new ObjectName("test:name=target");
162: ObjectName oname2 = new ObjectName("test:name=proxy");
163:
164: // createMBean on server1 and retrieve a proxy to it
165: Trivial2MBean mbean = (Trivial2MBean) MBeanProxy.create(
166: Trivial2.class, Trivial2MBean.class, oname1, server1);
167:
168: //bind the proxy to server2
169: server2.registerMBean(mbean, oname2);
170:
171: // invoke on server2
172: server2.invoke(oname2, "doOperation", null, null);
173:
174: // check that server1 received the invocation
175: assertTrue(((Boolean) server1.getAttribute(oname1,
176: "OperationInvoked")).booleanValue());
177: }
178:
179: public void testSimultaneousTypedAndDetypedInvocations()
180: throws Exception {
181: MBeanServer server = MBeanServerFactory.createMBeanServer();
182: ObjectName oname = new ObjectName("test:test=test");
183:
184: Trivial2MBean mbean = (Trivial2MBean) MBeanProxy.create(
185: Trivial2.class, Trivial2MBean.class, oname, server);
186:
187: // typed proxy interface
188: mbean.setSomething("Kissa");
189: assertTrue(mbean.getSomething().equals("Kissa"));
190:
191: // detyped proxy interface
192: DynamicMBean mbean2 = (DynamicMBean) mbean;
193: mbean2.setAttribute(new Attribute("Something", "Koira"));
194: assertTrue(mbean2.getAttribute("Something").equals("Koira"));
195:
196: // direct local server invocation
197: server.setAttribute(oname, new Attribute("Something", "Kissa"));
198: assertTrue(server.getAttribute(oname, "Something").equals(
199: "Kissa"));
200:
201: // typed proxy interface invocation
202: mbean.doOperation();
203: assertTrue(mbean.isOperationInvoked());
204:
205: mbean.reset();
206:
207: // detyped proxy invocation
208: mbean2.invoke("doOperation", null, null);
209: assertTrue(((Boolean) mbean2.getAttribute("OperationInvoked"))
210: .booleanValue());
211:
212: mbean2.invoke("reset", null, null);
213:
214: // direct local server invocation
215: server.invoke(oname, "doOperation", null, null);
216: assertTrue(((Boolean) server.getAttribute(oname,
217: "OperationInvoked")).booleanValue());
218: }
219:
220: public void testContextAccessToMBeanServer() throws Exception {
221: MBeanServer server = MBeanServerFactory.createMBeanServer();
222: ObjectName oname = new ObjectName("test:test=test");
223:
224: Trivial2MBean mbean = (Trivial2MBean) MBeanProxy.create(
225: Trivial2.class, Trivial2MBean.class, oname, server);
226:
227: // query the server this mbean is registered to
228: ProxyContext ctx = (ProxyContext) mbean;
229: MBeanServer srvr = ctx.getMBeanServer();
230:
231: Set mbeans = srvr.queryMBeans(new ObjectName("test:*"), null);
232: ObjectInstance oi = (ObjectInstance) mbeans.iterator().next();
233:
234: assertTrue(oi.getObjectName().equals(oname));
235:
236: assertTrue(srvr.getAttribute(
237: new ObjectName(
238: "JMImplementation:type=MBeanServerDelegate"),
239: "ImplementationName").equals("JBossMX"));
240:
241: }
242:
243: public void testArbitraryInterfaceWithProxy() throws Exception {
244: MBeanServer server = MBeanServerFactory.createMBeanServer();
245: ObjectName oname = new ObjectName("test:test=test");
246:
247: RequiredModelMBean rmm = new RequiredModelMBean();
248: Resource resource = new Resource();
249:
250: rmm.setManagedResource(resource, "ObjectReference");
251: rmm.setModelMBeanInfo(resource.getMBeanInfo());
252:
253: server.registerMBean(rmm, oname);
254:
255: MyInterface mbean = (MyInterface) MBeanProxy.get(
256: MyInterface.class, oname, server);
257:
258: mbean.setAttributeName("foo");
259: mbean.setAttributeName2("bar");
260:
261: assertTrue(mbean.getAttributeName2().equals("bar"));
262: assertTrue(mbean.doOperation().equals("tamppi"));
263: }
264:
265: /**
266: * This test shows how to override the default exception handling for
267: * proxy invocations. The default handling for exceptions that are not
268: * declared as part of the proxy typed interface (such as InstanceNotFound
269: * or AttributeNotFound exceptions) are rethrown as unchecked
270: * RuntimeProxyExceptions. See org.jboss.mx.proxy.DefaultExceptionHandler
271: * for details. This behavior can be changed at runtime through the proxy
272: * context interface setExceptionHandler() method.
273: */
274: public void testCustomExceptionHandler() throws Exception {
275: MBeanServer server = MBeanServerFactory.createMBeanServer();
276: ObjectName oname = new ObjectName("test:test=test");
277: ObjectName oname2 = new ObjectName("test:test=test2");
278:
279: RequiredModelMBean rmm = new RequiredModelMBean();
280: Resource resource = new Resource();
281:
282: rmm.setManagedResource(resource, "ObjectReference");
283: rmm.setModelMBeanInfo(resource.getMBeanInfo());
284:
285: // create two identical mbeans
286: server.registerMBean(rmm, oname);
287: server.registerMBean(rmm, oname2);
288:
289: ProxyContext ctx = (ProxyContext) MBeanProxy.get(
290: MyInterface.class, oname, server);
291:
292: // override InstanceNotFound exception to redirect from test=test instance
293: // to test=test2 instance
294: ctx.setExceptionHandler(new DefaultExceptionHandler() {
295: public Object handleInstanceNotFound(ProxyContext proxyCtx,
296: InstanceNotFoundException e, Method m, Object[] args)
297: throws Exception {
298: return proxyCtx.getMBeanServer().invoke(
299: new ObjectName("test:test=test2"), m.getName(),
300: args, null);
301: }
302: });
303:
304: // unregister mbean 1
305: server.unregisterMBean(oname);
306:
307: // invocation attempt to mbean1 should now redirect to mbean2
308: MyInterface mbean = (MyInterface) ctx;
309: assertTrue(mbean.doOperation().equals("tamppi"));
310: }
311:
312: public void testObjectToStringOnProxy() throws Exception {
313: MBeanServer server = MBeanServerFactory.createMBeanServer();
314: ObjectName oname = new ObjectName("test:test=test");
315:
316: RequiredModelMBean rmm = new RequiredModelMBean();
317: Resource resource = new Resource();
318:
319: rmm.setManagedResource(resource, "ObjectReference");
320: rmm.setModelMBeanInfo(resource.getMBeanInfo());
321:
322: server.registerMBean(rmm, oname);
323:
324: MyInterface mbean = (MyInterface) MBeanProxy.get(
325: MyInterface.class, oname, server);
326:
327: mbean.toString();
328:
329: Object o = (Object) mbean;
330: o.toString();
331: }
332:
333: public void testObjectToStringOverride() throws Exception {
334: MBeanServer server = MBeanServerFactory.createMBeanServer();
335: ObjectName oname = new ObjectName("test:test=test");
336:
337: RequiredModelMBean rmm = new RequiredModelMBean();
338: ResourceOverride resource = new ResourceOverride();
339:
340: rmm.setManagedResource(resource, "ObjectReference");
341: rmm.setModelMBeanInfo(resource.getMBeanInfo());
342:
343: server.registerMBean(rmm, oname);
344:
345: MyInterface mbean = (MyInterface) MBeanProxy.get(
346: MyInterface.class, oname, server);
347:
348: assertTrue(mbean.toString().equals("Resource"));
349: Object o = (Object) mbean;
350: assertTrue(o.toString().equals("Resource"));
351: }
352:
353: public void testObjectHashCodeOnProxy() throws Exception {
354: MBeanServer server = MBeanServerFactory.createMBeanServer();
355: ObjectName oname = new ObjectName("test:test=test");
356:
357: RequiredModelMBean rmm = new RequiredModelMBean();
358: Resource resource = new Resource();
359:
360: rmm.setManagedResource(resource, "ObjectReference");
361: rmm.setModelMBeanInfo(resource.getMBeanInfo());
362:
363: server.registerMBean(rmm, oname);
364:
365: MyInterface mbean = (MyInterface) MBeanProxy.get(
366: MyInterface.class, oname, server);
367:
368: mbean.hashCode();
369:
370: Object o = (Object) mbean;
371: o.toString();
372: }
373:
374: public void testObjectHashCodeOverride() throws Exception {
375: MBeanServer server = MBeanServerFactory.createMBeanServer();
376: ObjectName oname = new ObjectName("test:test=test");
377:
378: RequiredModelMBean rmm = new RequiredModelMBean();
379: ResourceOverride resource = new ResourceOverride();
380:
381: rmm.setManagedResource(resource, "ObjectReference");
382: rmm.setModelMBeanInfo(resource.getMBeanInfo());
383:
384: server.registerMBean(rmm, oname);
385:
386: MyInterface mbean = (MyInterface) MBeanProxy.get(
387: MyInterface.class, oname, server);
388:
389: assertTrue(mbean.hashCode() == 10);
390: Object o = (Object) mbean;
391: assertTrue(o.hashCode() == 10);
392: }
393:
394: public void testObjectEqualsOnProxy() throws Exception {
395: MBeanServer server = MBeanServerFactory.createMBeanServer();
396: ObjectName oname = new ObjectName("test:test=test");
397:
398: ModelMBean mmbean = new XMBean();
399: Resource resource = new Resource();
400:
401: mmbean.setManagedResource(resource, "ObjectReference");
402: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
403:
404: server.registerMBean(mmbean, oname);
405:
406: MyInterface mbean = (MyInterface) MBeanProxy.get(
407: MyInterface.class, oname, server);
408:
409: MyInterface mbean2 = (MyInterface) MBeanProxy.get(
410: MyInterface.class, oname, server);
411:
412: assertTrue(mbean.equals(mbean));
413: assertTrue(!mbean.equals(mbean2));
414: assertTrue(!mbean2.equals(mbean));
415: }
416:
417: public void testObjectEqualsOverride() throws Exception {
418: MBeanServer server = MBeanServerFactory.createMBeanServer();
419: ObjectName oname = new ObjectName("test:test=test");
420:
421: ModelMBean rmm = new RequiredModelMBean();
422: ResourceOverride resource = new ResourceOverride("state");
423:
424: rmm.setManagedResource(resource, "ObjectReference");
425: rmm.setModelMBeanInfo(resource.getMBeanInfo());
426:
427: server.registerMBean(rmm, oname);
428:
429: MyInterface mbean = (MyInterface) MBeanProxy.get(
430: MyInterface.class, oname, server);
431:
432: assertTrue(mbean.equals(mbean));
433: }
434:
435: public void testAttributeNotFoundOnTypedProxy() throws Exception {
436: MBeanServer server = MBeanServerFactory.createMBeanServer();
437: ObjectName oname = new ObjectName("test:test=test");
438:
439: ModelMBean mmbean = new XMBean();
440: ResourceIncorrectInfo resource = new ResourceIncorrectInfo();
441:
442: mmbean.setManagedResource(resource, "ObjectReference");
443: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
444:
445: server.registerMBean(mmbean, oname);
446:
447: MyInterface mbean = (MyInterface) MBeanProxy.get(
448: MyInterface.class, oname, server);
449:
450: ProxyContext ctx = (ProxyContext) mbean;
451: ctx.setExceptionHandler(new DefaultExceptionHandler());
452:
453: try {
454: mbean.setAttributeName2("some name");
455: } catch (IllegalArgumentException e) {
456: // expected
457:
458: // by default, if no such attribute 'AttributeName2' exists in the
459: // MBean metadata (as is the case with ResourceIncorrectInfo), the
460: // MBeanProxy invocation handler falls back attempting to execute
461: // MBeanServer.invoke() which fails with IAE.
462: }
463: }
464:
465: public void testAttributeNotFoundOnDeTypedProxy() throws Exception {
466: MBeanServer server = MBeanServerFactory.createMBeanServer();
467: ObjectName oname = new ObjectName("test:test=test");
468:
469: ModelMBean mmbean = new XMBean();
470: ResourceIncorrectInfo resource = new ResourceIncorrectInfo();
471:
472: mmbean.setManagedResource(resource, "ObjectReference");
473: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
474:
475: server.registerMBean(mmbean, oname);
476:
477: DynamicMBean mbean = (DynamicMBean) MBeanProxy.get(oname,
478: server);
479:
480: ProxyContext ctx = (ProxyContext) mbean;
481: ctx.setExceptionHandler(new DefaultExceptionHandler());
482:
483: try {
484: mbean.setAttribute(new Attribute("AttributeName2",
485: "some name"));
486: } catch (AttributeNotFoundException e) {
487: // expected
488: }
489: }
490:
491: public void testInheritanceInTypedProxyArgs() throws Exception {
492: MBeanServer server = MBeanServerFactory.createMBeanServer();
493: ObjectName oname = new ObjectName("test:test=test");
494:
495: XMBean mmbean = new XMBean();
496: ExtendedResource resource = new ExtendedResource();
497:
498: mmbean.setManagedResource(resource, "ObjectReference");
499: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
500:
501: server.registerMBean(mmbean, oname);
502:
503: MyInterface2 mbean = (MyInterface2) MBeanProxy.get(
504: MyInterface2.class, oname, server);
505:
506: assertTrue(mbean.doOperation().equals("doOperation"));
507:
508: try {
509: assertTrue(mbean.executeThis("executeThis").equals(
510: "executeThis"));
511: } catch (ClassCastException e) {
512: fail("KNOWN ISSUE: proxy generates incorrect JMX invocation "
513: + "signature in case argument subclasses are used.");
514: }
515: }
516:
517: public void testInheritanceInProxyAttribute() throws Exception {
518: MBeanServer server = MBeanServerFactory.createMBeanServer();
519: ObjectName oname = new ObjectName("test:test=test");
520:
521: XMBean mmbean = new XMBean();
522: ExtendedResource resource = new ExtendedResource();
523:
524: mmbean.setManagedResource(resource, "ObjectReference");
525: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
526:
527: server.registerMBean(mmbean, oname);
528:
529: MyInterface2 mbean = (MyInterface2) MBeanProxy.get(
530: MyInterface2.class, oname, server);
531:
532: mbean.setAttribute3("Attribute3");
533:
534: assertTrue(mbean.getAttribute3().equals("Attribute3"));
535: }
536:
537: public void testInheritanceInProxyReturnType() throws Exception {
538: MBeanServer server = MBeanServerFactory.createMBeanServer();
539: ObjectName oname = new ObjectName("test:test=test");
540:
541: XMBean mmbean = new XMBean();
542: ExtendedResource resource = new ExtendedResource();
543:
544: mmbean.setManagedResource(resource, "ObjectReference");
545: mmbean.setModelMBeanInfo(resource.getMBeanInfo());
546:
547: server.registerMBean(mmbean, oname);
548:
549: MyInterface2 mbean = (MyInterface2) MBeanProxy.get(
550: MyInterface2.class, oname, server);
551:
552: assertTrue(mbean.runMe("runMe").equals("runMe"));
553: }
554:
555: }
|