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 * @test |
|
26 * @bug 6287328 |
|
27 * @summary Add methods to StandardMBean to retrieve a method based on |
|
28 * MBean{Attribute|Operation}Info |
|
29 * @author Jean-Francois Denise |
|
30 * @run main FindMethodTest |
|
31 */ |
|
32 |
|
33 import java.lang.management.ManagementFactory; |
|
34 import java.lang.management.MemoryMXBean; |
|
35 import java.lang.management.ThreadMXBean; |
|
36 import java.lang.reflect.Method; |
|
37 import java.util.HashMap; |
|
38 import java.util.HashSet; |
|
39 import java.util.Map; |
|
40 import java.util.Set; |
|
41 import javax.management.MBean; |
|
42 import javax.management.MBeanAttributeInfo; |
|
43 import javax.management.MBeanInfo; |
|
44 import javax.management.MBeanOperationInfo; |
|
45 import javax.management.MBeanParameterInfo; |
|
46 import javax.management.MBeanServer; |
|
47 import javax.management.ManagedAttribute; |
|
48 import javax.management.ManagedOperation; |
|
49 import javax.management.ObjectName; |
|
50 import javax.management.StandardMBean; |
|
51 |
|
52 public class FindMethodTest { |
|
53 |
|
54 private static MBeanServer server = |
|
55 ManagementFactory.getPlatformMBeanServer(); |
|
56 |
|
57 private static Map<String, Set<Method>> expectedMapping = |
|
58 new HashMap<String, Set<Method>>(); |
|
59 private static Set<Method> STATE_SET = new HashSet<Method>(); |
|
60 private static Set<Method> ENABLED_SET = new HashSet<Method>(); |
|
61 private static Set<Method> DOIT_SET = new HashSet<Method>(); |
|
62 private static Set<Method> STATUS_SET = new HashSet<Method>(); |
|
63 private static Set<Method> HEAPMEMORYUSAGE_SET = new HashSet<Method>(); |
|
64 private static Set<Method> THREADINFO_SET = new HashSet<Method>(); |
|
65 private static Set<Method> DOIT_ANNOTATED_SET = new HashSet<Method>(); |
|
66 private static Set<Method> IT_ANNOTATED_SET = new HashSet<Method>(); |
|
67 private static HashSet<Set<Method>> TEST_MBEAN_SET = |
|
68 new HashSet<Set<Method>>(); |
|
69 private static HashSet<Set<Method>> ANNOTATED_MBEAN_SET = |
|
70 new HashSet<Set<Method>>(); |
|
71 private static HashSet<Set<Method>> MEMORY_MBEAN_SET = |
|
72 new HashSet<Set<Method>>(); |
|
73 private static HashSet<Set<Method>> THREAD_MBEAN_SET = |
|
74 new HashSet<Set<Method>>(); |
|
75 |
|
76 public interface TestMBean { |
|
77 |
|
78 public void doIt(); |
|
79 |
|
80 public void setState(String str); |
|
81 |
|
82 public String getState(); |
|
83 |
|
84 public boolean isEnabled(); |
|
85 |
|
86 public void setStatus(int i); |
|
87 } |
|
88 |
|
89 public interface FaultyTestMBean { |
|
90 |
|
91 public void doIt(String doIt); |
|
92 |
|
93 public long getState(); |
|
94 |
|
95 public void setEnabled(boolean b); |
|
96 |
|
97 public int getStatus(); |
|
98 |
|
99 public String setWrong(int i); |
|
100 } |
|
101 |
|
102 @MBean |
|
103 public static class AnnotatedTest { |
|
104 @ManagedOperation |
|
105 public void doItAnnotated() { |
|
106 |
|
107 } |
|
108 |
|
109 public void dontDoIt() { |
|
110 |
|
111 } |
|
112 |
|
113 @ManagedAttribute |
|
114 public String getItAnnotated() { |
|
115 return null; |
|
116 } |
|
117 @ManagedAttribute |
|
118 public void setItAnnotated(String str) { |
|
119 |
|
120 } |
|
121 |
|
122 public String getItNot() { |
|
123 return null; |
|
124 } |
|
125 |
|
126 } |
|
127 |
|
128 static class Test implements TestMBean { |
|
129 |
|
130 public void doIt() { |
|
131 throw new UnsupportedOperationException("Not supported yet."); |
|
132 } |
|
133 |
|
134 public void setState(String str) { |
|
135 throw new UnsupportedOperationException("Not supported yet."); |
|
136 } |
|
137 |
|
138 public String getState() { |
|
139 throw new UnsupportedOperationException("Not supported yet."); |
|
140 } |
|
141 |
|
142 public boolean isEnabled() { |
|
143 throw new UnsupportedOperationException("Not supported yet."); |
|
144 } |
|
145 |
|
146 public void setStatus(int i) { |
|
147 throw new UnsupportedOperationException("Not supported yet."); |
|
148 } |
|
149 } |
|
150 |
|
151 |
|
152 static { |
|
153 try { |
|
154 ENABLED_SET.add(TestMBean.class.getDeclaredMethod("isEnabled")); |
|
155 |
|
156 STATE_SET.add(TestMBean.class.getDeclaredMethod("getState")); |
|
157 STATE_SET.add(TestMBean.class.getDeclaredMethod("setState", |
|
158 String.class)); |
|
159 STATUS_SET.add(TestMBean.class.getDeclaredMethod("setStatus", |
|
160 int.class)); |
|
161 |
|
162 DOIT_SET.add(TestMBean.class.getDeclaredMethod("doIt")); |
|
163 |
|
164 DOIT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("doItAnnotated")); |
|
165 |
|
166 IT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("getItAnnotated")); |
|
167 IT_ANNOTATED_SET.add(AnnotatedTest.class.getDeclaredMethod("setItAnnotated", String.class)); |
|
168 |
|
169 THREADINFO_SET.add(ThreadMXBean.class.getDeclaredMethod("dumpAllThreads", boolean.class, |
|
170 boolean.class)); |
|
171 |
|
172 HEAPMEMORYUSAGE_SET.add(MemoryMXBean.class.getDeclaredMethod("getHeapMemoryUsage")); |
|
173 |
|
174 TEST_MBEAN_SET.add(ENABLED_SET); |
|
175 TEST_MBEAN_SET.add(STATE_SET); |
|
176 TEST_MBEAN_SET.add(STATUS_SET); |
|
177 TEST_MBEAN_SET.add(DOIT_SET); |
|
178 |
|
179 ANNOTATED_MBEAN_SET.add(DOIT_ANNOTATED_SET); |
|
180 ANNOTATED_MBEAN_SET.add(IT_ANNOTATED_SET); |
|
181 |
|
182 MEMORY_MBEAN_SET.add(HEAPMEMORYUSAGE_SET); |
|
183 |
|
184 THREAD_MBEAN_SET.add(THREADINFO_SET); |
|
185 |
|
186 expectedMapping.put("State", STATE_SET); |
|
187 expectedMapping.put("Enabled", ENABLED_SET); |
|
188 expectedMapping.put("Status", STATUS_SET); |
|
189 expectedMapping.put("doIt", DOIT_SET); |
|
190 expectedMapping.put("HeapMemoryUsage", HEAPMEMORYUSAGE_SET); |
|
191 expectedMapping.put("dumpAllThreads", THREADINFO_SET); |
|
192 expectedMapping.put("doItAnnotated", DOIT_ANNOTATED_SET); |
|
193 expectedMapping.put("ItAnnotated", IT_ANNOTATED_SET); |
|
194 |
|
195 } catch (Exception ex) { |
|
196 ex.printStackTrace(); |
|
197 throw new RuntimeException("Initialization failed"); |
|
198 } |
|
199 } |
|
200 |
|
201 private static void testMBean(ObjectName name, Class<?> itf, |
|
202 HashSet<Set<Method>> expectMappings) |
|
203 throws Exception { |
|
204 |
|
205 Set<Set<Method>> expectedMappings = |
|
206 (Set<Set<Method>>) expectMappings.clone(); |
|
207 |
|
208 MBeanInfo info = server.getMBeanInfo(name); |
|
209 for (MBeanAttributeInfo attr : info.getAttributes()) { |
|
210 Set<Method> expected = expectedMapping.get(attr.getName()); |
|
211 if (expected == null) { |
|
212 continue; |
|
213 } |
|
214 if (!expectedMappings.remove(expected)) { |
|
215 throw new Exception("The mapping to use is not the expected " + |
|
216 "one for " + attr); |
|
217 } |
|
218 System.out.println("Expected : " + expected); |
|
219 Set<Method> found = |
|
220 StandardMBean.findAttributeAccessors(itf, attr); |
|
221 System.out.println("Found : " + found); |
|
222 if (!found.equals(expected)) { |
|
223 throw new Exception("Mapping error."); |
|
224 } |
|
225 } |
|
226 for (MBeanOperationInfo op : info.getOperations()) { |
|
227 Set<Method> expected = expectedMapping.get(op.getName()); |
|
228 if (expected == null) { |
|
229 continue; |
|
230 } |
|
231 if (!expectedMappings.remove(expected)) { |
|
232 throw new Exception("The mapping to use is not the expected " + |
|
233 "one for " + op); |
|
234 } |
|
235 System.out.println("Expected : " + expected); |
|
236 Method method = |
|
237 StandardMBean.findOperationMethod(itf, op); |
|
238 Set<Method> found = new HashSet<Method>(); |
|
239 found.add(method); |
|
240 System.out.println("Found : " + found); |
|
241 if (!found.equals(expected)) { |
|
242 throw new Exception("Mapping error."); |
|
243 } |
|
244 } |
|
245 |
|
246 if (expectedMappings.size() != 0) { |
|
247 throw new Exception("Some mapping have not been found " + |
|
248 expectedMappings); |
|
249 } else { |
|
250 System.out.println("All mappings have been found"); |
|
251 } |
|
252 } |
|
253 |
|
254 public static void main(String[] args) throws Exception { |
|
255 // Positive tests |
|
256 Test t = new Test(); |
|
257 ObjectName name = ObjectName.valueOf(":type=Test"); |
|
258 server.registerMBean(t, name); |
|
259 AnnotatedTest at = new AnnotatedTest(); |
|
260 ObjectName annotatedName = ObjectName.valueOf(":type=AnnotatedTest"); |
|
261 server.registerMBean(at, annotatedName); |
|
262 |
|
263 testMBean(name, TestMBean.class, TEST_MBEAN_SET); |
|
264 |
|
265 testMBean(annotatedName, AnnotatedTest.class, ANNOTATED_MBEAN_SET); |
|
266 |
|
267 ObjectName memoryName = |
|
268 ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME); |
|
269 testMBean(memoryName, MemoryMXBean.class, MEMORY_MBEAN_SET); |
|
270 |
|
271 ObjectName threadName = |
|
272 ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME); |
|
273 testMBean(threadName, ThreadMXBean.class, THREAD_MBEAN_SET); |
|
274 |
|
275 // Negative tests |
|
276 try { |
|
277 StandardMBean.findOperationMethod(null, |
|
278 new MBeanOperationInfo("Test", |
|
279 TestMBean.class.getDeclaredMethod("doIt"))); |
|
280 throw new Exception("Expected exception not found"); |
|
281 } catch (IllegalArgumentException ex) { |
|
282 System.out.println("OK received expected exception " + ex); |
|
283 } |
|
284 try { |
|
285 StandardMBean.findOperationMethod(TestMBean.class, null); |
|
286 throw new Exception("Expected exception not found"); |
|
287 } catch (IllegalArgumentException ex) { |
|
288 System.out.println("OK received expected exception " + ex); |
|
289 } |
|
290 try { |
|
291 StandardMBean.findAttributeAccessors(null, |
|
292 new MBeanAttributeInfo("Test", "Test", |
|
293 TestMBean.class.getDeclaredMethod("getState"), |
|
294 TestMBean.class.getDeclaredMethod("setState", |
|
295 String.class))); |
|
296 throw new Exception("Expected exception not found"); |
|
297 } catch (IllegalArgumentException ex) { |
|
298 System.out.println("OK received expected exception " + ex); |
|
299 } |
|
300 try { |
|
301 StandardMBean.findAttributeAccessors(TestMBean.class, null); |
|
302 throw new Exception("Expected exception not found"); |
|
303 } catch (IllegalArgumentException ex) { |
|
304 System.out.println("OK received expected exception " + ex); |
|
305 } |
|
306 //Wrong operation signature |
|
307 try { |
|
308 StandardMBean.findOperationMethod(TestMBean.class, |
|
309 new MBeanOperationInfo("FaultyTest", |
|
310 FaultyTestMBean.class.getDeclaredMethod("doIt", |
|
311 String.class))); |
|
312 throw new Exception("Expected exception not found"); |
|
313 } catch (NoSuchMethodException ex) { |
|
314 System.out.println("OK received expected exception " + ex); |
|
315 } |
|
316 //Wrong attribute accessor |
|
317 try { |
|
318 StandardMBean.findAttributeAccessors(TestMBean.class, |
|
319 new MBeanAttributeInfo("FaultyTest", "FaultyTest", null, |
|
320 FaultyTestMBean.class.getDeclaredMethod("setEnabled", |
|
321 String.class))); |
|
322 throw new Exception("Expected exception not found"); |
|
323 } catch (NoSuchMethodException ex) { |
|
324 System.out.println("OK received expected exception " + ex); |
|
325 } |
|
326 //Wrong attribute type |
|
327 try { |
|
328 StandardMBean.findAttributeAccessors(TestMBean.class, |
|
329 new MBeanAttributeInfo("State", "toto.FaultType", |
|
330 "FaultyTest", true, true, false)); |
|
331 throw new Exception("Expected exception not found"); |
|
332 } catch (ClassNotFoundException ex) { |
|
333 System.out.println("OK received expected exception " + ex); |
|
334 } |
|
335 //Wrong operation parameter type |
|
336 try { |
|
337 MBeanParameterInfo[] p = {new MBeanParameterInfo("p1", |
|
338 "toto.FaultType2", "FaultyParameter") |
|
339 }; |
|
340 StandardMBean.findOperationMethod(TestMBean.class, |
|
341 new MBeanOperationInfo("doIt", "FaultyMethod", p, "void", |
|
342 0)); |
|
343 throw new Exception("Expected exception not found"); |
|
344 } catch (ClassNotFoundException ex) { |
|
345 System.out.println("OK received expected exception " + ex); |
|
346 } |
|
347 // Check that not annotated attributes are not found |
|
348 try { |
|
349 StandardMBean.findAttributeAccessors(AnnotatedTest.class, |
|
350 new MBeanAttributeInfo("ItNot", String.class.getName(), |
|
351 "FaultyTest", true, false, false)); |
|
352 throw new Exception("Expected exception not found"); |
|
353 } catch (NoSuchMethodException ex) { |
|
354 System.out.println("OK received expected exception " + ex); |
|
355 } |
|
356 // Check that not annotated operations are not found |
|
357 try { |
|
358 StandardMBean.findOperationMethod(AnnotatedTest.class, |
|
359 new MBeanOperationInfo("dontDoIt","dontDoIt",null, |
|
360 Void.TYPE.getName(),0)); |
|
361 throw new Exception("Expected exception not found"); |
|
362 } catch (NoSuchMethodException ex) { |
|
363 System.out.println("OK received expected exception " + ex); |
|
364 } |
|
365 // Check that wrong getter return type throws Exception |
|
366 try { |
|
367 StandardMBean.findAttributeAccessors(AnnotatedTest.class, |
|
368 new MBeanAttributeInfo("ItAnnotated", Long.class.getName(), |
|
369 "FaultyTest", true, false, false)); |
|
370 throw new Exception("Expected exception not found"); |
|
371 } catch (NoSuchMethodException ex) { |
|
372 System.out.println("OK received expected exception " + ex); |
|
373 } |
|
374 // Check that wrong setter return type throws Exception |
|
375 try { |
|
376 StandardMBean.findAttributeAccessors(FaultyTestMBean.class, |
|
377 new MBeanAttributeInfo("Wrong", String.class.getName(), |
|
378 "FaultyTest", true, true, false)); |
|
379 throw new Exception("Expected exception not found"); |
|
380 } catch (NoSuchMethodException ex) { |
|
381 System.out.println("OK received expected exception " + ex); |
|
382 } |
|
383 } |
|
384 } |
|