1 /* |
|
2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 * have any questions. |
|
22 */ |
|
23 |
|
24 /* |
|
25 * |
|
26 * @test JMXNamespaceTest.java |
|
27 * @summary General JMXNamespace test. |
|
28 * @bug 5072476 |
|
29 * @author Daniel Fuchs |
|
30 * @run clean JMXNamespaceTest |
|
31 * Wombat WombatMBean JMXRemoteTargetNamespace |
|
32 * NamespaceController NamespaceControllerMBean |
|
33 * @compile -XDignore.symbol.file=true JMXNamespaceTest.java |
|
34 * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java |
|
35 * NamespaceController.java NamespaceControllerMBean.java |
|
36 * @run main/othervm JMXNamespaceTest |
|
37 */ |
|
38 import java.lang.management.ManagementFactory; |
|
39 import java.lang.management.MemoryMXBean; |
|
40 import java.lang.reflect.InvocationTargetException; |
|
41 import java.lang.reflect.Method; |
|
42 import java.util.Arrays; |
|
43 import java.util.Collections; |
|
44 import java.util.List; |
|
45 import java.util.Map; |
|
46 import java.util.Set; |
|
47 import java.util.logging.Logger; |
|
48 import javax.management.DynamicMBean; |
|
49 import javax.management.InstanceNotFoundException; |
|
50 import javax.management.InvalidAttributeValueException; |
|
51 import javax.management.JMX; |
|
52 import javax.management.MBeanServer; |
|
53 import javax.management.MBeanServerConnection; |
|
54 import javax.management.MBeanServerFactory; |
|
55 import javax.management.NotificationEmitter; |
|
56 import javax.management.ObjectInstance; |
|
57 import javax.management.ObjectName; |
|
58 import javax.management.StandardMBean; |
|
59 import javax.management.namespace.JMXNamespaces; |
|
60 import javax.management.namespace.JMXNamespace; |
|
61 import javax.management.namespace.JMXNamespaceMBean; |
|
62 import javax.management.namespace.JMXRemoteNamespaceMBean; |
|
63 import javax.management.namespace.MBeanServerConnectionWrapper; |
|
64 import javax.management.namespace.MBeanServerSupport; |
|
65 import javax.management.remote.JMXConnector; |
|
66 import javax.management.remote.JMXConnectorFactory; |
|
67 import javax.management.remote.JMXConnectorServer; |
|
68 import javax.management.remote.JMXConnectorServerFactory; |
|
69 import javax.management.remote.JMXServiceURL; |
|
70 |
|
71 /** |
|
72 * |
|
73 * @author Sun Microsystems, Inc. |
|
74 */ |
|
75 public class JMXNamespaceTest { |
|
76 |
|
77 /** |
|
78 * A logger for this class. |
|
79 **/ |
|
80 private static final Logger LOG = |
|
81 Logger.getLogger(JMXNamespaceTest.class.getName()); |
|
82 |
|
83 /** Creates a new instance of JMXNamespaceTest */ |
|
84 public JMXNamespaceTest() { |
|
85 } |
|
86 |
|
87 public static class WombatRepository extends MBeanServerSupport { |
|
88 final Wombat wombat; |
|
89 final StandardMBean mbean; |
|
90 final ObjectName wombatName; |
|
91 |
|
92 public WombatRepository(ObjectName wombatName) { |
|
93 try { |
|
94 wombat = new Wombat(); |
|
95 mbean = wombat; |
|
96 this.wombatName = wombatName; |
|
97 wombat.preRegister(null,wombatName); |
|
98 } catch (Exception x) { |
|
99 throw new IllegalArgumentException(x); |
|
100 } |
|
101 } |
|
102 |
|
103 @Override |
|
104 public DynamicMBean getDynamicMBeanFor(ObjectName name) |
|
105 throws InstanceNotFoundException { |
|
106 if (wombatName.equals(name)) return mbean; |
|
107 else throw new InstanceNotFoundException(String.valueOf(name)); |
|
108 } |
|
109 |
|
110 @Override |
|
111 protected Set<ObjectName> getNames() { |
|
112 final Set<ObjectName> res = Collections.singleton(wombatName); |
|
113 return res; |
|
114 } |
|
115 |
|
116 @Override |
|
117 public NotificationEmitter |
|
118 getNotificationEmitterFor(ObjectName name) |
|
119 throws InstanceNotFoundException { |
|
120 final DynamicMBean mb = getDynamicMBeanFor(name); |
|
121 if (mb instanceof NotificationEmitter) |
|
122 return (NotificationEmitter)mb; |
|
123 return null; |
|
124 } |
|
125 } |
|
126 |
|
127 public static class SimpleTest { |
|
128 public final String descr; |
|
129 private final Class<?> testClass; |
|
130 private final Method method; |
|
131 public SimpleTest(String descr) { |
|
132 this.descr = descr; |
|
133 this.testClass = JMXNamespaceTest.class; |
|
134 try { |
|
135 method = testClass. |
|
136 getDeclaredMethod(descr,SimpleTestConf.class, |
|
137 Object[].class); |
|
138 } catch (NoSuchMethodException x) { |
|
139 throw new IllegalArgumentException(descr+": test not found", |
|
140 x); |
|
141 } |
|
142 } |
|
143 |
|
144 public void run(SimpleTestConf conf, Object... args) |
|
145 throws Exception { |
|
146 try { |
|
147 method.invoke(null,conf,args); |
|
148 } catch (InvocationTargetException x) { |
|
149 final Throwable cause = x.getCause(); |
|
150 if (cause instanceof Exception) throw (Exception)cause; |
|
151 if (cause instanceof Error) throw (Error)cause; |
|
152 throw x; |
|
153 } |
|
154 } |
|
155 } |
|
156 |
|
157 public static class SimpleTestConf { |
|
158 public final Wombat wombat; |
|
159 public final StandardMBean mbean; |
|
160 public final String dirname; |
|
161 public final ObjectName handlerName; |
|
162 public final ObjectName wombatNickName; |
|
163 public final ObjectName wombatName; |
|
164 public final JMXNamespace wombatNamespace; |
|
165 public final MBeanServer server; |
|
166 public final WombatMBean proxy; |
|
167 public SimpleTestConf(String[] args) throws Exception { |
|
168 wombat = new Wombat(); |
|
169 mbean = wombat; |
|
170 dirname = "wombat"; |
|
171 handlerName = |
|
172 new ObjectName(dirname+"//:type=JMXNamespace"); |
|
173 |
|
174 wombatNickName = |
|
175 new ObjectName("burrow:type=Wombat"); |
|
176 |
|
177 wombatName = |
|
178 new ObjectName(dirname+"//"+wombatNickName); |
|
179 |
|
180 wombatNamespace = |
|
181 new JMXNamespace( |
|
182 new WombatRepository(wombatNickName)); |
|
183 |
|
184 server = ManagementFactory.getPlatformMBeanServer(); |
|
185 System.out.println(handlerName+" registered="+ |
|
186 server.isRegistered(handlerName)); |
|
187 server.registerMBean(wombatNamespace,handlerName); |
|
188 |
|
189 try { |
|
190 proxy = JMX.newMBeanProxy(server,wombatName, |
|
191 WombatMBean.class); |
|
192 } catch (Exception x) { |
|
193 server.unregisterMBean(handlerName); |
|
194 throw x; |
|
195 } |
|
196 } |
|
197 |
|
198 public void close() { |
|
199 try { |
|
200 server.unregisterMBean(handlerName); |
|
201 } catch (Exception x) { |
|
202 System.out.println("Failed to close: " + x); |
|
203 x.printStackTrace(); |
|
204 } |
|
205 } |
|
206 |
|
207 public void test(SimpleTest test,Object... args) |
|
208 throws Exception { |
|
209 try { |
|
210 test.run(this,args); |
|
211 passed++; |
|
212 } catch (Exception x) { |
|
213 failed++; |
|
214 System.err.println(test.descr+" failed: " + x); |
|
215 x.printStackTrace(); |
|
216 } |
|
217 } |
|
218 |
|
219 public volatile int failed = 0; |
|
220 public volatile int passed = 0; |
|
221 } |
|
222 |
|
223 static void checkValue(String name,Object expected, Object returned) |
|
224 throws InvalidAttributeValueException { |
|
225 if (Collections.singletonList(expected). |
|
226 equals(Collections.singletonList(returned))) return; |
|
227 |
|
228 throw new InvalidAttributeValueException("Bad value for "+ |
|
229 name+": ["+returned+"] - was expecting ["+expected+"]"); |
|
230 } |
|
231 |
|
232 // --------------------------------------------------------------- |
|
233 // SIMPLE TESTS BEGIN HERE |
|
234 // --------------------------------------------------------------- |
|
235 |
|
236 static void getCaptionTest(SimpleTestConf env, Object... args) |
|
237 throws Exception { |
|
238 System.out.println(env.proxy.getCaption()); |
|
239 } |
|
240 |
|
241 static void setCaptionTest(SimpleTestConf env, Object... args) |
|
242 throws Exception { |
|
243 env.proxy.setCaption((String)args[0]); |
|
244 final String result = env.proxy.getCaption(); |
|
245 System.out.println(result); |
|
246 checkValue("Caption",args[0],result); |
|
247 } |
|
248 |
|
249 static void queryNamesTest1(SimpleTestConf env, Object... args) |
|
250 throws Exception { |
|
251 final ObjectName pat = |
|
252 new ObjectName(env.handlerName.getDomain()+"*:*"); |
|
253 final Set<ObjectName> res = |
|
254 env.server.queryNames(pat,null); |
|
255 System.out.println("queryNamesTest1: "+res); |
|
256 checkValue("names",Collections.singleton(env.wombatName),res); |
|
257 } |
|
258 |
|
259 static void queryNamesTest2(SimpleTestConf env, Object... args) |
|
260 throws Exception { |
|
261 final ObjectName pat = |
|
262 new ObjectName("*:"+ |
|
263 env.wombatName.getKeyPropertyListString()); |
|
264 final Set<ObjectName> res = |
|
265 env.server.queryNames(pat,null); |
|
266 System.out.println("queryNamesTest2: "+res); |
|
267 checkValue("names",Collections.emptySet(),res); |
|
268 } |
|
269 |
|
270 static void getDomainsTest(SimpleTestConf env, Object... args) |
|
271 throws Exception { |
|
272 final List<String> domains = |
|
273 Arrays.asList(env.server.getDomains()); |
|
274 System.out.println("getDomainsTest: "+domains); |
|
275 if (domains.contains(env.wombatName.getDomain())) |
|
276 throw new InvalidAttributeValueException("domain: "+ |
|
277 env.wombatName.getDomain()); |
|
278 if (!domains.contains(env.handlerName.getDomain())) |
|
279 throw new InvalidAttributeValueException("domain not found: "+ |
|
280 env.handlerName.getDomain()); |
|
281 } |
|
282 |
|
283 // --------------------------------------------------------------- |
|
284 // SIMPLE TESTS END HERE |
|
285 // --------------------------------------------------------------- |
|
286 |
|
287 private static void simpleTest(String[] args) { |
|
288 final SimpleTestConf conf; |
|
289 try { |
|
290 conf = new SimpleTestConf(args); |
|
291 try { |
|
292 conf.test(new SimpleTest("getCaptionTest")); |
|
293 conf.test(new SimpleTest("setCaptionTest"), |
|
294 "I am a new Wombat!"); |
|
295 conf.test(new SimpleTest("queryNamesTest1")); |
|
296 conf.test(new SimpleTest("queryNamesTest2")); |
|
297 conf.test(new SimpleTest("getDomainsTest")); |
|
298 } finally { |
|
299 conf.close(); |
|
300 } |
|
301 } catch (Exception x) { |
|
302 System.err.println("simpleTest FAILED: " +x); |
|
303 x.printStackTrace(); |
|
304 throw new RuntimeException(x); |
|
305 } |
|
306 System.out.println("simpleTest: "+conf.passed+ |
|
307 " PASSED, " + conf.failed + " FAILED."); |
|
308 if (conf.failed>0) { |
|
309 System.err.println("simpleTest FAILED ["+conf.failed+"]"); |
|
310 throw new RuntimeException("simpleTest FAILED ["+conf.failed+"]"); |
|
311 } else { |
|
312 System.err.println("simpleTest PASSED ["+conf.passed+"]"); |
|
313 } |
|
314 } |
|
315 |
|
316 public static void recursiveTest(String[] args) { |
|
317 final SimpleTestConf conf; |
|
318 try { |
|
319 conf = new SimpleTestConf(args); |
|
320 try { |
|
321 final JMXServiceURL url = |
|
322 new JMXServiceURL("rmi","localHost",0); |
|
323 final Map<String,Object> empty = Collections.emptyMap(); |
|
324 final JMXConnectorServer server = |
|
325 JMXConnectorServerFactory.newJMXConnectorServer(url, |
|
326 empty,conf.server); |
|
327 server.start(); |
|
328 final JMXServiceURL address = server.getAddress(); |
|
329 final JMXConnector client = |
|
330 JMXConnectorFactory.connect(address, |
|
331 empty); |
|
332 final String[] signature = { |
|
333 JMXServiceURL.class.getName(), |
|
334 Map.class.getName(), |
|
335 }; |
|
336 final String[] signature2 = { |
|
337 JMXServiceURL.class.getName(), |
|
338 Map.class.getName(), |
|
339 String.class.getName(), |
|
340 }; |
|
341 final Object[] params = { |
|
342 address, |
|
343 null, |
|
344 }; |
|
345 final MBeanServerConnection c = |
|
346 client.getMBeanServerConnection(); |
|
347 final ObjectName dirName1 = |
|
348 new ObjectName("kanga//:type=JMXNamespace"); |
|
349 c.createMBean(JMXRemoteTargetNamespace.class.getName(), |
|
350 dirName1, params,signature); |
|
351 c.invoke(dirName1, "connect", null, null); |
|
352 try { |
|
353 final MemoryMXBean memory = |
|
354 JMX.newMXBeanProxy(c, |
|
355 new ObjectName("kanga//"+ |
|
356 ManagementFactory.MEMORY_MXBEAN_NAME), |
|
357 MemoryMXBean.class); |
|
358 System.out.println("HeapMemory #1: "+ |
|
359 memory.getHeapMemoryUsage().toString()); |
|
360 final MemoryMXBean memory2 = |
|
361 JMX.newMXBeanProxy(c, |
|
362 new ObjectName("kanga//kanga//"+ |
|
363 ManagementFactory.MEMORY_MXBEAN_NAME), |
|
364 MemoryMXBean.class); |
|
365 System.out.println("HeapMemory #2: "+ |
|
366 memory2.getHeapMemoryUsage().toString()); |
|
367 final Object[] params2 = { |
|
368 address, |
|
369 null, |
|
370 "kanga//kanga" |
|
371 // "kanga//kanga//roo//kanga", <= cycle |
|
372 }; |
|
373 final ObjectName dirName2 = |
|
374 new ObjectName("kanga//roo//:type=JMXNamespace"); |
|
375 c.createMBean(JMXRemoteTargetNamespace.class.getName(), |
|
376 dirName2, params2, signature2); |
|
377 System.out.println(dirName2 + " created!"); |
|
378 JMX.newMBeanProxy(c,dirName2, |
|
379 JMXRemoteNamespaceMBean.class).connect(); |
|
380 try { |
|
381 final ObjectName wombatName1 = |
|
382 new ObjectName("kanga//roo//"+conf.wombatName); |
|
383 final ObjectName wombatName2 = |
|
384 new ObjectName("kanga//roo//"+wombatName1); |
|
385 final WombatMBean wombat1 = |
|
386 JMX.newMBeanProxy(c,wombatName1,WombatMBean.class); |
|
387 final WombatMBean wombat2 = |
|
388 JMX.newMBeanProxy(c,wombatName2,WombatMBean.class); |
|
389 final String newCaption="I am still the same old wombat"; |
|
390 wombat1.setCaption(newCaption); |
|
391 final String caps = conf.proxy.getCaption(); |
|
392 System.out.println("Caption: "+caps); |
|
393 checkValue("Caption",newCaption,caps); |
|
394 final String caps1 = wombat1.getCaption(); |
|
395 System.out.println("Caption #1: "+caps1); |
|
396 checkValue("Caption #1",newCaption,caps1); |
|
397 final String caps2 = wombat2.getCaption(); |
|
398 System.out.println("Caption #2: "+caps2); |
|
399 checkValue("Caption #2",newCaption,caps2); |
|
400 final ObjectInstance instance = |
|
401 NamespaceController.createInstance(conf.server); |
|
402 final NamespaceControllerMBean controller = |
|
403 JMX.newMBeanProxy(conf.server,instance.getObjectName(), |
|
404 NamespaceControllerMBean.class); |
|
405 final String[] dirs = controller.findNamespaces(); |
|
406 System.out.println("directories: " + |
|
407 Arrays.asList(dirs)); |
|
408 final int depth = 4; |
|
409 final String[] dirs2 = controller.findNamespaces(null,null,depth); |
|
410 System.out.println("directories[depth="+depth+"]: " + |
|
411 Arrays.asList(dirs2)); |
|
412 for (String dir : dirs2) { |
|
413 if (dir.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) |
|
414 dir = dir.substring(0,dir.length()- |
|
415 JMXNamespaces.NAMESPACE_SEPARATOR.length()); |
|
416 if (dir.split(JMXNamespaces.NAMESPACE_SEPARATOR).length |
|
417 > (depth+1)) { |
|
418 throw new RuntimeException(dir+": depth exceeds "+depth); |
|
419 } |
|
420 final ObjectName handlerName = |
|
421 JMXNamespaces.getNamespaceObjectName(dir); |
|
422 final JMXNamespaceMBean handler = |
|
423 JMX.newMBeanProxy(conf.server,handlerName, |
|
424 JMXNamespaceMBean.class); |
|
425 try { |
|
426 System.err.println("Directory "+dir+" domains: "+ |
|
427 Arrays.asList(handler.getDomains())); |
|
428 System.err.println("Directory "+dir+" default domain: "+ |
|
429 handler.getDefaultDomain()); |
|
430 System.err.println("Directory "+dir+" MBean count: "+ |
|
431 handler.getMBeanCount()); |
|
432 } catch(Exception x) { |
|
433 System.err.println("get info failed for " + |
|
434 dir +", "+handlerName+": "+x); |
|
435 x.getCause().printStackTrace(); |
|
436 throw x; |
|
437 } |
|
438 } |
|
439 |
|
440 } finally { |
|
441 c.unregisterMBean(dirName2); |
|
442 } |
|
443 } finally { |
|
444 c.unregisterMBean(dirName1); |
|
445 client.close(); |
|
446 server.stop(); |
|
447 } |
|
448 } finally { |
|
449 conf.close(); |
|
450 } |
|
451 System.err.println("recursiveTest PASSED"); |
|
452 } catch (Exception x) { |
|
453 System.err.println("recursiveTest FAILED: " +x); |
|
454 x.printStackTrace(); |
|
455 throw new RuntimeException(x); |
|
456 } |
|
457 } |
|
458 |
|
459 public static void verySimpleTest(String[] args) { |
|
460 System.err.println("verySimpleTest: starting"); |
|
461 try { |
|
462 final MBeanServer srv = MBeanServerFactory.createMBeanServer(); |
|
463 srv.registerMBean(new JMXNamespace( |
|
464 JMXNamespaces.narrowToNamespace(srv, "foo")), |
|
465 JMXNamespaces.getNamespaceObjectName("foo")); |
|
466 throw new Exception("Excpected IllegalArgumentException not raised."); |
|
467 } catch (IllegalArgumentException x) { |
|
468 System.err.println("verySimpleTest: got expected exception: "+x); |
|
469 } catch (Exception x) { |
|
470 System.err.println("verySimpleTest FAILED: " +x); |
|
471 x.printStackTrace(); |
|
472 throw new RuntimeException(x); |
|
473 } |
|
474 System.err.println("verySimpleTest: PASSED"); |
|
475 } |
|
476 |
|
477 public static void verySimpleTest2(String[] args) { |
|
478 System.err.println("verySimpleTest2: starting"); |
|
479 try { |
|
480 final MBeanServer srv = MBeanServerFactory.createMBeanServer(); |
|
481 final JMXConnectorServer cs = JMXConnectorServerFactory. |
|
482 newJMXConnectorServer(new JMXServiceURL("rmi",null,0), |
|
483 null, srv); |
|
484 cs.start(); |
|
485 final JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress()); |
|
486 |
|
487 srv.registerMBean(new JMXNamespace( |
|
488 new MBeanServerConnectionWrapper( |
|
489 JMXNamespaces.narrowToNamespace( |
|
490 cc.getMBeanServerConnection(), |
|
491 "foo"))), |
|
492 JMXNamespaces.getNamespaceObjectName("foo")); |
|
493 throw new Exception("Excpected IllegalArgumentException not raised."); |
|
494 } catch (IllegalArgumentException x) { |
|
495 System.err.println("verySimpleTest2: got expected exception: "+x); |
|
496 } catch (Exception x) { |
|
497 System.err.println("verySimpleTest2 FAILED: " +x); |
|
498 x.printStackTrace(); |
|
499 throw new RuntimeException(x); |
|
500 } |
|
501 System.err.println("verySimpleTest2: PASSED"); |
|
502 } |
|
503 |
|
504 public static void main(String[] args) { |
|
505 simpleTest(args); |
|
506 recursiveTest(args); |
|
507 verySimpleTest(args); |
|
508 verySimpleTest2(args); |
|
509 } |
|
510 |
|
511 } |
|