/* * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 4847959 6191402 * @summary Test newly-generified APIs * @author Eamonn McManus * * @run clean GenericTest * @run build GenericTest * @run main GenericTest */ import java.lang.management.ManagementFactory; import java.lang.reflect.*; import java.util.*; import javax.management.*; import javax.management.openmbean.*; import javax.management.relation.*; import javax.management.timer.Timer; import javax.management.timer.TimerMBean; public class GenericTest { private static int failures; public static void main(String[] args) throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // Check we are really using the generified version boolean generic; Method findmbs = MBeanServerFactory.class.getMethod("findMBeanServer", String.class); Type findmbstype = findmbs.getGenericReturnType(); if (!(findmbstype instanceof ParameterizedType)) { System.out.println("FAILURE: API NOT GENERIC!"); System.out.println(" MBeanServerFactory.findMBeanServer -> " + findmbstype); failures++; generic = false; } else { System.out.println("OK: this API is generic"); generic = true; } ArrayList mbsList1 = MBeanServerFactory.findMBeanServer(null); checked(mbsList1, MBeanServer.class); ArrayList mbsList2 = MBeanServerFactory.findMBeanServer(null); check("ArrayList findMBeanServer", mbsList1.size() == 1); check("ArrayList findMBeanServer", mbsList1.equals(mbsList2)); Set names1 = checked(mbs.queryNames(null, null), ObjectName.class); Set names2 = mbs.queryNames(null, null); Set names3 = checked(((MBeanServerConnection) mbs).queryNames(null, null), ObjectName.class); check("Set MBeanServer.queryNames", names1.size() >= 1); check("Set MBeanServer.queryNames", names2.size() >= 1); check("Set MBeanServerConnection.queryNames", names3.size() >= 1); check("queryNames sets same", names1.equals(names2) && names2.equals(names3)); Set mbeans1 = checked(mbs.queryMBeans(null, null), ObjectInstance.class); Set mbeans2 = mbs.queryMBeans(null, null); Set mbeans3 = checked(((MBeanServerConnection) mbs).queryMBeans(null, null), ObjectInstance.class); check("Set MBeanServer.queryMBeans", mbeans1.size() >= 1); check("Set MBeanServer.queryMBeans", mbeans2.size() >= 1); check("Set MBeanServerConnection.queryMBeans", mbeans3.size() >= 1); check("queryMBeans sets same", mbeans1.equals(mbeans2) && mbeans2.equals(mbeans3)); AttributeChangeNotificationFilter acnf = new AttributeChangeNotificationFilter(); acnf.enableAttribute("foo"); Vector acnfs = acnf.getEnabledAttributes(); checked(acnfs, String.class); check("Vector AttributeChangeNotificationFilter.getEnabled" + "Attributes", acnfs.equals(Arrays.asList(new String[] {"foo"}))); if (generic) { Attribute a = new Attribute("foo", "bar"); AttributeList al1 = new AttributeList(); al1.add(a); AttributeList al2 = new AttributeList(Arrays.asList(new Attribute[] {a})); check("new AttributeList(List)", al1.equals(al2)); List al3 = checked(al1.asList(), Attribute.class); al3.remove(a); check("List AttributeList.asList()", al1.equals(al3) && al1.isEmpty()); } List namelist1 = new ArrayList(names1); Role role = new Role("rolename", namelist1); List namelist2 = checked(role.getRoleValue(), ObjectName.class); check("new Role(String,List).getRoleValue() -> " + "List", namelist1.equals(namelist2)); RoleList rl1 = new RoleList(); rl1.add(role); RoleList rl2 = new RoleList(Arrays.asList(new Role[] {role})); check("new RoleList(List)", rl1.equals(rl2)); if (generic) { List rl3 = checked(rl1.asList(), Role.class); rl3.remove(role); check("List RoleList.asList()", rl1.equals(rl3) && rl1.isEmpty()); } RoleUnresolved ru = new RoleUnresolved("rolename", namelist1, RoleStatus.LESS_THAN_MIN_ROLE_DEGREE); List namelist3 = checked(ru.getRoleValue(), ObjectName.class); check("new RoleUnresolved(...List...).getRoleValue() -> " + "List", namelist1.equals(namelist3)); RoleUnresolvedList rul1 = new RoleUnresolvedList(); rul1.add(ru); RoleUnresolvedList rul2 = new RoleUnresolvedList(Arrays.asList(new RoleUnresolved[] {ru})); check("new RoleUnresolvedList(List", rul1.equals(rul2)); if (generic) { List rul3 = checked(rul1.asList(), RoleUnresolved.class); rul3.remove(ru); check("List RoleUnresolvedList.asList()", rul1.equals(rul3) && rul1.isEmpty()); } // This case basically just tests that we can compile this sort of thing OpenMBeanAttributeInfo ombai1 = new OpenMBeanAttributeInfoSupport("a", "a descr", SimpleType.INTEGER, true, true, false); CompositeType ct = new CompositeType("ct", "ct descr", new String[] {"item1"}, new String[] {"item1 descr"}, new OpenType[] {SimpleType.INTEGER}); OpenMBeanAttributeInfo ombai2 = new OpenMBeanAttributeInfoSupport("a", "a descr", ct, true, true, false); TabularType tt = new TabularType("tt", "tt descr", ct, new String[] {"item1"}); OpenMBeanAttributeInfo ombai3 = new OpenMBeanAttributeInfoSupport("a", "a descr", tt, true, true, false); ArrayType at = new ArrayType(2, SimpleType.STRING); OpenMBeanAttributeInfo ombai4 = new OpenMBeanAttributeInfoSupport("a", "a descr", at, true, true, false); OpenMBeanAttributeInfo ombai4a = new OpenMBeanAttributeInfoSupport("a", "a descr", (ArrayType) at, true, true, false); OpenMBeanAttributeInfo ombai5 = new OpenMBeanAttributeInfoSupport("a", "a descr", SimpleType.INTEGER, true, true, false, 5, 1, 9); OpenMBeanAttributeInfo ombai6 = new OpenMBeanAttributeInfoSupport("a", "a descr", SimpleType.INTEGER, true, true, false, 5, new Integer[] {1, 5}); OpenMBeanInfo ombi = new OpenMBeanInfoSupport("a.a", "a.a descr", new OpenMBeanAttributeInfo[] { ombai1, ombai2, ombai3, ombai4, ombai5, ombai6, }, null, null, null); Map itemMap = checked(singletonMap("item1", 5), String.class, Integer.class); CompositeData cd = new CompositeDataSupport(ct, itemMap); check("CompositeDataSupport(CompositeType, Map", cd.get("item1").equals(5)); Set ctkeys = checked(ct.keySet(), String.class); check("Set CompositeType.keySet()", ctkeys.equals(singleton("item1"))); List ttindex = checked(tt.getIndexNames(), String.class); check("Set TabularType.getIndexNames()", ttindex.equals(singletonList("item1"))); TabularData td = new TabularDataSupport(tt); td.putAll(new CompositeData[] {cd}); List tdkey = checked(singletonList(5), Integer.class); Set> tdkeys = checked(singleton(tdkey), (Class>) tdkey.getClass()); Collection tdvalues = checked(singleton(cd), CompositeData.class); check("Set> TabularDataSupport.keySet()", td.keySet().equals(tdkeys)); check("Collection TabularDataSupport.values()", td.values().iterator().next().equals(tdvalues.iterator().next())); ObjectName stupidName = new ObjectName("stupid:a=b"); mbs.registerMBean(new Stupid(), stupidName); StupidMBean proxy = MBeanServerInvocationHandler.newProxyInstance(mbs, stupidName, StupidMBean.class, false); check("MBeanServerInvocationHandler.newProxyInstance", proxy.getFive() == 5); mbs.unregisterMBean(stupidName); mbs.registerMBean(new StandardMBean(new Stupid(), StupidMBean.class), stupidName); check(" StandardMBean(T impl, Class intf)", proxy.getFive() == 5); // Following is based on the package.html for javax.management.relation // Create the Relation Service MBean ObjectName relSvcName = new ObjectName(":type=RelationService"); RelationService relSvcObject = new RelationService(true); mbs.registerMBean(relSvcObject, relSvcName); // Create an MBean proxy for easier access to the Relation Service RelationServiceMBean relSvc = MBeanServerInvocationHandler.newProxyInstance(mbs, relSvcName, RelationServiceMBean.class, false); // Define the DependsOn relation type RoleInfo[] dependsOnRoles = { new RoleInfo("dependent", Module.class.getName()), new RoleInfo("dependedOn", Module.class.getName()) }; relSvc.createRelationType("DependsOn", dependsOnRoles); // Now define a relation instance "moduleA DependsOn moduleB" ObjectName moduleA = new ObjectName(":type=Module,name=A"); ObjectName moduleB = new ObjectName(":type=Module,name=B"); // Following two lines added to example: mbs.registerMBean(new Module(), moduleA); mbs.registerMBean(new Module(), moduleB); Role dependent = new Role("dependent", singletonList(moduleA)); Role dependedOn = new Role("dependedOn", singletonList(moduleB)); Role[] roleArray = {dependent, dependedOn}; RoleList roles = new RoleList(Arrays.asList(roleArray)); relSvc.createRelation("A-DependsOn-B", "DependsOn", roles); // Query the Relation Service to find what modules moduleA depends on Map> dependentAMap = relSvc.findAssociatedMBeans(moduleA, "DependsOn", "dependent"); Set dependentASet = dependentAMap.keySet(); dependentASet = checked(dependentASet, ObjectName.class); // Set of ObjectName containing moduleB check("Map> RelationService.findAssociatedMBeans", dependentAMap.size() == 1 && dependentASet.equals(singleton(moduleB))); Map> refRels = relSvc.findReferencingRelations(moduleA, "DependsOn", "dependent"); List refRoles = checked(refRels.get("A-DependsOn-B"), String.class); check("Map> RelationService.findReferencingRelations", refRoles.equals(singletonList("dependent"))); List relsOfType = relSvc.findRelationsOfType("DependsOn"); relsOfType = checked(relsOfType, String.class); check("List RelationService.findRelationsOfType", relsOfType.equals(singletonList("A-DependsOn-B"))); List allRelIds = relSvc.getAllRelationIds(); allRelIds = checked(allRelIds, String.class); check("List RelationService.getAllRelationIds()", allRelIds.equals(singletonList("A-DependsOn-B"))); List allRelTypes = relSvc.getAllRelationTypeNames(); allRelTypes = checked(allRelTypes, String.class); check("List RelationService.getAllRelationTypeNames", allRelTypes.equals(singletonList("DependsOn"))); Map> refdMBeans = relSvc.getReferencedMBeans("A-DependsOn-B"); check("Map> RelationService.getReferencedMBeans", refdMBeans.get(moduleA).equals(singletonList("dependent")) && refdMBeans.get(moduleB).equals(singletonList("dependedOn"))); List roleContents = checked(relSvc.getRole("A-DependsOn-B", "dependent"), ObjectName.class); check("List RelationService.getRole", roleContents.equals(singletonList(moduleA))); RoleInfo roleInfoDependent = relSvc.getRoleInfo("DependsOn", "dependent"); RoleInfo roleInfoDependedOn = relSvc.getRoleInfo("DependsOn", "dependedOn"); List expectedRoleInfos = Arrays.asList(new RoleInfo[] {roleInfoDependent, roleInfoDependedOn}); List roleInfos = checked(relSvc.getRoleInfos("DependsOn"), RoleInfo.class); check("List RelationService.getRoleInfos", equalListContents(expectedRoleInfos, roleInfos)); RelationType relType = new RelationTypeSupport("DependsOn", dependsOnRoles); List relTypeRoleInfos = checked(relType.getRoleInfos(), RoleInfo.class); // Since there's no RoleInfo.equals and since the RelationTypeSupport // constructor clones the RoleInfos passed to it, it's tricky to // test equality here so we check type and size and have done with it check("List RelationType.getRoleInfos", relTypeRoleInfos.size() == 2); MBeanServerNotificationFilter mbsnf = new MBeanServerNotificationFilter(); mbsnf.enableObjectName(moduleA); check("Vector MBeanServerNotificationFilter." + "getEnabledObjectNames", mbsnf.getEnabledObjectNames().equals(Arrays.asList(moduleA))); mbsnf.enableAllObjectNames(); mbsnf.disableObjectName(moduleB); check("Vector MBeanServerNotificationFilter." + "getDisabledObjectNames", mbsnf.getDisabledObjectNames().equals(Arrays.asList(moduleB))); RelationService unusedRelSvc = new RelationService(false); RelationNotification rn1 = new RelationNotification(RelationNotification.RELATION_MBEAN_REMOVAL, unusedRelSvc, 0L, 0L, "yo!", "A-DependsOn-B", "DependsOn", null, singletonList(moduleA)); List toUnreg = checked(rn1.getMBeansToUnregister(), ObjectName.class); check("List RelationNotification.getMBeansToUnregister", toUnreg.equals(singletonList(moduleA))); RelationNotification rn2 = new RelationNotification(RelationNotification.RELATION_MBEAN_UPDATE, unusedRelSvc, 0L, 0L, "yo!", "A-DependsOn-B", "DependsOn", null, "dependent", singletonList(moduleA), singletonList(moduleB)); check("List RelationNotification.getOldRoleValue", checked(rn2.getOldRoleValue(), ObjectName.class) .equals(singletonList(moduleB))); check("List RelationNotification.getNewRoleValue", checked(rn2.getNewRoleValue(), ObjectName.class) .equals(singletonList(moduleA))); ObjectName timerName = new ObjectName(":type=timer"); mbs.registerMBean(new Timer(), timerName); TimerMBean timer = MBeanServerInvocationHandler.newProxyInstance(mbs, timerName, TimerMBean.class, false); Date doomsday = new Date(Long.MAX_VALUE); int timer1 = timer.addNotification("one", "one", null, doomsday); int timer2 = timer.addNotification("two", "two", null, doomsday); Vector idsOne = timer.getNotificationIDs("one"); check("Vector TimerMBean.getNotificationIDs", idsOne.equals(singletonList(timer1))); Vector allIds = timer.getAllNotificationIDs(); check("Vector TimerMBean.getAllNotificationIDs", equalListContents(allIds, Arrays.asList(new Integer[]{timer1, timer2}))); // ADD NEW TEST CASES ABOVE THIS COMMENT if (failures == 0) System.out.println("All tests passed"); else { System.out.println("TEST FAILURES: " + failures); System.exit(1); } // DO NOT ADD NEW TEST CASES HERE, ADD THEM ABOVE THE PREVIOUS COMMENT } public static interface StupidMBean { public int getFive(); } public static class Stupid implements StupidMBean { public int getFive() { return 5; } } public static class Module extends StandardMBean implements StupidMBean { public Module() throws NotCompliantMBeanException { super(StupidMBean.class); } public int getFive() { return 5; } } private static List singletonList(E value) { return Collections.singletonList(value); } private static Set singleton(E value) { return Collections.singleton(value); } private static Map singletonMap(K key, V value) { return Collections.singletonMap(key, value); } private static List checked(List c, Class type) { List unchecked = new ArrayList(); List checked = Collections.checkedList(unchecked, type); checked.addAll(c); return Collections.checkedList(c, type); } private static Set checked(Set c, Class type) { Set unchecked = new HashSet(); Set checked = Collections.checkedSet(unchecked, type); checked.addAll(c); return Collections.checkedSet(c, type); } private static Map checked(Map m, Class keyType, Class valueType) { Map unchecked = new HashMap(); Map checked = Collections.checkedMap(unchecked, keyType, valueType); checked.putAll(m); return Collections.checkedMap(m, keyType, valueType); } /* The fact that we have to call this method is a clear signal that * the API says List where it means Set. */ private static boolean equalListContents(List l1, List l2) { return new HashSet(l1).equals(new HashSet(l2)); } private static void check(String what, boolean cond) { if (cond) System.out.println("OK: " + what); else { System.out.println("FAILED: " + what); failures++; } } }