blob: 75f7944edd11b0bd2e366d1ced1753029fbf36d5 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @summary Test that we can create proxies which are NotificationEmitters.
27 * @bug 6411747
28 * @author Daniel Fuchs
29 * @run clean NotificationEmitterProxy
30 * @run build NotificationEmitterProxy
31 * @run main NotificationEmitterProxy
32 */
33
34import java.lang.management.ManagementFactory;
35
36import javax.management.*;
37import javax.management.remote.*;
38import javax.naming.NoPermissionException;
39
40public class NotificationEmitterProxy {
41
42 public static class Counter {
43 int count;
44 public synchronized int count() {
45 count++;
46 notifyAll();
47 return count;
48 }
49 public synchronized int peek() {
50 return count;
51 }
52 public synchronized int waitfor(int max, long timeout)
53 throws InterruptedException {
54 final long start = System.currentTimeMillis();
55 while (count < max && timeout > 0) {
56 final long rest = timeout -
57 (System.currentTimeMillis() - start);
58 if (rest <= 0) break;
59 wait(rest);
60 }
61 return count;
62 }
63 }
64
65 public static class CounterListener
66 implements NotificationListener {
67 final private Counter counter;
68 public CounterListener(Counter counter) {
69 this.counter = counter;
70 }
71 public void handleNotification(Notification notification,
72 Object handback) {
73 System.out.println("Received notif from " + handback +
74 ":\n\t" + notification);
75 counter.count();
76 }
77 }
78
79 public static void main(String[] args) throws Exception {
80 System.out.println("<<< Register for notification from a proxy");
81
82 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
83 final ObjectName name = new ObjectName(":class=Simple");
84
85 JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
86 final JMXConnectorServer server =
87 JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
88 server.start();
89 url = server.getAddress();
90
91 final JMXConnector client = JMXConnectorFactory.connect(url);
92
93 final Counter counter = new Counter();
94 final CounterListener listener = new CounterListener(counter);
95 final Counter mxcounter = new Counter();
96 final CounterListener mxlistener = new CounterListener(mxcounter);
97 final NotificationFilterSupport filter =
98 new NotificationFilterSupport();
99 filter.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);
100 filter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
101 int registered = 0;
102 try {
103 final MBeanServerDelegateMBean delegate =
104 JMX.newMBeanProxy(client.getMBeanServerConnection(),
105 MBeanServerDelegate.DELEGATE_NAME,
106 MBeanServerDelegateMBean.class,
107 true);
108
109 NotificationEmitter emitter = (NotificationEmitter)delegate;
110 emitter.addNotificationListener(listener,filter,"JMX.newMBeanProxy");
111 } catch (Exception x) {
112 throw new RuntimeException("Failed to register listener with "+
113 " JMX.newMBeanProxy: " + x, x);
114 }
115
116 try {
117 final MBeanServerDelegateMBean delegate =
118 MBeanServerInvocationHandler.newProxyInstance(mbs,
119 MBeanServerDelegate.DELEGATE_NAME,
120 MBeanServerDelegateMBean.class,
121 true);
122
123 NotificationEmitter emitter = (NotificationEmitter)delegate;
124 emitter.addNotificationListener(listener,filter,
125 "MBeanServerInvocationHandler.newProxyInstance");
126 } catch (Exception x) {
127 throw new RuntimeException("Failed to register listener with "+
128 " MBeanServerInvocationHandler.newProxyInstance: " + x, x);
129 }
130
131 System.out.println("<<< Register an MBean.");
132
133 final Simple simple = new Simple();
134 mbs.registerMBean(simple, name);
135 registered++;
136
137 SimpleMXBean simple0 =
138 JMX.newMXBeanProxy(client.getMBeanServerConnection(),
139 name,
140 SimpleMXBean.class,
141 true);
142
143 SimpleMXBean simple1 =
144 JMX.newMXBeanProxy(mbs,
145 name,
146 SimpleMXBean.class,
147 false);
148
149 final int expected = 2*registered;
150 final int reg = counter.waitfor(expected,3000);
151 if (reg != expected)
152 throw new RuntimeException("Bad notification count: " + reg +
153 ", expected " +expected);
154 System.out.println("Received expected "+reg+
155 " notifs after registerMBean");
156
157 ((NotificationEmitter)simple0)
158 .addNotificationListener(mxlistener,null,name);
159 simple1.equals("Are you a Wombat?");
160 final int mxnotifs = mxcounter.waitfor(1,3000);
161 if (mxnotifs != 1)
162 throw new RuntimeException("Bad MXBean notification count: " +
163 mxnotifs);
164 System.out.println("Received expected "+mxnotifs+
165 " notifs from MXBean");
166
167 mbs.unregisterMBean(name);
168 final int unreg = counter.waitfor(expected+reg,3000);
169 if (unreg != (expected+reg))
170 throw new RuntimeException("Bad notification count: " + unreg +
171 ", expected " +expected+reg);
172 System.out.println("Received expected "+(unreg-reg)+
173 " notifs after unregisterMBean");
174 System.out.println("Total notifs received: " + unreg);
175
176
177 }
178
179 public static interface Simplest {
180
181 }
182
183 public static interface SimpleMXBean extends Simplest {
184 public String equals(String x);
185 }
186
187 private static class Simple extends NotificationBroadcasterSupport
188 implements SimpleMXBean {
189 public static final String NOTIF_TYPE = "simple.equals";
190 private static long seq=0;
191 private static synchronized long seq() { return ++seq; };
192 public String equals(String x) {
193 sendNotification(new Notification(NOTIF_TYPE,this,seq(),x));
194 return x;
195 }
196
197 }
198
199
200
201 }