/* * 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 EventWithNamespaceTest.java 1.8 * @bug 6539857 * @summary General Namespace & Notifications test. * @author Daniel Fuchs * @run clean EventWithNamespaceTest Wombat WombatMBean * JMXRemoteTargetNamespace * NamespaceController NamespaceControllerMBean * @compile -XDignore.symbol.file=true EventWithNamespaceTest.java * Wombat.java WombatMBean.java JMXRemoteTargetNamespace.java * NamespaceController.java NamespaceControllerMBean.java * @run main EventWithNamespaceTest */ import java.lang.management.ManagementFactory; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.MBeanServerFactory; import javax.management.Notification; import javax.management.NotificationEmitter; import javax.management.NotificationListener; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.namespace.JMXNamespaces; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; /** * * @author Sun Microsystems, Inc. */ public class EventWithNamespaceTest { /** * A logger for this class. **/ private static final Logger LOG = Logger.getLogger(EventWithNamespaceTest.class.getName()); /** Creates a new instance of EventWithNamespaceTest */ public EventWithNamespaceTest() { } private static Map singletonMap(String key, Object value) { final Map map = new HashMap(); map.put(key,value); return map; } public Map getServerMap() { return singletonMap(JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE,"true"); } public JMXServiceURL export(MBeanServer server) throws Exception { final JMXServiceURL in = new JMXServiceURL("rmi",null,0); final Map env = getServerMap(); final JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(in,env,null); final ObjectName csname = ObjectName. getInstance(cs.getClass().getPackage().getName()+ ":type="+cs.getClass().getSimpleName()); server.registerMBean(cs,csname); cs.start(); return cs.getAddress(); } public static class Counter { int count; public synchronized int count() { count++; notifyAll(); return count; } public synchronized int peek() { return count; } public synchronized int waitfor(int max, long timeout) throws InterruptedException { final long start = System.currentTimeMillis(); while (count < max && timeout > 0) { final long rest = timeout - (System.currentTimeMillis() - start); if (rest <= 0) break; wait(rest); } return count; } } public static class CounterListener implements NotificationListener { final private Counter counter; public CounterListener(Counter counter) { this.counter = counter; } public void handleNotification(Notification notification, Object handback) { System.out.println("Received notif from " + handback + ":\n\t" + notification); if (!notification.getSource().equals(handback)) { System.err.println("OhOh... Unexpected source: \n\t"+ notification.getSource()+"\n\twas expecting:\n\t"+ handback); } counter.count(); } } public void simpleTest(String[] args) { try { final MBeanServer server1 = ManagementFactory.getPlatformMBeanServer(); final JMXServiceURL url1 = export(server1); final MBeanServer server2 = MBeanServerFactory.createMBeanServer("server2"); final JMXServiceURL url2 = export(server2); final MBeanServer server3 = MBeanServerFactory.createMBeanServer("server3"); final JMXServiceURL url3 = export(server3); final ObjectInstance ncinst = NamespaceController.createInstance(server1); final NamespaceControllerMBean nc = JMX.newMBeanProxy(server1,ncinst.getObjectName(), NamespaceControllerMBean.class); final String mount2 = nc.mount(url2,"server2",null); final String mount3 = nc.mount(url3,"server2//server3", null); final ObjectName deep = new ObjectName("server2//server3//bush:type=Wombat,name=kanga"); server1.createMBean(Wombat.class.getName(),deep); System.err.println("There's a wombat in the bush!"); final Counter counter = new Counter(); final NotificationListener listener = new CounterListener(counter); final JMXConnector jc = JMXConnectorFactory.connect(url1); final MBeanServerConnection conn1 = jc.getMBeanServerConnection(); final ObjectName shallow = new ObjectName("bush:"+ deep.getKeyPropertyListString()); final MBeanServerConnection conn2 = JMXNamespaces.narrowToNamespace(conn1,"server2//server3"); final WombatMBean proxy1 = JMX.newMBeanProxy(conn1,deep,WombatMBean.class,true); final WombatMBean proxy2 = JMX.newMBeanProxy(conn2,shallow,WombatMBean.class,true); System.err.println("Adding first Notification Listener"); conn1.addNotificationListener(deep,listener,null,deep); System.err.println("Adding second Notification Listener"); ((NotificationEmitter)proxy2). addNotificationListener(listener,null,shallow); final JMXConnector c3 = JMXConnectorFactory.connect(url3, singletonMap(JMXConnector.USE_EVENT_SERVICE,"false")); System.err.println("Adding third Notification Listener"); c3.getMBeanServerConnection(). addNotificationListener(shallow,listener,null,shallow); System.err.println("Set attribute to trigger notif"); proxy1.setCaption("I am a new Wombat!"); System.err.println("Get attribute"); System.err.println("New caption: "+proxy2.getCaption()); System.err.println("Wait for Notifs..."); final int rcvcount = counter.waitfor(3,3000); if (rcvcount != 3) throw new RuntimeException("simpleTest failed: "+ "received count is " +rcvcount); System.err.println("simpleTest: got expected "+rcvcount+ " notifs"); System.err.println("removing all listeners"); conn1.removeNotificationListener(deep,listener,null,deep); ((NotificationEmitter)proxy2) .removeNotificationListener(listener,null,shallow); c3.getMBeanServerConnection(). removeNotificationListener(shallow,listener,null,shallow); System.err.println("simpleTest passed: got "+rcvcount+ " notifs"); } catch (RuntimeException x) { throw x; } catch (Exception x) { throw new RuntimeException("simpleTest failed: " + x,x); } } public void run(String[] args) { simpleTest(args); } public static void main(String[] args) { new EventWithNamespaceTest().run(args); } }