--- a/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java Wed Oct 21 15:47:09 2009 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +0,0 @@
-/*
- * 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 JMXNamespaceViewTest.java
- * @summary Test the JMXNamespaceView class.
- * @bug 5072476
- * @author Daniel Fuchs
- * @run clean JMXNamespaceViewTest Wombat WombatMBean
- * @run build JMXNamespaceViewTest Wombat WombatMBean
- * @run main JMXNamespaceViewTest
- */
-
-
-import java.lang.management.ManagementFactory;
-import java.net.ServerSocket;
-import java.rmi.registry.LocateRegistry;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.management.ClientContext;
-import javax.management.JMException;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.namespace.JMXNamespace;
-import javax.management.namespace.JMXNamespaceView;
-import javax.management.namespace.JMXNamespaces;
-import javax.management.namespace.JMXRemoteNamespace;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-
-/**
- * A simple test to test the JMXNamespaceViewTest...
- * @author dfuchs
- */
-public class JMXNamespaceViewTest {
-
- /**
- * Describe the configuration of a namespace
- */
- public static class NamespaceConfig {
- /** name of the namespace - no // allowed **/
- public String name;
- /**
- * JMXServiceURL through which the namespace is exported, if it
- * is a remote namespace. {@code null} if the namespace is local.
- * This is an inpur URL - eg: new JMXServiceURL("rmi",null,0).toString()
- * is acceptable here.
- */
- public String jmxurl;
- /**
- * Values of the name= key for each WombatMBean contained in the
- * namespace.
- */
- public String[] wombats;
- /** list of child namespace **/
- public NamespaceConfig[] children;
- }
-
- /**
- * Creates a NamespaceConfig record for a local namespace.
- * @param name name of the namespace
- * @param wombats names of WombatMBean it should contain.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String[] wombats) {
- return config(name,null,wombats);
- }
-
- /**
- * Creates a NamespaceConfig record for a remote namespace.
- * @param name name of the namespace
- * @param jmxurl input JMXServiceURL for creating the JMXConnectorServer
- * @param wombats names of WombatMBean it should contain.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String jmxurl,
- String[] wombats) {
- return config(name,jmxurl,wombats,(NamespaceConfig[])null);
- }
-
- /**
- * Creates a NamespaceConfig record for a local namespace.
- * @param name name of the namespace
- * @param wombats names of WombatMBean it should contain.
- * @param children list of sub namespaces.
- * @return a NamespaceConfig.
- */
- public static NamespaceConfig config(String name, String[] wombats,
- NamespaceConfig... children) {
- return config(name,null,wombats,children);
- }
-
- /**
- * Creates a NamespaceConfig record for a remote namespace.
- * @param name name of the namespace
- * @param jmxurl input JMXServiceURL for creating the JMXConnectorServer
- * @param wombats names of WombatMBean it should contain.
- * @param children list of sub namespaces.
- * @return a NamespaceConfig.
- */
- static NamespaceConfig config(String name, String jmxurl, String[] wombats,
- NamespaceConfig... children) {
- final NamespaceConfig cfg = new NamespaceConfig();
- cfg.name=name; cfg.jmxurl=jmxurl; cfg.wombats=wombats;
- cfg.children=children;
- return cfg;
- }
-
- /**
- * Returns the given names. This is a utility method to ease code
- * reading.
- * @param names names of Wombat MBeans.
- * @return the given names.
- */
- static String[] wombats(String... names) {
- return names;
- }
-
- /**
- * Creates a JMXServiceURL string for the given protocol.
- * This is also a utility method to ease code reading.
- * @param protocol The protocol name (e.g. "rmi")
- * @return A JMXServiceURL string.
- * @throws Exception if creation of the JMXServiceURL fails.
- */
- static String url(String protocol) throws Exception {
- return new JMXServiceURL(protocol,null,0).toString();
- }
-
- /**
- * Creates a config for a hierarchy of namespaces, mixing local namespaces
- * and remote namespaces using the given protocol.
- * @param protocol The protocol that should be used for remote namespaces.
- * @return A namespace config hierarchy.
- * @throws java.lang.Exception
- */
- public static NamespaceConfig[] makeConfig(String protocol)
- throws Exception {
- final NamespaceConfig[] config = {
- // Top level namespace "top1" (local)
- config("top1",wombats("wchief","w1","w2","w3"),
- // top1//local1
- config("local1",wombats("wchief","ww1","ww2")),
- // top1//local2
- config("local2",wombats("wchief","ww4","ww5","ww6"),
- // top1//local2//local3
- config("local3",wombats("wchief","www1","www2")),
- // top1//local2//rmi1
- config("rmi1",url(protocol),wombats("wchief","www3","www4","www5"))),
- // top1//rmi2
- config("rmi2",url(protocol),wombats("wchief","ww7","ww8","ww9"),
- // top1//rmi2//local4
- config("local4",wombats("wchief","www6","www7")),
- // top1//rmi2//rmi3
- config("rmi3",url(protocol),wombats("wchief","www3","www4","www5"),
- // top1//rmi2//rmi3//local5
- config("local5",wombats("wchief","wwww1"))))),
- // Top level namespace "top2" (local)
- config("top2",wombats("wchief","w21","w22","w23"),
- // top2//local21
- config("local21",wombats("wchief","ww21","ww22")),
- // top2//rmi22
- config("rmi22",url(protocol),wombats("wchief","ww27","ww28","ww29"),
- // top2//rmi22//local24
- config("local24",wombats("wchief","www26","www27")),
- // top2//rmi22//rmi23
- config("rmi23",url(protocol),wombats("wchief","www23","www24","www25"),
- // top2//rmi22//rmi23//local25
- config("local25",wombats("wchief","wwww21"))))),
- // Top level namespace "top3" (remote)
- config("top3",url(protocol),wombats("wchief","w31","w32","w33"),
- // top3//local31
- config("local31",wombats("wchief","ww31","ww32")),
- // top3//rmi32
- config("rmi32",url(protocol),wombats("wchief","ww37","ww38","ww39"),
- // top3//rmi32//local34
- config("local34",wombats("wchief","www36","www37")),
- // top3//rmi32//rmi33
- config("rmi33",url(protocol),wombats("wchief","www33","www34","www35"),
- // top3//rmi32//local35
- config("local35",wombats("wchief","wwww31"))))),
- };
- return config;
- }
-
- /**
- * Close all connector servers in the list.
- * @param cslist List of connector servers to close.
- */
- public static void closeAll(List<JMXConnectorServer> cslist) {
- for (JMXConnectorServer cs : cslist) {
- try {
- cs.stop();
- } catch (Exception xx) {
- System.err.println("Failed to stop connector: " + xx);
- }
- }
- }
-
- public static class MBeanServerConfigCreator {
- public MBeanServer createMBeanServerFor(NamespaceConfig config) {
- return MBeanServerFactory.newMBeanServer();
- }
- }
-
- /**
- * Load the given namespace configuration inside the given MBeanServer.
- * Return a list of connector servers created in the process.
- * @param server The MBeanServer in which the namespaces must
- * be created.
- * @param namespaces The list of namespaces to create.
- * @return a list of started connector servers.
- * @throws java.lang.Exception failed to create the specified namespaces.
- */
- public static List<JMXConnectorServer> load(MBeanServer server,
- MBeanServerConfigCreator factory,
- NamespaceConfig... namespaces) throws Exception {
- final List<JMXConnectorServer> cslist =
- new ArrayList<JMXConnectorServer>();
- try {
- final ObjectName creator =
- new ObjectName("jmx.creator:type=JMXNamespaceCreator");
- if (System.getProperty("jmx.wait")!=null
- && !server.isRegistered(creator)) {
- server.registerMBean(new JMXNamespaceCreator(),creator);
- }
- for (NamespaceConfig cfg : namespaces) {
- final MBeanServer srv = factory.createMBeanServerFor(cfg);
- if (System.getProperty("jmx.wait")!=null
- && !srv.isRegistered(creator)) {
- srv.registerMBean(new JMXNamespaceCreator(),creator);
- }
- if (cfg.wombats != null) {
- for (String w : cfg.wombats) {
- final ObjectName n =
- new ObjectName("wombat:type=Wombat,name=" + w);
- final WombatMBean ww = new Wombat();
- srv.registerMBean(ww, n);
- }
- }
- if (cfg.children != null) {
- cslist.addAll(load(srv, factory, cfg.children));
- }
- JMXNamespace nm;
- if (cfg.jmxurl == null) {
- nm = new JMXNamespace(srv);
- } else {
- JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL(cfg.jmxurl),
- null, srv);
- srv.registerMBean(cs,
- new ObjectName("jmx.remote:type=JMXConnectorServer"));
- cs.start();
- cslist.add(cs);
- nm = JMXRemoteNamespace.
- newJMXRemoteNamespace(cs.getAddress(),
- null);
- }
- server.registerMBean(nm,
- JMXNamespaces.getNamespaceObjectName(cfg.name));
- if (nm instanceof JMXRemoteNamespace) {
- server.invoke(
- JMXNamespaces.getNamespaceObjectName(cfg.name),
- "connect", null, null);
- }
- }
- } catch (Exception x) {
- closeAll(cslist);
- throw x;
- }
- return cslist;
- }
-
- /**
- * Add an entry {@code <path,NamespaceConfig>} in the map for the given
- * namespace and its subnamespaces.
- * @param map A {@code Map<path,NamespaceConfig>}.
- * @param parent The path of the parent workspace.
- * @param cfg The NamespaceConfig hierarchy to index in the map.
- */
- public static void fillMap(Map<String,NamespaceConfig> map, String parent,
- NamespaceConfig cfg) {
-
- final String where;
- if (parent == null || parent.equals(""))
- where=cfg.name;
- else
- where=parent+JMXNamespaces.NAMESPACE_SEPARATOR+cfg.name;
- map.put(where,cfg);
- if (cfg.children==null) return;
- for(NamespaceConfig child:cfg.children) {
- fillMap(map,where,child);
- }
- }
-
- /**
- * Compare a list of namespace names obtained from JMXNamespaceView.list()
- * with the expected clildren list of the corresponding NamespaceConfig.
- * @param list A list of namespace names
- * @param children A list of NamespaceConfig correspondng to expected
- * namespace.
- * @param fail If true and the comparison yields false, throws an
- * exception instead of simply returning false.
- * @return true if OK, false if NOK.
- */
- private static boolean compare(String[] list, NamespaceConfig[] children,
- boolean fail) {
- final List<String> found = new ArrayList<String>(Arrays.asList(list));
- if (found.contains(ClientContext.NAMESPACE))
- found.remove(ClientContext.NAMESPACE);
-
- if (children == null && found.size()==0) return true;
- if (children == null && fail == false) return false;
- if (children == null) throw new RuntimeException(
- "No child expected. Found "+Arrays.toString(list));
- final Set<String> names = new HashSet<String>();
- for (NamespaceConfig cfg : children) {
- names.add(cfg.name);
- if (found.contains(cfg.name)) continue;
- if (!fail) return false;
- throw new RuntimeException(cfg.name+" not found in "+
- found);
- }
- found.removeAll(names);
- if (found.size()==0) return true;
- if (fail==false) return false;
- throw new RuntimeException("found additional namespaces: "+
- found);
- }
-
- /**
- * Compares the result of queryNames(null,null) with a set of expected
- * wombats.
- * @param where The path of the namespace that was queried.
- * @param list The set of ObjectNames found.
- * @param wombats The expected list of wombats.
- * @param fail If true and the comparison yields false, throws an
- * exception instead of simply returning false.
- * @return true if OK, false if NOK.
- * @throws java.lang.Exception something went wrong.
- */
- private static boolean compare(String where,
- Set<ObjectName>list, String[] wombats,
- boolean fail) throws Exception {
- final Set<ObjectName> found = new HashSet<ObjectName>();
- final Set<ObjectName> expected = new HashSet<ObjectName>();
- for (ObjectName n : list) {
- if ("Wombat".equals(n.getKeyProperty("type")))
- found.add(n);
- }
- for(String w : wombats) {
- final ObjectName n =
- new ObjectName("wombat:type=Wombat,name=" + w);
- expected.add(n);
- if (found.contains(n)) continue;
- if (fail == false) return false;
- throw new RuntimeException(where+
- ": Wombat "+w+" not found in "+found);
- }
- found.removeAll(expected);
- if (found.size()==0) {
- System.out.println(where+": found all expected: "+expected);
- return true;
- }
- if (fail==false) return false;
- throw new RuntimeException(where+": found additional MBeans: "+
- found);
- }
-
- /**
- * A generic test to test JMXNamespaceView over a namespace configuration.
- * @param server The MBeanServer in which to load the namespace
- * config.
- * @param namespaces The namespace config to run the test over...
- * @throws java.lang.Exception
- */
- public static void doTest(MBeanServer server, NamespaceConfig... namespaces)
- throws Exception {
- List<JMXConnectorServer> cslist = load(server,
- new MBeanServerConfigCreator(), namespaces);
- Map<String,NamespaceConfig> inputMap =
- new HashMap<String,NamespaceConfig>();
-
- for (NamespaceConfig cfg : namespaces) {
- fillMap(inputMap,"",cfg);
- }
- try {
- final JMXNamespaceView root = new JMXNamespaceView(server);
- List<JMXNamespaceView> vlist = new ArrayList<JMXNamespaceView>();
- vlist.add(root);
-
- while (!vlist.isEmpty()) {
- JMXNamespaceView v = vlist.remove(0);
- final String where = v.isRoot()?"root":v.where();
- System.out.println(where+": "+
- v.getMBeanServerConnection().queryNames(null,null));
- for (String ns : v.list()) {
- final JMXNamespaceView down = v.down(ns);
- vlist.add(down);
- if (!down.where().equals(v.isRoot()?ns:where+
- JMXNamespaces.NAMESPACE_SEPARATOR+ns)) {
- throw new RuntimeException("path of "+down.where()+
- " should be "+(v.isRoot()?ns:where+
- JMXNamespaces.NAMESPACE_SEPARATOR+ns));
- }
- if (down.up().equals(v)) continue;
- throw new RuntimeException("parent of "+down.where()+
- " should be "+where);
- }
- final NamespaceConfig[] children;
- final NamespaceConfig cfg;
- if (v.isRoot()) {
- children=namespaces;
- cfg = null;
- } else {
- cfg = inputMap.get(where);
- children = cfg==null?null:cfg.children;
- }
- compare(v.list(),children,true);
- if (!v.isRoot()) {
- if (where.endsWith(ClientContext.NAMESPACE)) {
- System.out.println(where+": skipping queryNames analysis");
- continue;
- }
- //System.out.println(where+": cfg is: "+cfg);
- compare(where,v.getMBeanServerConnection().
- queryNames(null, null),cfg.wombats,true);
- }
- }
-
- exportAndWaitIfNeeded(server);
- } finally {
- closeAll(cslist);
- }
- }
-
- public static interface JMXNamespaceCreatorMBean {
- public ObjectInstance createLocalNamespace(String namespace)
- throws JMException ;
- public void removeLocalNamespace(String namespace)
- throws JMException;
- }
-
- public static class JMXNamespaceCreator
- implements MBeanRegistration,
- JMXNamespaceCreatorMBean {
-
- private volatile MBeanServer mbeanServer;
-
- public ObjectInstance createLocalNamespace(String namespace)
- throws JMException {
- return mbeanServer.registerMBean(
- new JMXNamespace(MBeanServerFactory.newMBeanServer()),
- JMXNamespaces.getNamespaceObjectName(namespace));
- }
-
- public void removeLocalNamespace(String namespace)
- throws JMException {
- mbeanServer.unregisterMBean(
- JMXNamespaces.getNamespaceObjectName(namespace));
- }
-
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws Exception {
- mbeanServer = server;
- return name;
- }
-
- public void postRegister(Boolean registrationDone) {
- }
-
- public void preDeregister() throws Exception {
- }
-
- public void postDeregister() {
- }
-
- }
-
- public static void exportAndWaitIfNeeded(MBeanServer server)
- throws Exception {
- if (System.getProperty("jmx.wait")!=null) {
- final int port = getPortFor("rmi");
- LocateRegistry.createRegistry(port);
- final JMXServiceURL url =
- new JMXServiceURL("rmi",null,port,
- "/jndi/rmi://localhost:"+port+"/jmxrmi");
- final JMXConnectorServer cs =
- JMXConnectorServerFactory.
- newJMXConnectorServer(url, null, server);
- cs.start();
- try {
- System.out.println("RMI Server waiting at: "+cs.getAddress());
- System.in.read();
- } finally {
- cs.stop();
- }
- }
- }
-
- public static int getPortFor(String protocol) throws Exception {
- final int aport =
- Integer.valueOf(System.getProperty("jmx."+protocol+".port","0"));
- if (aport > 0) return aport;
- final ServerSocket s = new ServerSocket(0);
- try {
- final int port = s.getLocalPort();
- return port;
- } finally {
- s.close();
- }
- }
-
- public static void main(String[] args) throws Exception {
- doTest(ManagementFactory.getPlatformMBeanServer(),makeConfig("rmi"));
- }
-
-}