/* * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* * * @test QueryNamesTest.java 1.4 * @summary Test how queryNames works with Namespaces. * @author Daniel Fuchs * @bug 5072476 6768935 * @run clean QueryNamesTest Wombat WombatMBean * @run build QueryNamesTest Wombat WombatMBean * @run main QueryNamesTest */ import java.io.IOException; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.logging.Logger; import javax.management.InstanceNotFoundException; import javax.management.JMException; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.RuntimeOperationsException; import javax.management.namespace.JMXNamespace; import javax.management.namespace.JMXNamespaces; /** * Class QueryNamesTest * @author Sun Microsystems, 2005 - All rights reserved. */ public class QueryNamesTest { /** * A logger for this class. **/ private static final Logger LOG = Logger.getLogger(QueryNamesTest.class.getName()); public static class LocalNamespace extends JMXNamespace { private static MBeanServer check(MBeanServer server) { if (server == null) throw new IllegalArgumentException("MBeanServer can't be null"); return server; } public LocalNamespace() { this(MBeanServerFactory.createMBeanServer()); } public LocalNamespace(MBeanServer server) { super(check(server)); } public static String add(MBeanServerConnection server, String nspath) throws IOException, JMException { server.createMBean(LocalNamespace.class.getName(), JMXNamespaces.getNamespaceObjectName(nspath)); return nspath; } } /** Creates a new instance of QueryNamesTest */ public QueryNamesTest() { } private static String[] namespaces = { "greg", "greg//chichille", "greg//chichille//petard", "greg//alambic", "greg//alambic//canette", "greg//chichille/virgule", "greg//chichille/funeste", "greg//chichille/virgule//bidouble", "greg//chichille/virgule//bi/double", "fran", "fran//gast", "fran//gast//gaf", "fran//longtar", "fran//longtar//parcmetre" }; private static void createNamespaces(MBeanServer server) throws Exception { final LinkedList all = new LinkedList(); try { for (String ns : namespaces) all.addFirst(LocalNamespace.add(server,ns)); } catch (Exception e) { removeNamespaces(server,all.toArray(new String[all.size()])); throw e; } } // Dummy test that checks that all JMXNamespaces are registered, // but are not returned by queryNames("*:*"); // private static void checkRegistration(MBeanServer server) throws Exception { final Set handlerNames = new HashSet(namespaces.length); for (String ns : namespaces) handlerNames.add(JMXNamespaces.getNamespaceObjectName(ns)); for (ObjectName nh : handlerNames) // check handler registration if (!server.isRegistered(nh)) throw new InstanceNotFoundException("handler "+nh+ " is not registered"); // global: queryNames("*:*") from top level final Set all1 = server.queryNames(null,null); final Set all2 = server.queryNames(ObjectName.WILDCARD,null); if (!all1.equals(all2)) throw new Exception("queryNames(*:*) != queryNames(null)"); final Set common = new HashSet(all1); common.retainAll(handlerNames); final Set ref = new HashSet(); for (String ns : namespaces) { if (!ns.contains(JMXNamespaces.NAMESPACE_SEPARATOR)) ref.add(JMXNamespaces.getNamespaceObjectName(ns)); } if (!common.equals(ref)) { throw new Exception("some handler names were not returned by " + "wildcard query - only returned: "+common+ ", expected: "+ref); } // for each namespace: queryNames("//*:*"); for (String ns : namespaces) { final ObjectName pattern = new ObjectName(ns+ JMXNamespaces.NAMESPACE_SEPARATOR+"*:*"); final Set all4 = server.queryNames(pattern,null); final Set common4 = new HashSet(all4); common4.retainAll(handlerNames); final Set ref4 = new HashSet(); for (String ns2 : namespaces) { if (! ns2.startsWith(ns+JMXNamespaces.NAMESPACE_SEPARATOR)) continue; if (!ns2.substring(ns.length()+ JMXNamespaces.NAMESPACE_SEPARATOR.length()). contains(JMXNamespaces.NAMESPACE_SEPARATOR)) ref4.add(JMXNamespaces.getNamespaceObjectName(ns2)); } if (!common4.equals(ref4)) { throw new Exception("some handler names were not returned by " + "wildcard query on "+pattern+" - only returned: "+common4+ ", expected: "+ref4); } } } // Make a Map private static Map> makeNsTree(String[] nslist) { final Map> nsTree = new LinkedHashMap>(nslist.length); for (String ns : nslist) { if (nsTree.get(ns) == null) nsTree.put(ns,new LinkedHashSet()); final String[] elts = ns.split(JMXNamespaces.NAMESPACE_SEPARATOR); int last = ns.lastIndexOf(JMXNamespaces.NAMESPACE_SEPARATOR); if (last<0) continue; while (last > 0 && ns.charAt(last-1) == '/') last--; final String parent = ns.substring(0,last); if (nsTree.get(parent) == null) nsTree.put(parent,new LinkedHashSet()); nsTree.get(parent).add(ns); } return nsTree; } private static class Rigolo { final static String[] ones = { "a", "e", "i", "o", "u", "y", "ai", "oo", "ae", "ey", "ay", "oy", "au", "ou", "eu", "oi", "ei", "ea"}; final static String[] twos = { "b", "bz", "c", "cz", "ch", "ct", "ck", "cs", "d", "ds", "f", "g", "gh", "h", "j", "k", "l", "m", "n", "p", "ps", "q", "r", "s", "sh", "t", "v", "w", "x", "z"}; final static String[] threes = {"rr","tt","pp","ss","dd","ff","ll", "mm", "nn", "zz", "cc", "bb"}; final static String[] fours = {"x", "s", "ght", "cks", "rt", "rts", "ghts", "bs", "ts", "gg" }; final static String[] fives = { "br", "bl", "cr", "cn", "cth", "dr", "fr", "fl", "cl", "chr", "gr", "gl", "kr", "kh", "pr", "pl", "ph", "rh", "sr", "tr", "vr"}; private Random rg = new Random(); private String next(String[] table) { return table[rg.nextInt(table.length)]; } public String nextName(int max) { final Random rg = new Random(); final int nl = 3 + rg.nextInt(max); boolean begin = rg.nextBoolean(); StringBuilder sb = new StringBuilder(); for (int j = 0; j < nl ; j++) { if (begin) { sb.append(next(ones)); } else if (j > 0 && j < nl-1 && rg.nextInt(4)==0) { sb.append(next(threes)); } else if (j < nl-1 && rg.nextInt(3)==0) { sb.append(next(fives)); } else { sb.append(next(twos)); } begin = !begin; } if (!begin && rg.nextInt(2)==0) sb.append(next(fours)); return sb.toString(); } private ObjectName getWombatName(String ns, String domain, String name) throws MalformedObjectNameException { String d = domain; if (ns != null && !ns.equals("")) d = ns + JMXNamespaces.NAMESPACE_SEPARATOR + domain; return new ObjectName(d+":type=Wombat,name="+name); } public Set nextWombats(String ns) throws MalformedObjectNameException { final int dcount = 1 + rg.nextInt(5); final Set wombats = new HashSet(); for (int i = 0; i < dcount ; i++) { final String d = nextName(7); final int ncount = 5 + rg.nextInt(20); for (int j = 0 ; j> nsTree = makeNsTree(namespaces); final Random rg = new Random(); final Rigolo rigolo = new Rigolo(); for (String ns : namespaces) { final ObjectName name = JMXNamespaces.getNamespaceObjectName(ns); final String[] doms = (String[])server.getAttribute(name,"Domains"); final Set subs = new HashSet(); for (String d : doms) { if (d.endsWith(JMXNamespaces.NAMESPACE_SEPARATOR)) { subs.add(ns+JMXNamespaces.NAMESPACE_SEPARATOR+d.substring(0, d.length()-JMXNamespaces.NAMESPACE_SEPARATOR.length())); } } final Set expectNs = new HashSet(nsTree.get(ns)); if (! subs.containsAll(expectNs)) throw new Exception("getDomains didn't return all namespaces: "+ "returned="+subs+", expected="+expectNs); if (! expectNs.containsAll(subs)) throw new Exception("getDomains returned additional namespaces: "+ "returned="+subs+", expected="+expectNs); final Set nsNames = server.queryNames( new ObjectName(ns+ JMXNamespaces.NAMESPACE_SEPARATOR+"*"+ JMXNamespaces.NAMESPACE_SEPARATOR+":*"),null); final Set expect = new HashSet(expectNs.size()); for (String sub : expectNs) { expect.add(JMXNamespaces.getNamespaceObjectName(sub)); } if (! nsNames.containsAll(expect)) throw new Exception("queryNames didn't return all namespaces: "+ "returned="+nsNames+", expected="+expect); if (! expect.containsAll(nsNames)) throw new Exception("getDomains returned additional namespaces: "+ "returned="+nsNames+", expected="+expect); } } private static void addWombats(MBeanServer server, Set names) throws Exception { for (ObjectName on : names) { if (! server.isRegistered(on)) { server.createMBean(Wombat.class.getName(),on); System.out.println("A new wombat is born: "+on); } } } private static void addWombats(MBeanServer server, Map> wombats) throws Exception { for (String ns : wombats.keySet()) { addWombats(server,wombats.get(ns)); } } private static Map> nameWombats() throws Exception { final Rigolo rigolo = new Rigolo(); final Map> wombats = new HashMap>(namespaces.length); for (String ns : namespaces) { wombats.put(ns,rigolo.nextWombats(ns)); } wombats.put("",rigolo.nextWombats("")); return wombats; } private static boolean removeWombats(MBeanServer server, Map> wombats) { boolean res = true; for (String ns : wombats.keySet()) { res = res && removeWombats(server,wombats.get(ns)); } return res; } private static boolean removeWombats(MBeanServer server, Set wombats) { boolean res = true; for (ObjectName on : wombats) { try { if (server.isRegistered(on)) server.unregisterMBean(on); } catch (Exception x) { res = false; System.out.println("Failed to remove "+on+": "+x); } } return res; } private static void checkNsPattern(MBeanServer server) throws Exception { final List list = new ArrayList(); for (String s : namespaces) { final String[] cmpnt = s.split("//"); for (int i=0;i res = new HashSet(); try { res.addAll(server.queryNames(ObjectName.valueOf(s),null)); } catch (RuntimeOperationsException x) { if (x.getCause() instanceof IllegalArgumentException) { System.out.println("queryNames("+s+"): OK - received "+x.getCause()); continue; } System.err.println("queryNames("+s+"): Bad cause: "+x.getCause()); throw x; } catch (Exception x) { System.err.println("queryNames("+s+"): Bad exception: "+x); throw x; } System.err.println("queryNames("+s+"): Bad result: "+res); System.err.println("queryNames("+s+"): Excpected exception not thrown."); throw new Exception("queryNames("+s+"): Excpected exception not thrown."); } for (String s : list) { final Set res = new HashSet(); try { res.addAll(server.queryMBeans(ObjectName.valueOf(s),null)); } catch (RuntimeOperationsException x) { if (x.getCause() instanceof IllegalArgumentException) { System.out.println("queryMBeans("+s+"): OK - received "+x.getCause()); continue; } System.err.println("queryMBeans("+s+"): Bad cause: "+x.getCause()); throw x; } catch (Exception x) { System.err.println("queryMBeans("+s+"): Bad exception: "+x); throw x; } System.err.println("queryMBeans("+s+"): Bad result: "+res); System.err.println("queryMBeans("+s+"): Excpected exception not thrown."); throw new Exception("queryMBeans("+s+"): Excpected exception not thrown."); } } public static void main(String[] args) throws Exception { final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); Map> wombats = nameWombats(); createNamespaces(server); try { addWombats(server,wombats); System.out.println("MBeans: " +server.getMBeanCount()); System.out.println("Visible: " +server.queryNames(null,null).size()); System.out.println("Domains: " +Arrays.asList(server.getDomains())); checkRegistration(server); checkNsQuery(server); checkNsPattern(server); } finally { boolean res = true; res = res && removeWombats(server, wombats); if (!res) throw new RuntimeException("failed to cleanup some namespaces"); } } private static boolean removeNamespaces(MBeanServer server) { final List l = Arrays.asList(namespaces); Collections.reverse(l); return removeNamespaces(server, l.toArray(new String[namespaces.length])); } private static boolean removeNamespaces(MBeanServer server, String[] t) { boolean success = true; for (String ns : t) { try { server.unregisterMBean(JMXNamespaces.getNamespaceObjectName(ns)); } catch (Exception x) { System.out.println("failed to remove namespace: "+ ns); success = false; } } return success; } }