1 /* |
|
2 * Copyright 2003-2008 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 /* |
|
26 * @test |
|
27 * @bug 6332907 |
|
28 * @summary test the ability for connector server to close individual connections |
|
29 * @author Shanliang JIANG |
|
30 * @run clean CloseConnectionTest |
|
31 * @run build CloseConnectionTest |
|
32 * @run main CloseConnectionTest |
|
33 */ |
|
34 import java.io.IOException; |
|
35 import java.util.ArrayList; |
|
36 import java.util.List; |
|
37 import javax.management.MBeanServerFactory; |
|
38 |
|
39 import javax.management.Notification; |
|
40 import javax.management.NotificationListener; |
|
41 import javax.management.remote.JMXConnectionNotification; |
|
42 import javax.management.remote.JMXConnector; |
|
43 import javax.management.remote.JMXConnectorFactory; |
|
44 import javax.management.remote.JMXServiceURL; |
|
45 import javax.management.remote.JMXConnectorServer; |
|
46 import javax.management.remote.JMXConnectorServerFactory; |
|
47 |
|
48 public class CloseConnectionTest { |
|
49 |
|
50 public static void main(String[] args) throws Exception { |
|
51 System.out.println(">>> Test the ability for connector server to close " + |
|
52 "individual connections."); |
|
53 |
|
54 final String[] protos = new String[]{"rmi", "iiop", "jmxmp"}; |
|
55 for (String p : protos) { |
|
56 System.out.println("\n>>> Testing the protocol " + p); |
|
57 JMXServiceURL addr = new JMXServiceURL(p, null, 0); |
|
58 System.out.println(">>> Creating a JMXConnectorServer on " + addr); |
|
59 JMXConnectorServer server = null; |
|
60 try { |
|
61 server = JMXConnectorServerFactory.newJMXConnectorServer(addr, |
|
62 null, |
|
63 MBeanServerFactory.createMBeanServer()); |
|
64 } catch (Exception e) { |
|
65 System.out.println(">>> Skip the protocol: " + p); |
|
66 continue; |
|
67 } |
|
68 |
|
69 test1(server); |
|
70 test2(server); |
|
71 |
|
72 server.stop(); |
|
73 } |
|
74 |
|
75 System.out.println(">>> Bye bye!"); |
|
76 } |
|
77 |
|
78 private static void test1(JMXConnectorServer server) throws Exception { |
|
79 try { |
|
80 server.closeConnection("toto"); |
|
81 // not started, known id |
|
82 throw new RuntimeException("An IllegalArgumentException is not thrown."); |
|
83 } catch (IllegalStateException e) { |
|
84 System.out.println(">>> Test1: Got expected IllegalStateException: " + e); |
|
85 } |
|
86 |
|
87 server.start(); |
|
88 System.out.println(">>>Test1 Started the server on " + server.getAddress()); |
|
89 |
|
90 try { |
|
91 server.closeConnection("toto"); |
|
92 throw new RuntimeException("An IllegalArgumentException is not thrown."); |
|
93 } catch (IllegalArgumentException e) { |
|
94 System.out.println(">> Test1: Got expected IllegalArgumentException: " + e); |
|
95 } |
|
96 |
|
97 MyListener listener = new MyListener(); |
|
98 server.addNotificationListener(listener, null, null); |
|
99 |
|
100 System.out.println(">>> Test1: Connecting a client to the server ..."); |
|
101 final JMXConnector conn = JMXConnectorFactory.connect(server.getAddress()); |
|
102 conn.getMBeanServerConnection().getDefaultDomain(); |
|
103 final String id1 = conn.getConnectionId(); |
|
104 |
|
105 listener.wait(JMXConnectionNotification.OPENED, timeout); |
|
106 |
|
107 System.out.println(">>> Test1: Closing the connection: " + conn.getConnectionId()); |
|
108 server.closeConnection(id1); |
|
109 listener.wait(JMXConnectionNotification.CLOSED, timeout); |
|
110 |
|
111 System.out.println(">>> Test1: Using again the connector whose connection " + |
|
112 "should be closed by the server, it should reconnect " + |
|
113 "automatically to the server and get a new connection id."); |
|
114 conn.getMBeanServerConnection().getDefaultDomain(); |
|
115 final String id2 = conn.getConnectionId(); |
|
116 listener.wait(JMXConnectionNotification.OPENED, timeout); |
|
117 |
|
118 if (id1.equals(id2)) { |
|
119 throw new RuntimeException("Failed, the first client connection is not closed."); |
|
120 } |
|
121 |
|
122 System.out.println(">>> Test1: Greate, we get a new connection id " + id2 + |
|
123 ", the first one is closed as expected."); |
|
124 |
|
125 System.out.println(">>> Test1: Closing the client."); |
|
126 conn.close(); |
|
127 System.out.println(">>> Test1: Stopping the server."); |
|
128 server.removeNotificationListener(listener); |
|
129 } |
|
130 |
|
131 private static void test2(JMXConnectorServer server) throws Exception { |
|
132 System.out.println(">>> Test2 close a connection before " + |
|
133 "the client can use it..."); |
|
134 final Killer killer = new Killer(server); |
|
135 server.addNotificationListener(killer, null, null); |
|
136 |
|
137 System.out.println(">>> Test2 Connecting a client to the server ..."); |
|
138 final JMXConnector conn; |
|
139 try { |
|
140 conn = JMXConnectorFactory.connect(server.getAddress()); |
|
141 throw new RuntimeException(">>> Failed, do not receive an " + |
|
142 "IOException telling the connection is refused."); |
|
143 } catch (IOException ioe) { |
|
144 System.out.println(">>> Test2 got expected IOException: "+ioe); |
|
145 } |
|
146 } |
|
147 |
|
148 private static class MyListener implements NotificationListener { |
|
149 public void handleNotification(Notification n, Object hb) { |
|
150 if (n instanceof JMXConnectionNotification) { |
|
151 synchronized (received) { |
|
152 received.add((JMXConnectionNotification) n); |
|
153 received.notify(); |
|
154 } |
|
155 } |
|
156 } |
|
157 |
|
158 public JMXConnectionNotification wait(String type, long timeout) |
|
159 throws Exception { |
|
160 JMXConnectionNotification waited = null; |
|
161 long toWait = timeout; |
|
162 long deadline = System.currentTimeMillis() + timeout; |
|
163 synchronized (received) { |
|
164 while (waited == null && toWait > 0) { |
|
165 received.wait(toWait); |
|
166 for (JMXConnectionNotification n : received) { |
|
167 if (type.equals(n.getType())) { |
|
168 waited = n; |
|
169 break; |
|
170 } |
|
171 } |
|
172 received.clear(); |
|
173 toWait = deadline - System.currentTimeMillis(); |
|
174 } |
|
175 } |
|
176 |
|
177 if (waited == null) { |
|
178 throw new RuntimeException("Do not receive expected notification " + type); |
|
179 } else { |
|
180 System.out.println(">>> Received expected notif: "+type+ |
|
181 " "+waited.getConnectionId()); |
|
182 } |
|
183 |
|
184 return waited; |
|
185 } |
|
186 |
|
187 final List<JMXConnectionNotification> received = |
|
188 new ArrayList<JMXConnectionNotification>(); |
|
189 } |
|
190 |
|
191 private static class Killer implements NotificationListener { |
|
192 public Killer(JMXConnectorServer server) { |
|
193 this.server = server; |
|
194 } |
|
195 public void handleNotification(Notification n, Object hb) { |
|
196 if (n instanceof JMXConnectionNotification) { |
|
197 if (JMXConnectionNotification.OPENED.equals(n.getType())) { |
|
198 final JMXConnectionNotification cn = |
|
199 (JMXConnectionNotification)n; |
|
200 try { |
|
201 System.out.println(">>> Killer: close the connection "+ |
|
202 cn.getConnectionId()); |
|
203 server.closeConnection(cn.getConnectionId()); |
|
204 } catch (Exception e) { |
|
205 // impossible? |
|
206 e.printStackTrace(); |
|
207 System.exit(1); |
|
208 } |
|
209 } |
|
210 } |
|
211 } |
|
212 |
|
213 private final JMXConnectorServer server; |
|
214 } |
|
215 |
|
216 private static final long timeout = 6000; |
|
217 } |
|