1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: SocketManagedConnectionFactoryTestCase.java,v 1.4 2005/12/01 13:44:39 tanderson Exp $
44 */
45 package org.exolab.jms.net.socket;
46
47 import java.net.InetAddress;
48 import java.util.ArrayList;
49 import java.util.List;
50
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53
54 import org.exolab.jms.net.connector.ConnectionRequestInfo;
55 import org.exolab.jms.net.connector.ManagedConnection;
56 import org.exolab.jms.net.connector.ManagedConnectionAcceptor;
57 import org.exolab.jms.net.connector.ManagedConnectionFactory;
58 import org.exolab.jms.net.connector.ManagedConnectionFactoryTestCase;
59 import org.exolab.jms.net.connector.ResourceException;
60 import org.exolab.jms.net.connector.TestAcceptorEventListener;
61 import org.exolab.jms.net.connector.TestInvocationHandler;
62 import org.exolab.jms.net.uri.URI;
63 import org.exolab.jms.net.uri.URIHelper;
64
65
66 /***
67 * Tests the {@link SocketManagedConnectionFactory}.
68 *
69 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
70 * @version $Revision: 1.4 $ $Date: 2005/12/01 13:44:39 $
71 */
72 public abstract class SocketManagedConnectionFactoryTestCase extends
73 ManagedConnectionFactoryTestCase {
74
75 /***
76 * The acceptor URI.
77 */
78 private final URI _uri;
79
80 /***
81 * The logger.
82 */
83 static final Log _log
84 = LogFactory.getLog(SocketManagedConnectionFactoryTestCase.class);
85
86
87 /***
88 * Construct an instance of this class for a specific test case.
89 *
90 * @param name the name of test case
91 * @param uri the acceptor URI
92 * @throws Exception for any error
93 */
94 public SocketManagedConnectionFactoryTestCase(String name, String uri)
95 throws Exception {
96 super(name);
97 _uri = new URI(uri);
98 }
99
100 /***
101 * Verifies that clients can connect via the the alternative URI specified
102 * by {@link SocketRequestInfo#getAlternativeHost()}, if the primary URI
103 * cannot be reached.
104 *
105 * @throws Exception for any error
106 */
107 public void testAlternativeURI() throws Exception {
108 URI uri = new URI(_uri);
109 uri.setHost("anonexistenthost1");
110 checkAlternativeURI(uri, _uri.getHost());
111 }
112
113 /***
114 * Verifies that clients can connect via the the alternative URI specified
115 * by {@link SocketRequestInfo#getAlternativeHost()}, if the primary URI
116 * cannot be reached.
117 * In this case, a SecurityException is thrown when attempting to connect
118 * to the primary URI.
119 *
120 * @throws Exception for any error
121 */
122 public void testAlternativeURIWithSecMgr() throws Exception {
123 final URI uri= new URI(_uri);
124 uri.setHost("anonexistenthost2");
125
126 SecurityManager manager = new SecurityManager() {
127 public void checkConnect(String host, int port) {
128 if (host.equals(uri.getHost()) && port == uri.getPort()) {
129 throw new SecurityException(
130 "Cant connect to " + host + ":" + port);
131 }
132
133 }
134 };
135 SecurityManager original = System.getSecurityManager();
136 System.setSecurityManager(manager);
137 try {
138 checkAlternativeURI(uri, _uri.getHost());
139 } finally {
140 System.setSecurityManager(original);
141 }
142 }
143
144 /***
145 * Tests the behaviour of setting {@link SocketRequestInfo#getBindAll} to
146 * <code>false</code> to restrict connections to a single address.
147 *
148 * @throws Exception for any error
149 */
150 public void testBindSingle() throws Exception {
151 String scheme = _uri.getScheme();
152 int port = _uri.getPort();
153
154
155
156 final String loopbackIP = "127.0.0.1";
157 if (InetAddress.getLocalHost().getHostAddress().equals(loopbackIP)) {
158 fail("Local host address must not be the same as "
159 + loopbackIP + " in order for this test case to run");
160
161 }
162 URI loopback = URIHelper.create(scheme, loopbackIP, port);
163 SocketRequestInfo acceptInfo = getSocketRequestInfo(loopback);
164 acceptInfo.setBindAll(false);
165
166
167 ManagedConnectionAcceptor acceptor
168 = createAcceptor(null, acceptInfo);
169 TestAcceptorEventListener listener = new TestAcceptorEventListener(
170 new TestInvocationHandler());
171 acceptor.accept(listener);
172
173
174 String host = InetAddress.getLocalHost().getHostName();
175 URI localhost = URIHelper.create(scheme, host, port);
176 SocketRequestInfo failInfo = getSocketRequestInfo(localhost);
177
178
179 try {
180 createConnection(null, failInfo);
181 fail("Expected connection to " + localhost + " to fail");
182 } catch (ResourceException exception) {
183
184 }
185
186
187 SocketRequestInfo info = getSocketRequestInfo(loopback);
188 ManagedConnection connection = null;
189 try {
190 connection = createConnection(null, info);
191 } catch (Exception exception) {
192 fail("Expected connections to " + loopback + " to succeed:" +
193 exception);
194 }
195
196
197 connection.destroy();
198
199
200
201
202 listener.destroy();
203
204 acceptor.close();
205 }
206
207 /***
208 * Tests connection matching when the alternative URI is used.
209 *
210 * @throws Exception for any error
211 */
212 public void testMatchManagedConnectionsWithAlternativeURI()
213 throws Exception {
214
215 SocketRequestInfo info = getSocketRequestInfo(_uri);
216 ManagedConnectionAcceptor acceptor = createAcceptor(null, info);
217 TestAcceptorEventListener listener = new TestAcceptorEventListener(
218 new TestInvocationHandler());
219 acceptor.accept(listener);
220
221
222 List connections = new ArrayList();
223 ManagedConnection connection = connection = createConnection(null, info);
224 connections.add(connection);
225
226
227 ManagedConnectionFactory factory = getManagedConnectionFactory();
228 ManagedConnection match = null;
229
230
231
232 match = factory.matchManagedConnections(connections, null, info);
233 assertEquals(connection, match);
234
235
236
237 URI failURI = getUnusedURI();
238 SocketRequestInfo altInfo = getSocketRequestInfo(failURI);
239 altInfo.setAlternativeHost(_uri.getHost());
240
241
242 SocketRequestInfo failInfo = getSocketRequestInfo(failURI);
243 match = factory.matchManagedConnections(connections, null, failInfo);
244 assertNull(match);
245
246
247 acceptor.close();
248 listener.destroy();
249 connection.destroy();
250 }
251
252 /***
253 * Returns connection request info suitable for creating a managed
254 * connection.
255 *
256 * @return connection request info for creating a managed connection
257 * @throws Exception for any error
258 */
259 protected ConnectionRequestInfo getManagedConnectionRequestInfo()
260 throws Exception {
261 return getSocketRequestInfo(_uri);
262 }
263
264 /***
265 * Returns connection request info suitable for creating a managed
266 * connection acceptor.
267 * <p/>
268 * This implementation returns that returned by {@link
269 * #getManagedConnectionRequestInfo()}.
270 *
271 * @return connection request info for creating a managed connection
272 * acceptor
273 * @throws Exception for any error
274 */
275 protected ConnectionRequestInfo getAcceptorConnectionRequestInfo()
276 throws Exception {
277 return getManagedConnectionRequestInfo();
278 }
279
280 /***
281 * Returns socket request info, for the specified URI, suitable for creating
282 * a managed connection and connection acceptor.
283 *
284 * @return socket request info for creating a managed connection
285 * @throws Exception for any error
286 */
287 protected SocketRequestInfo getSocketRequestInfo(URI uri)
288 throws Exception {
289 return new SocketRequestInfo(uri);
290 }
291
292 /***
293 * Returns a unused acceptor URI, for use by the {@link
294 * #testAlternativeURI()} test case.
295 * <p/>
296 * This implementation uses the acceptor URI supplied at construction,
297 * with an invalid host name
298 *
299 * @return an unused acceptor URI
300 * @throws Exception for any error
301 */
302 protected URI getUnusedURI() throws Exception {
303 URI result = new URI(_uri);
304 result.setHost("someinvalidhostname");
305 return result;
306 }
307
308 /***
309 * Verifies that clients can connect via the the alternative URI determined
310 * by {@link SocketRequestInfo#getAlternativeHost()}, if the primary URI
311 * cannot be reached.
312 *
313 * @param uri an URI with host that cannot be connected to
314 * @param alternativeHost the alternative host to connect to
315 * @throws Exception for any error
316 */
317 private void checkAlternativeURI(URI uri, String alternativeHost)
318 throws Exception {
319 URI successURI = new URI(uri);
320 successURI.setHost(alternativeHost);
321 SocketRequestInfo acceptInfo = getSocketRequestInfo(successURI);
322
323 SocketRequestInfo failInfo = getSocketRequestInfo(uri);
324
325
326 SocketRequestInfo successInfo = getSocketRequestInfo(uri);
327 successInfo.setAlternativeHost(successURI.getHost());
328
329
330
331 ManagedConnectionAcceptor acceptor = createAcceptor(null, acceptInfo);
332 TestAcceptorEventListener listener = new TestAcceptorEventListener(
333 new TestInvocationHandler());
334 acceptor.accept(listener);
335
336
337 try {
338 createConnection(null, failInfo);
339 fail("Expected connection to " + uri + " to fail");
340 } catch (ResourceException exception) {
341
342 }
343
344
345 ManagedConnection connection = null;
346 try {
347 connection = createConnection(null, successInfo);
348 } catch (Exception exception) {
349 fail("Expected connections to " + successURI + " to succeed:" +
350 exception);
351 }
352
353
354 connection.destroy();
355 acceptor.close();
356 }
357
358 }