2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
22
package org.jboss.test.remoting.transport.bisocket;
24
import java.lang.reflect.Field;
25
import java.net.InetAddress;
26
import java.util.HashMap;
29
import java.util.Timer;
30
import java.util.TimerTask;
32
import javax.management.MBeanServer;
34
import junit.framework.TestCase;
36
import org.apache.log4j.ConsoleAppender;
37
import org.apache.log4j.Level;
38
import org.apache.log4j.Logger;
39
import org.apache.log4j.PatternLayout;
40
import org.jboss.remoting.Client;
41
import org.jboss.remoting.InvocationRequest;
42
import org.jboss.remoting.InvokerLocator;
43
import org.jboss.remoting.ServerInvocationHandler;
44
import org.jboss.remoting.ServerInvoker;
45
import org.jboss.remoting.callback.Callback;
46
import org.jboss.remoting.callback.HandleCallbackException;
47
import org.jboss.remoting.callback.InvokerCallbackHandler;
48
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
49
import org.jboss.remoting.transport.Connector;
50
import org.jboss.remoting.transport.PortUtil;
51
import org.jboss.remoting.transport.bisocket.Bisocket;
52
import org.jboss.remoting.transport.bisocket.BisocketClientInvoker;
53
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;
54
import org.jboss.test.remoting.transport.bisocket.ServerTimerReuseTestCase.TestCallbackHandler;
55
import org.jboss.test.remoting.transport.bisocket.ServerTimerReuseTestCase.TestInvocationHandler;
59
* TimerReuseTestCase verifies that it is safe to add a callback BisocketClientInvoker
60
* after the static Timer used by the PingTimerTasks has shut down because all previous
61
* PingTimerTasks have ended.
65
* The phenomenon described in JBREM-748 seems to be platform dependent. It's not clear,
66
* for example, how long it takes for a Timer to shut down after all of its tasks have
67
* ended. Therefore, there are multiple test methods that wait varying amounts of
68
* time before installing a second InvokerCallbackHandler.
70
* @author <a href="ron.sigal@jboss.com">Ron Sigal</a>
71
* @version $Revision: 2737 $
73
* Copyright May 31, 2007
76
public class TimerReuseTestCase extends TestCase
78
public static int port;
80
private static Logger log = Logger.getLogger(TimerReuseTestCase.class);
81
private static boolean firstTime = true;
83
// remoting server connector
84
private Connector connector;
85
private InvokerLocator serverLocator;
86
private SampleInvocationHandler invocationHandler;
89
public void setUp() throws Exception
94
Logger.getLogger("org.jboss.remoting").setLevel(Level.INFO);
95
Logger.getLogger("org.jboss.test.remoting").setLevel(Level.INFO);
96
String pattern = "[%d{ABSOLUTE}] [%t] %5p (%F:%L) - %m%n";
97
PatternLayout layout = new PatternLayout(pattern);
98
ConsoleAppender consoleAppender = new ConsoleAppender(layout);
99
Logger.getRootLogger().addAppender(consoleAppender);
104
public void tearDown()
109
public void testTimerRestartImmdiately() throws Throwable
111
log.info("entering " + getName());
116
public void testTimerRestartAfter1Second() throws Throwable
118
log.info("entering " + getName());
119
doTestTimerReuse(1000);
123
public void testTimerRestartAfter5Seconds() throws Throwable
125
log.info("entering " + getName());
126
doTestTimerReuse(5000);
130
public void testTimerRestartAfter30Seconds() throws Throwable
132
log.info("entering " + getName());
133
doTestTimerReuse(30000);
136
public void testNewControlConnectionImmdiately() throws Throwable
138
log.info("entering " + getName());
139
doTestNewControlConnectionTimerReuse(1);
142
public void testNewControlConnectionAfter1Second() throws Throwable
144
log.info("entering " + getName());
145
doTestNewControlConnectionTimerReuse(1000);
149
public void testNewControlConnectionAfter5Seconds() throws Throwable
151
log.info("entering " + getName());
152
doTestNewControlConnectionTimerReuse(5000);
156
public void testNewControlConnectionAfter30Seconds() throws Throwable
158
log.info("entering " + getName());
159
doTestNewControlConnectionTimerReuse(30000);
163
public void doTestTimerReuse(int waitPeriod) throws Throwable
166
String host = InetAddress.getLocalHost().getHostAddress();
167
port = PortUtil.findFreePort(host);
168
String locatorURI = getTransport() + "://" + host + ":" + port;
169
serverLocator = new InvokerLocator(locatorURI);
170
log.info("Starting remoting server with locator uri of: " + locatorURI);
171
HashMap config = new HashMap();
172
config.put(InvokerLocator.FORCE_REMOTE, "true");
173
addExtraServerConfig(config);
174
connector = new Connector(serverLocator, config);
176
invocationHandler = new SampleInvocationHandler();
177
connector.addInvocationHandler("sample", invocationHandler);
181
HashMap clientConfig = new HashMap();
182
clientConfig.put(InvokerLocator.FORCE_REMOTE, "true");
183
addExtraClientConfig(clientConfig);
184
Client client = new Client(serverLocator, clientConfig);
186
log.info("Client is connected");
187
TestCallbackHandler callbackHandler = new TestCallbackHandler();
188
client.addListener(callbackHandler, new HashMap());
189
log.info("First callback handler is installed.");
191
// Reinstall callback handler. Test passes if no exception is thrown.
192
client.removeListener(callbackHandler);
193
Thread.sleep(waitPeriod);
194
client.addListener(callbackHandler, new HashMap());
195
log.info("Second callback handler is installed.");
197
client.removeListener(callbackHandler);
204
* Verifies that BisocketClientInvoker.replaceControlSocket() reuses static
205
* Timer, if possible.
207
public void doTestNewControlConnectionTimerReuse(int waitPeriod) throws Throwable
209
log.info("entering " + getName());
212
String host = InetAddress.getLocalHost().getHostAddress();
213
int port = PortUtil.findFreePort(host);
214
String locatorURI = getTransport() + "://" + host + ":" + port;
215
serverLocator = new InvokerLocator(locatorURI);
216
log.info("Starting remoting server with locator uri of: " + locatorURI);
217
HashMap config = new HashMap();
218
config.put(InvokerLocator.FORCE_REMOTE, "true");
219
addExtraServerConfig(config);
220
connector = new Connector(serverLocator, config);
222
invocationHandler = new SampleInvocationHandler();
223
connector.addInvocationHandler("sample", invocationHandler);
227
InvokerLocator clientLocator1 = new InvokerLocator(locatorURI);
228
HashMap clientConfig = new HashMap();
229
clientConfig.put(InvokerLocator.FORCE_REMOTE, "true");
230
addExtraClientConfig(clientConfig);
231
Client client = new Client(clientLocator1, clientConfig);
233
log.info("client is connected");
236
assertEquals("abc", client.invoke("abc"));
237
log.info("connection is good");
239
// Add callback handler.
240
TestCallbackHandler callbackHandler = new TestCallbackHandler();
241
HashMap metadata = new HashMap();
242
metadata.put(Bisocket.IS_CALLBACK_SERVER, "true");
243
client.addListener(callbackHandler, metadata);
245
// Stop PingTimerTask on server. This allows the possibility that the Timer
247
BisocketServerInvoker serverInvoker = (BisocketServerInvoker) connector.getServerInvoker();
248
Field field = ServerInvoker.class.getDeclaredField("callbackHandlers");
249
field.setAccessible(true);
250
Map callbackHandlers = (Map) field.get(serverInvoker);
251
assertEquals(1, callbackHandlers.size());
252
ServerInvokerCallbackHandler serverInvokerCallbackHandler;
253
serverInvokerCallbackHandler = (ServerInvokerCallbackHandler) callbackHandlers.values().iterator().next();
254
field = ServerInvokerCallbackHandler.class.getDeclaredField("callBackClient");
255
field.setAccessible(true);
256
Client callbackClient = (Client) field.get(serverInvokerCallbackHandler);
257
assertNotNull(callbackClient);
258
BisocketClientInvoker callbackClientInvoker = (BisocketClientInvoker) callbackClient.getInvoker();
259
field = BisocketClientInvoker.class.getDeclaredField("pingTimerTask");
260
field.setAccessible(true);
261
TimerTask pingTimerTask1 = (TimerTask) field.get(callbackClientInvoker);
262
BisocketClientInvoker ci = (BisocketClientInvoker) client.getInvoker();
263
assertNotNull(pingTimerTask1);
264
pingTimerTask1.cancel();
266
// Cause recreation of PingTimerTask on server. If call below to
267
// createControlConnection() doesn't throw an exception, then the test passes.
268
Thread.sleep(waitPeriod);
269
field = Client.class.getDeclaredField("callbackConnectors");
270
field.setAccessible(true);
271
Map callbackConnectors = (Map) field.get(client);
272
assertEquals(1, callbackConnectors.size());
273
Set connectors = (Set) callbackConnectors.values().iterator().next();
274
assertEquals(1, connectors.size());
275
Connector callbackConnector = (Connector) connectors.iterator().next();
276
BisocketServerInvoker callbackInvoker = (BisocketServerInvoker) callbackConnector.getServerInvoker();
277
field = BisocketServerInvoker.class.getDeclaredField("controlConnectionThreadMap");
278
field.setAccessible(true);
279
Map controlConnectionThreadMap = (Map) field.get(callbackInvoker);
280
assertEquals(1, controlConnectionThreadMap.size());
281
Thread controlConnectionThread = (Thread) controlConnectionThreadMap.values().iterator().next();
282
Class[] classes = BisocketServerInvoker.class.getDeclaredClasses();
283
Class ControlConnectionThreadClass = null;
285
for (int i = 0; i < classes.length; i++)
287
if (classes[i].toString().indexOf("ControlConnectionThread") != -1)
289
ControlConnectionThreadClass = classes[i];
294
assertNotNull(ControlConnectionThreadClass);
295
field = ControlConnectionThreadClass.getDeclaredField("listenerId");
296
field.setAccessible(true);
297
String listenerId = (String) field.get(controlConnectionThread);
298
assertNotNull(listenerId);
299
callbackInvoker.createControlConnection(listenerId, false);
302
// Get PingTimerTask and verify it has changed.
303
field = BisocketClientInvoker.class.getDeclaredField("pingTimerTask");
304
field.setAccessible(true);
305
TimerTask pingTimerTask2 = (TimerTask) field.get(callbackClientInvoker);
306
assertNotSame(pingTimerTask1, pingTimerTask2);
309
client.removeListener(callbackHandler);
312
log.info(getName() + " PASSES");
316
protected String getTransport()
322
protected void addExtraClientConfig(Map config) {}
323
protected void addExtraServerConfig(Map config) {}
326
static class SampleInvocationHandler implements ServerInvocationHandler
328
public void addListener(InvokerCallbackHandler callbackHandler)
332
callbackHandler.handleCallback(new Callback("callback"));
334
catch (HandleCallbackException e)
336
log.error("unable to send callback", e);
339
public Object invoke(final InvocationRequest invocation) throws Throwable
341
return invocation.getParameter();
343
public void removeListener(InvokerCallbackHandler callbackHandler) {}
344
public void setMBeanServer(MBeanServer server) {}
345
public void setInvoker(ServerInvoker invoker) {}
348
static class TestCallbackHandler implements InvokerCallbackHandler
351
public void handleCallback(Callback callback) throws HandleCallbackException
b'\\ No newline at end of file'