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