1 /* 2 * Copyright (c) 2004, 2005, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4847959 6191402 27 * @summary Test newly-generified APIs 28 * @author Eamonn McManus 29 * @run clean GenericTest 30 * @run build GenericTest 31 * @run main GenericTest 32 */ 33 34 import java.lang.management.ManagementFactory; 35 import java.lang.reflect.*; 36 import java.util.*; 37 import javax.management.*; 38 import javax.management.openmbean.*; 39 import javax.management.relation.*; 40 import javax.management.timer.Timer; 41 import javax.management.timer.TimerMBean; 42 43 public class GenericTest { 44 private static int failures; 45 main(String[] args)46 public static void main(String[] args) throws Exception { 47 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 48 49 // Check we are really using the generified version 50 boolean generic; 51 Method findmbs = MBeanServerFactory.class.getMethod("findMBeanServer", 52 String.class); 53 Type findmbstype = findmbs.getGenericReturnType(); 54 if (!(findmbstype instanceof ParameterizedType)) { 55 System.out.println("FAILURE: API NOT GENERIC!"); 56 System.out.println(" MBeanServerFactory.findMBeanServer -> " + 57 findmbstype); 58 failures++; 59 generic = false; 60 } else { 61 System.out.println("OK: this API is generic"); 62 generic = true; 63 } 64 65 ArrayList<MBeanServer> mbsList1 = 66 MBeanServerFactory.findMBeanServer(null); 67 checked(mbsList1, MBeanServer.class); 68 ArrayList mbsList2 = MBeanServerFactory.findMBeanServer(null); 69 check("ArrayList<MBeanServer> findMBeanServer", mbsList1.size() == 1); 70 check("ArrayList findMBeanServer", mbsList1.equals(mbsList2)); 71 72 Set<ObjectName> names1 = 73 checked(mbs.queryNames(null, null), ObjectName.class); 74 Set names2 = mbs.queryNames(null, null); 75 Set<ObjectName> names3 = 76 checked(((MBeanServerConnection) mbs).queryNames(null, null), 77 ObjectName.class); 78 check("Set<ObjectName> MBeanServer.queryNames", names1.size() >= 1); 79 check("Set MBeanServer.queryNames", names2.size() >= 1); 80 check("Set<ObjectName> MBeanServerConnection.queryNames", 81 names3.size() >= 1); 82 check("queryNames sets same", 83 names1.equals(names2) && names2.equals(names3)); 84 85 Set<ObjectInstance> mbeans1 = 86 checked(mbs.queryMBeans(null, null), ObjectInstance.class); 87 Set mbeans2 = mbs.queryMBeans(null, null); 88 Set<ObjectInstance> mbeans3 = 89 checked(((MBeanServerConnection) mbs).queryMBeans(null, null), 90 ObjectInstance.class); 91 check("Set<ObjectInstsance> MBeanServer.queryMBeans", 92 mbeans1.size() >= 1); 93 check("Set MBeanServer.queryMBeans", mbeans2.size() >= 1); 94 check("Set<ObjectInstsance> MBeanServerConnection.queryMBeans", 95 mbeans3.size() >= 1); 96 check("queryMBeans sets same", 97 mbeans1.equals(mbeans2) && mbeans2.equals(mbeans3)); 98 99 100 AttributeChangeNotificationFilter acnf = 101 new AttributeChangeNotificationFilter(); 102 acnf.enableAttribute("foo"); 103 Vector<String> acnfs = acnf.getEnabledAttributes(); 104 checked(acnfs, String.class); 105 check("Vector<String> AttributeChangeNotificationFilter.getEnabled" + 106 "Attributes", acnfs.equals(Arrays.asList(new String[] {"foo"}))); 107 108 if (generic) { 109 Attribute a = new Attribute("foo", "bar"); 110 AttributeList al1 = new AttributeList(); 111 al1.add(a); 112 AttributeList al2 = 113 new AttributeList(Arrays.asList(new Attribute[] {a})); 114 check("new AttributeList(List<Attribute>)", al1.equals(al2)); 115 List<Attribute> al3 = checked(al1.asList(), Attribute.class); 116 al3.remove(a); 117 check("List<Attribute> AttributeList.asList()", 118 al1.equals(al3) && al1.isEmpty()); 119 } 120 121 List<ObjectName> namelist1 = new ArrayList<ObjectName>(names1); 122 Role role = new Role("rolename", namelist1); 123 List<ObjectName> namelist2 = 124 checked(role.getRoleValue(), ObjectName.class); 125 check("new Role(String,List<ObjectName>).getRoleValue() -> " + 126 "List<ObjectName>", namelist1.equals(namelist2)); 127 128 RoleList rl1 = new RoleList(); 129 rl1.add(role); 130 RoleList rl2 = new RoleList(Arrays.asList(new Role[] {role})); 131 check("new RoleList(List<Role>)", rl1.equals(rl2)); 132 if (generic) { 133 List<Role> rl3 = checked(rl1.asList(), Role.class); 134 rl3.remove(role); 135 check("List<Role> RoleList.asList()", 136 rl1.equals(rl3) && rl1.isEmpty()); 137 } 138 139 RoleUnresolved ru = 140 new RoleUnresolved("rolename", namelist1, 141 RoleStatus.LESS_THAN_MIN_ROLE_DEGREE); 142 List<ObjectName> namelist3 = 143 checked(ru.getRoleValue(), ObjectName.class); 144 check("new RoleUnresolved(...List<ObjectName>...).getRoleValue() -> " + 145 "List<ObjectName>", namelist1.equals(namelist3)); 146 147 RoleUnresolvedList rul1 = new RoleUnresolvedList(); 148 rul1.add(ru); 149 RoleUnresolvedList rul2 = 150 new RoleUnresolvedList(Arrays.asList(new RoleUnresolved[] {ru})); 151 check("new RoleUnresolvedList(List<RoleUnresolved>", rul1.equals(rul2)); 152 if (generic) { 153 List<RoleUnresolved> rul3 = 154 checked(rul1.asList(), RoleUnresolved.class); 155 rul3.remove(ru); 156 check("List<RoleUnresolved> RoleUnresolvedList.asList()", 157 rul1.equals(rul3) && rul1.isEmpty()); 158 } 159 160 // This case basically just tests that we can compile this sort of thing 161 OpenMBeanAttributeInfo ombai1 = 162 new OpenMBeanAttributeInfoSupport("a", "a descr", 163 SimpleType.INTEGER, 164 true, true, false); 165 CompositeType ct = 166 new CompositeType("ct", "ct descr", new String[] {"item1"}, 167 new String[] {"item1 descr"}, 168 new OpenType[] {SimpleType.INTEGER}); 169 OpenMBeanAttributeInfo ombai2 = 170 new OpenMBeanAttributeInfoSupport("a", "a descr", 171 ct, true, true, false); 172 TabularType tt = 173 new TabularType("tt", "tt descr", ct, new String[] {"item1"}); 174 OpenMBeanAttributeInfo ombai3 = 175 new OpenMBeanAttributeInfoSupport("a", "a descr", 176 tt, true, true, false); 177 ArrayType<String[][]> at = 178 new ArrayType<String[][]>(2, SimpleType.STRING); 179 OpenMBeanAttributeInfo ombai4 = 180 new OpenMBeanAttributeInfoSupport("a", "a descr", 181 at, true, true, false); 182 OpenMBeanAttributeInfo ombai4a = 183 new OpenMBeanAttributeInfoSupport("a", "a descr", 184 (ArrayType) at, 185 true, true, false); 186 OpenMBeanAttributeInfo ombai5 = 187 new OpenMBeanAttributeInfoSupport("a", "a descr", 188 SimpleType.INTEGER, 189 true, true, false, 190 5, 1, 9); 191 OpenMBeanAttributeInfo ombai6 = 192 new OpenMBeanAttributeInfoSupport("a", "a descr", 193 SimpleType.INTEGER, 194 true, true, false, 195 5, new Integer[] {1, 5}); 196 197 OpenMBeanInfo ombi = 198 new OpenMBeanInfoSupport("a.a", "a.a descr", 199 new OpenMBeanAttributeInfo[] { 200 ombai1, ombai2, ombai3, ombai4, 201 ombai5, ombai6, 202 }, 203 null, null, null); 204 205 Map<String,Integer> itemMap = 206 checked(singletonMap("item1", 5), 207 String.class, Integer.class); 208 CompositeData cd = 209 new CompositeDataSupport(ct, itemMap); 210 check("CompositeDataSupport(CompositeType, Map<String,?>", 211 cd.get("item1").equals(5)); 212 213 Set<String> ctkeys = checked(ct.keySet(), String.class); 214 check("Set<String> CompositeType.keySet()", 215 ctkeys.equals(singleton("item1"))); 216 217 List<String> ttindex = checked(tt.getIndexNames(), String.class); 218 check("Set<String> TabularType.getIndexNames()", 219 ttindex.equals(singletonList("item1"))); 220 221 TabularData td = new TabularDataSupport(tt); 222 td.putAll(new CompositeData[] {cd}); 223 List<Integer> tdkey = checked(singletonList(5), Integer.class); 224 Set<List<Integer>> tdkeys = checked(singleton(tdkey), 225 (Class<List<Integer>>) tdkey.getClass()); 226 Collection<CompositeData> tdvalues = checked(singleton(cd), 227 CompositeData.class); 228 check("Set<List<?>> TabularDataSupport.keySet()", 229 td.keySet().equals(tdkeys)); 230 check("Collection<CompositeData> TabularDataSupport.values()", 231 td.values().iterator().next().equals(tdvalues.iterator().next())); 232 233 ObjectName stupidName = new ObjectName("stupid:a=b"); 234 mbs.registerMBean(new Stupid(), stupidName); 235 StupidMBean proxy = 236 MBeanServerInvocationHandler.newProxyInstance(mbs, 237 stupidName, 238 StupidMBean.class, 239 false); 240 check("MBeanServerInvocationHandler.newProxyInstance", 241 proxy.getFive() == 5); 242 mbs.unregisterMBean(stupidName); 243 244 mbs.registerMBean(new StandardMBean(new Stupid(), StupidMBean.class), 245 stupidName); 246 check("<T> StandardMBean(T impl, Class<T> intf)", 247 proxy.getFive() == 5); 248 249 // Following is based on the package.html for javax.management.relation 250 // Create the Relation Service MBean 251 ObjectName relSvcName = new ObjectName(":type=RelationService"); 252 RelationService relSvcObject = new RelationService(true); 253 mbs.registerMBean(relSvcObject, relSvcName); 254 255 // Create an MBean proxy for easier access to the Relation Service 256 RelationServiceMBean relSvc = 257 MBeanServerInvocationHandler.newProxyInstance(mbs, relSvcName, 258 RelationServiceMBean.class, 259 false); 260 261 // Define the DependsOn relation type 262 RoleInfo[] dependsOnRoles = { 263 new RoleInfo("dependent", Module.class.getName()), 264 new RoleInfo("dependedOn", Module.class.getName()) 265 }; 266 relSvc.createRelationType("DependsOn", dependsOnRoles); 267 268 // Now define a relation instance "moduleA DependsOn moduleB" 269 270 ObjectName moduleA = new ObjectName(":type=Module,name=A"); 271 ObjectName moduleB = new ObjectName(":type=Module,name=B"); 272 273 // Following two lines added to example: 274 mbs.registerMBean(new Module(), moduleA); 275 mbs.registerMBean(new Module(), moduleB); 276 277 Role dependent = new Role("dependent", singletonList(moduleA)); 278 Role dependedOn = new Role("dependedOn", singletonList(moduleB)); 279 Role[] roleArray = {dependent, dependedOn}; 280 RoleList roles = new RoleList(Arrays.asList(roleArray)); 281 relSvc.createRelation("A-DependsOn-B", "DependsOn", roles); 282 283 // Query the Relation Service to find what modules moduleA depends on 284 Map<ObjectName,List<String>> dependentAMap = 285 relSvc.findAssociatedMBeans(moduleA, "DependsOn", "dependent"); 286 Set<ObjectName> dependentASet = dependentAMap.keySet(); 287 dependentASet = checked(dependentASet, ObjectName.class); 288 // Set of ObjectName containing moduleB 289 check("Map<ObjectName,List<String>> RelationService.findAssociatedMBeans", 290 dependentAMap.size() == 1 && 291 dependentASet.equals(singleton(moduleB))); 292 293 Map<String,List<String>> refRels = 294 relSvc.findReferencingRelations(moduleA, "DependsOn", "dependent"); 295 List<String> refRoles = 296 checked(refRels.get("A-DependsOn-B"), String.class); 297 check("Map<String,List<String>> RelationService.findReferencingRelations", 298 refRoles.equals(singletonList("dependent"))); 299 300 List<String> relsOfType = relSvc.findRelationsOfType("DependsOn"); 301 relsOfType = checked(relsOfType, String.class); 302 check("List<String> RelationService.findRelationsOfType", 303 relsOfType.equals(singletonList("A-DependsOn-B"))); 304 305 List<String> allRelIds = relSvc.getAllRelationIds(); 306 allRelIds = checked(allRelIds, String.class); 307 check("List<String> RelationService.getAllRelationIds()", 308 allRelIds.equals(singletonList("A-DependsOn-B"))); 309 310 List<String> allRelTypes = relSvc.getAllRelationTypeNames(); 311 allRelTypes = checked(allRelTypes, String.class); 312 check("List<String> RelationService.getAllRelationTypeNames", 313 allRelTypes.equals(singletonList("DependsOn"))); 314 315 Map<ObjectName,List<String>> refdMBeans = 316 relSvc.getReferencedMBeans("A-DependsOn-B"); 317 check("Map<ObjectName,List<String>> RelationService.getReferencedMBeans", 318 refdMBeans.get(moduleA).equals(singletonList("dependent")) && 319 refdMBeans.get(moduleB).equals(singletonList("dependedOn"))); 320 321 List<ObjectName> roleContents = 322 checked(relSvc.getRole("A-DependsOn-B", "dependent"), 323 ObjectName.class); 324 check("List<ObjectName> RelationService.getRole", 325 roleContents.equals(singletonList(moduleA))); 326 327 RoleInfo roleInfoDependent = 328 relSvc.getRoleInfo("DependsOn", "dependent"); 329 RoleInfo roleInfoDependedOn = 330 relSvc.getRoleInfo("DependsOn", "dependedOn"); 331 List<RoleInfo> expectedRoleInfos = 332 Arrays.asList(new RoleInfo[] {roleInfoDependent, roleInfoDependedOn}); 333 List<RoleInfo> roleInfos = 334 checked(relSvc.getRoleInfos("DependsOn"), RoleInfo.class); 335 check("List<RoleInfo> RelationService.getRoleInfos", 336 equalListContents(expectedRoleInfos, roleInfos)); 337 338 RelationType relType = 339 new RelationTypeSupport("DependsOn", dependsOnRoles); 340 List<RoleInfo> relTypeRoleInfos = 341 checked(relType.getRoleInfos(), RoleInfo.class); 342 // Since there's no RoleInfo.equals and since the RelationTypeSupport 343 // constructor clones the RoleInfos passed to it, it's tricky to 344 // test equality here so we check type and size and have done with it 345 check("List<RoleInfo> RelationType.getRoleInfos", 346 relTypeRoleInfos.size() == 2); 347 348 MBeanServerNotificationFilter mbsnf = 349 new MBeanServerNotificationFilter(); 350 mbsnf.enableObjectName(moduleA); 351 check("Vector<ObjectName> MBeanServerNotificationFilter." + 352 "getEnabledObjectNames", 353 mbsnf.getEnabledObjectNames().equals(Arrays.asList(moduleA))); 354 mbsnf.enableAllObjectNames(); 355 mbsnf.disableObjectName(moduleB); 356 check("Vector<ObjectName> MBeanServerNotificationFilter." + 357 "getDisabledObjectNames", 358 mbsnf.getDisabledObjectNames().equals(Arrays.asList(moduleB))); 359 360 RelationService unusedRelSvc = new RelationService(false); 361 RelationNotification rn1 = 362 new RelationNotification(RelationNotification.RELATION_MBEAN_REMOVAL, 363 unusedRelSvc, 0L, 0L, "yo!", 364 "A-DependsOn-B", "DependsOn", null, 365 singletonList(moduleA)); 366 List<ObjectName> toUnreg = 367 checked(rn1.getMBeansToUnregister(), ObjectName.class); 368 check("List<ObjectName> RelationNotification.getMBeansToUnregister", 369 toUnreg.equals(singletonList(moduleA))); 370 371 RelationNotification rn2 = 372 new RelationNotification(RelationNotification.RELATION_MBEAN_UPDATE, 373 unusedRelSvc, 0L, 0L, "yo!", 374 "A-DependsOn-B", "DependsOn", null, 375 "dependent", singletonList(moduleA), 376 singletonList(moduleB)); 377 check("List<ObjectName> RelationNotification.getOldRoleValue", 378 checked(rn2.getOldRoleValue(), ObjectName.class) 379 .equals(singletonList(moduleB))); 380 check("List<ObjectName> RelationNotification.getNewRoleValue", 381 checked(rn2.getNewRoleValue(), ObjectName.class) 382 .equals(singletonList(moduleA))); 383 384 ObjectName timerName = new ObjectName(":type=timer"); 385 mbs.registerMBean(new Timer(), timerName); 386 TimerMBean timer = 387 MBeanServerInvocationHandler.newProxyInstance(mbs, 388 timerName, 389 TimerMBean.class, 390 false); 391 Date doomsday = new Date(Long.MAX_VALUE); 392 int timer1 = timer.addNotification("one", "one", null, doomsday); 393 int timer2 = timer.addNotification("two", "two", null, doomsday); 394 Vector<Integer> idsOne = timer.getNotificationIDs("one"); 395 check("Vector<Integer> TimerMBean.getNotificationIDs", 396 idsOne.equals(singletonList(timer1))); 397 Vector<Integer> allIds = timer.getAllNotificationIDs(); 398 check("Vector<Integer> TimerMBean.getAllNotificationIDs", 399 equalListContents(allIds, 400 Arrays.asList(new Integer[]{timer1, timer2}))); 401 402 // ADD NEW TEST CASES ABOVE THIS COMMENT 403 404 if (failures == 0) 405 System.out.println("All tests passed"); 406 else { 407 System.out.println("TEST FAILURES: " + failures); 408 System.exit(1); 409 } 410 411 // DO NOT ADD NEW TEST CASES HERE, ADD THEM ABOVE THE PREVIOUS COMMENT 412 } 413 414 public static interface StupidMBean { getFive()415 public int getFive(); 416 } 417 418 public static class Stupid implements StupidMBean { getFive()419 public int getFive() { 420 return 5; 421 } 422 } 423 424 public static class Module extends StandardMBean implements StupidMBean { Module()425 public Module() throws NotCompliantMBeanException { 426 super(StupidMBean.class); 427 } 428 getFive()429 public int getFive() { 430 return 5; 431 } 432 } 433 singletonList(E value)434 private static <E> List<E> singletonList(E value) { 435 return Collections.singletonList(value); 436 } 437 singleton(E value)438 private static <E> Set<E> singleton(E value) { 439 return Collections.singleton(value); 440 } 441 singletonMap(K key, V value)442 private static <K,V> Map<K,V> singletonMap(K key, V value) { 443 return Collections.singletonMap(key, value); 444 } 445 checked(List<E> c, Class<E> type)446 private static <E> List<E> checked(List<E> c, Class<E> type) { 447 List<E> unchecked = new ArrayList<E>(); 448 List<E> checked = Collections.checkedList(unchecked, type); 449 checked.addAll(c); 450 return Collections.checkedList(c, type); 451 } 452 checked(Set<E> c, Class<E> type)453 private static <E> Set<E> checked(Set<E> c, Class<E> type) { 454 Set<E> unchecked = new HashSet<E>(); 455 Set<E> checked = Collections.checkedSet(unchecked, type); 456 checked.addAll(c); 457 return Collections.checkedSet(c, type); 458 } 459 checked(Map<K,V> m, Class<K> keyType, Class<V> valueType)460 private static <K,V> Map<K,V> checked(Map<K,V> m, 461 Class<K> keyType, 462 Class<V> valueType) { 463 Map<K,V> unchecked = new HashMap<K,V>(); 464 Map<K,V> checked = Collections.checkedMap(unchecked, keyType, valueType); 465 checked.putAll(m); 466 return Collections.checkedMap(m, keyType, valueType); 467 } 468 469 /* The fact that we have to call this method is a clear signal that 470 * the API says List where it means Set. 471 */ equalListContents(List<E> l1, List<E> l2)472 private static <E> boolean equalListContents(List<E> l1, List<E> l2) { 473 return new HashSet<E>(l1).equals(new HashSet<E>(l2)); 474 } 475 check(String what, boolean cond)476 private static void check(String what, boolean cond) { 477 if (cond) 478 System.out.println("OK: " + what); 479 else { 480 System.out.println("FAILED: " + what); 481 failures++; 482 } 483 } 484 } 485