~ubuntu-branches/ubuntu/oneiric/libjboss-remoting-java/oneiric

« back to all changes in this revision

Viewing changes to src/org/jboss/remoting/transport/multiplex/MultiplexServerInvoker.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
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.
6
 
*
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.
11
 
*
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.
16
 
*
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.
21
 
*/
22
 
 
23
 
package org.jboss.remoting.transport.multiplex;
24
 
 
25
 
import java.io.EOFException;
26
 
import java.io.IOException;
27
 
import java.net.InetAddress;
28
 
import java.net.InetSocketAddress;
29
 
import java.net.ServerSocket;
30
 
import java.net.Socket;
31
 
import java.net.SocketException;
32
 
import java.net.SocketTimeoutException;
33
 
import java.util.ArrayList;
34
 
import java.util.Collection;
35
 
import java.util.Collections;
36
 
import java.util.HashMap;
37
 
import java.util.HashSet;
38
 
import java.util.Iterator;
39
 
import java.util.List;
40
 
import java.util.Map;
41
 
import java.util.Set;
42
 
 
43
 
import javax.net.ServerSocketFactory;
44
 
import javax.net.ssl.HandshakeCompletedEvent;
45
 
import javax.net.ssl.HandshakeCompletedListener;
46
 
 
47
 
import org.jboss.logging.Logger;
48
 
import org.jboss.remoting.Client;
49
 
import org.jboss.remoting.InvokerLocator;
50
 
import org.jboss.remoting.InvokerRegistry;
51
 
import org.jboss.remoting.ServerInvocationHandler;
52
 
import org.jboss.remoting.ServerInvoker;
53
 
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
54
 
import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
55
 
import org.jboss.remoting.transport.PortUtil;
56
 
import org.jboss.remoting.transport.multiplex.utility.AddressPair;
57
 
import org.jboss.remoting.transport.socket.SocketServerInvoker;
58
 
import org.jboss.remoting.util.socket.HandshakeRepeater;
59
 
 
60
 
 
61
 
/**
62
 
 * <code>MultiplexServerInvoker</code> is the server side of the Multiplex transport.
63
 
 * For more information, see Remoting documentation on labs.jboss.org.
64
 
 * 
65
 
 * @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
66
 
 * @author <a href="mailto:r.sigal@computer.org">Ron Sigal</a>
67
 
 * 
68
 
 * @deprecated As of release 2.4.0 the multiplex transport will no longer be actively supported.
69
 
 */
70
 
public class MultiplexServerInvoker extends SocketServerInvoker
71
 
implements Runnable, VirtualSocket.DisconnectListener
72
 
{
73
 
   protected static final Logger log = Logger.getLogger(MultiplexServerInvoker.class);
74
 
   private static boolean trace = log.isTraceEnabled();
75
 
   
76
 
   private static Map socketGroupMap = new HashMap();
77
 
   private static Map addressPairMap = new HashMap();
78
 
   private static HandshakeCompletedEvent handshakeCompletedEvent;
79
 
 
80
 
   private boolean isVirtual = false;
81
 
   private Map virtualServerInvokers;
82
 
   private Socket connectPrimingSocket;
83
 
   private SocketGroupInfo socketGroupInfo;
84
 
   private AddressPair addressPair;
85
 
   private String bindHost;
86
 
   private int bindPort;
87
 
   private int originalBindPort;
88
 
   private InetAddress bindAddress;
89
 
   private InetSocketAddress connectSocketAddress;
90
 
   private boolean readyToStart = true; 
91
 
   private boolean needsSocketGroupConfiguration = true;
92
 
   private boolean cleanedUp;
93
 
   private boolean hasMaster;
94
 
   private int errorCount;
95
 
   
96
 
   private ServerSocket serverSocket;
97
 
   
98
 
   /////////////////////////////////////////////////////////////////////////////////////
99
 
   //                    configurable Multiplex parameters                            //
100
 
   /////////////////////////////////////////////////////////////////////////////////////
101
 
   /*
102
 
    * The following parameters may be set in any of four ways:
103
 
    * 
104
 
    * 1. They may be appended to an <code>InvokerLocator</code> passed to a
105
 
    *    <code>Connector</code> constructor.
106
 
    * 2. They may be included in a configuration <code>Map</code> passed to a
107
 
    *    <code>Connector</code> constructor.
108
 
    * 3. They may be described in a <config> XML element passed to
109
 
    *    <code>Connector.setConfiguration()</code>.
110
 
    * 4. In some cases, a <code>MultiplexServerInvoker</code> setter methods may be invoked.
111
 
    * 
112
 
    * Of those of the following parameters destined for <code>MultiplexServerInvoker</code>,
113
 
    * there are two categories.
114
 
    * 
115
 
    * 1. <code>serverMultiplexId</code>, <code>multiplexConnectHost</code>, and
116
 
    *    <code>multiplexConnectPort</code> are used to
117
 
    *    match up <code>MultiplexClientInvoker</code>s and virtual
118
 
    *    <code>MultiplexServerInvokers</code> so that
119
 
    *    they share an underlying socket connection.  Depending on the way in which
120
 
    *    the information is provided (see Remoting documentation), the connection may
121
 
    *    be created any time during or after the call to <code>Connector.create()</code>. Note,
122
 
    *    however, that if a callback <code>MultiplexServerInvoker</code> is created with just a 
123
 
    *    <code>serverMultiplexId</code> parameter (server rule 3 in the Remoting documentation),
124
 
    *    then calling <code>setMultiplexConnectHost()</code> and
125
 
    *    <code>setMultiplexConnectPort()</code> will
126
 
    *    not trigger the creation of a connection.  Moreover, when a <code>Client</code> comes
127
 
    *    along, the connect information supplied by the <code>Client</code> will be used, so there
128
 
    *    is no point to having setter methods for these parameters.
129
 
    *    
130
 
    * 2. <code>maxAcceptErrors</code> is used in the
131
 
    *    <code>MultiplexServerInvoker</code> <code>accept()</code> loop, and it
132
 
    *    may be changed at any time by calling <code>setMaxAcceptErrors()</code>. 
133
 
    * 
134
 
    * Those of the following parameters which are destined for the <code>MultiplexingManager</code>,
135
 
    * <code>InputMultiplexor</code>, and <code>OutputMultiplexor</code> classes are
136
 
    * passed to them by way of a configuration <code>Map</code> passed to
137
 
    * <code>VirtualSocket</code> and <code>VirtualServerSocket</code> constructors.
138
 
    * 
139
 
    * A <code>VirtualServerSocket</code> is created when a server side master
140
 
    * <code>MultiplexServerInvoker</code>
141
 
    * accepts a connection request generated by the creation of a priming socket on a client.  
142
 
    * Since this can happen any time after <code>Connector.start()</code> is created, the values of
143
 
    * these parameters can be changed by calling their respective setter methods any
144
 
    * time before <code>Connector.start()</code> is called.
145
 
    * 
146
 
    * A <code>VirtualSocket</code> is created when a client side
147
 
    * <code>MultiplexClientInvoker</code> or callback
148
 
    * <code>MultiplexServerInvoker</code> opens a priming socket, and this happens when
149
 
    * <code>Connector.create()</code> is called.  Therefore, the values of these parameters can be 
150
 
    * changed by calling their respective setter methods any time before
151
 
    * <code>Connector.create()</code> is called.
152
 
    */
153
 
   // MultiplexingManager:
154
 
   private int staticThreadsMonitorPeriod;
155
 
   private int shutdownRequestTimeout;
156
 
   private int shutdownRefusalsMaximum;
157
 
   private int shutdownMonitorPeriod;
158
 
   
159
 
   // InputMultiplexor:
160
 
   private int inputBufferSize;
161
 
   private int inputMaxErrors;
162
 
 
163
 
   // OutputMultiplexor: 
164
 
   private int outputMessagePoolSize;
165
 
   private int outputMessageSize;
166
 
   private int outputMaxChunkSize;
167
 
   private int outputMaxTimeSlice;
168
 
   private int outputMaxDataSlice;
169
 
 
170
 
   // MultiplexServerInvoker
171
 
   private int     maxAcceptErrors;
172
 
   private String  serverMultiplexId;
173
 
   private String  multiplexConnectHost;
174
 
   private int     multiplexConnectPort;
175
 
   private boolean multiplexConnectPortIsSet;  // to check for missing configuration information
176
 
 
177
 
   public static Map getAddressPairMap()
178
 
   {
179
 
      return addressPairMap;
180
 
   }
181
 
   
182
 
   public static Map getSocketGroupMap()
183
 
   {
184
 
      return socketGroupMap;
185
 
   }
186
 
   
187
 
   
188
 
/**
189
 
 * 
190
 
 * Create a new <code>MultiplexServerInvoker</code>.
191
 
 * 
192
 
 * @param locator
193
 
 */
194
 
   public MultiplexServerInvoker(InvokerLocator locator)
195
 
   {
196
 
      super(locator);
197
 
//      virtualServerInvokers = Collections.synchronizedMap(new HashMap());
198
 
      virtualServerInvokers = new HashMap();
199
 
   }
200
 
 
201
 
   
202
 
/**
203
 
 * Create a new <code>MultiplexServerInvoker</code>.
204
 
 */
205
 
   public MultiplexServerInvoker(InvokerLocator locator, Map configuration)
206
 
   {
207
 
      super(locator, configuration);
208
 
//      virtualServerInvokers = Collections.synchronizedMap(new HashMap());
209
 
      virtualServerInvokers = new HashMap();
210
 
   }
211
 
 
212
 
 
213
 
   /**
214
 
    * Create a new <code>MultiplexServerInvoker</code>.
215
 
    */
216
 
   protected MultiplexServerInvoker(InvokerLocator locator, Map configuration,
217
 
                                    List serverSockets, Socket socket,
218
 
                                    Map virtualServerInvokers)
219
 
   {
220
 
      super(locator, configuration);
221
 
      this.serverSockets = serverSockets;
222
 
      serverSocket = (ServerSocket) serverSockets.get(0);
223
 
      connectPrimingSocket = socket;
224
 
      this.virtualServerInvokers = virtualServerInvokers;
225
 
      isVirtual = true;
226
 
      needsSocketGroupConfiguration = false;
227
 
      ((VirtualSocket) connectPrimingSocket).addDisconnectListener(this);
228
 
      
229
 
      try
230
 
      {
231
 
         getParameters();
232
 
      }
233
 
      catch (Exception e)
234
 
      {
235
 
         log.error(e);
236
 
      }
237
 
   }
238
 
   
239
 
 
240
 
   /**
241
 
    * Each implementation of the remote client invoker should have
242
 
    * a default data type that is uses in the case it is not specified
243
 
    * in the invoker locator uri.
244
 
    */
245
 
   protected String getDefaultDataType()
246
 
   {
247
 
      return SerializableMarshaller.DATATYPE;
248
 
   }
249
 
 
250
 
   //TODO: -TME Need to check on synchronization after initial hook up
251
 
   public void start() throws IOException
252
 
   { 
253
 
      if (readyToStart)
254
 
         finishStart();
255
 
   }
256
 
   
257
 
   
258
 
   public void run()
259
 
   {
260
 
      if(trace)
261
 
      {
262
 
         log.trace("Started execution of method run");
263
 
      }
264
 
      ServerSocketRefresh thread=new ServerSocketRefresh();
265
 
      thread.setDaemon(true);
266
 
      thread.start();
267
 
      
268
 
      try
269
 
      {
270
 
         while(running)
271
 
         {
272
 
            try
273
 
            {
274
 
               if(trace)
275
 
               {
276
 
                  log.trace("Socket is going to be accepted");
277
 
               }
278
 
               thread.release(); //goes on if serversocket refresh is completed
279
 
               Socket socket = serverSocket.accept();
280
 
               if(trace)
281
 
               {
282
 
                  log.trace("Accepted: " + socket);
283
 
               }
284
 
               processInvocation(socket);
285
 
            }
286
 
            catch (SocketException e)
287
 
            {
288
 
               if ("Socket is closed".equals(e.getMessage())
289
 
                     || "Socket closed".equals(e.getMessage()))
290
 
               {
291
 
                  log.info("socket is closed: stopping thread");
292
 
                  // If this invoker was started by a Connector, let the Connector stop it.
293
 
                  if (hasMaster) 
294
 
                     stop();
295
 
                  return;
296
 
               }
297
 
               else if (++errorCount > maxAcceptErrors)
298
 
               {
299
 
                  log.error("maximum accept errors exceeded: stopping thread");
300
 
                  // If this invoker was started by a Connector, let the Connector stop it.
301
 
                  if (hasMaster)
302
 
                     stop();
303
 
                  return;
304
 
               }
305
 
               else
306
 
               {
307
 
                  log.info(e);
308
 
               }
309
 
            }
310
 
            catch (SocketTimeoutException e)
311
 
            {
312
 
               if(running)
313
 
               {
314
 
                  // If remote MultiplexClientInvoker and optional callback MultiplexServerInvoker
315
 
                  // have shutdown, it's safe to stop.
316
 
                  if (connectPrimingSocket != null && ((VirtualSocket)connectPrimingSocket).hasReceivedDisconnectMessage())
317
 
                  {
318
 
                     log.info("Client has closed: stopping thread");
319
 
                     // If this invoker was started by a Connector, let the Connector stop it.
320
 
                     if (hasMaster)
321
 
                        stop();
322
 
                     return;
323
 
                  }
324
 
               }
325
 
            }
326
 
            catch (javax.net.ssl.SSLHandshakeException e)
327
 
            {
328
 
               log.info("SSLHandshakeException", e);
329
 
            }
330
 
            catch(Throwable ex)
331
 
            {
332
 
               if(running)
333
 
               {
334
 
                  log.error("Failed to accept socket connection", ex);
335
 
                  if (++errorCount > maxAcceptErrors)
336
 
                  {
337
 
                     log.error("maximum accept errors exceeded: stopping");
338
 
                     // If this invoker was started by a Connector, let the Connector stop it.
339
 
                     if (hasMaster)
340
 
                        stop();
341
 
                     return;
342
 
                  }
343
 
               }
344
 
               else
345
 
               {
346
 
                  log.info(ex);
347
 
               }
348
 
            }
349
 
         }
350
 
      }
351
 
      finally
352
 
      {
353
 
         thread.interrupt();
354
 
      }
355
 
   }
356
 
   
357
 
   
358
 
   public boolean isSafeToShutdown()
359
 
   {
360
 
      return (connectPrimingSocket == null || ((VirtualSocket) connectPrimingSocket).hasReceivedDisconnectMessage());
361
 
   }
362
 
   
363
 
   
364
 
   public void notifyDisconnected(VirtualSocket virtualSocket)
365
 
   {
366
 
      if (virtualSocket != connectPrimingSocket)
367
 
      {
368
 
         log.error("notified about disconnection of unrecognized virtual socket");
369
 
         return;
370
 
      }
371
 
      
372
 
      log.debug("remote peer socket has closed: stopping");
373
 
      stop();
374
 
   }
375
 
   
376
 
   
377
 
   public void stop()
378
 
   {
379
 
      // If running == false, super.stop() will not call cleanup().
380
 
      // However, MultiplexServerInvoker could have stuff to clean up
381
 
      // (socket group information) even if it didn't start.
382
 
      if (!running)
383
 
         cleanup();
384
 
    
385
 
      super.stop();
386
 
   }
387
 
   
388
 
   
389
 
   public String toString()
390
 
   {
391
 
      if (isVirtual)
392
 
      {
393
 
         VirtualServerSocket vss = (VirtualServerSocket) serverSocket;
394
 
         if (vss != null)
395
 
            return "MultiplexServerInvoker[virtual:"
396
 
               + vss.getInetAddress() + ":" + vss.getLocalPort()
397
 
               + "->"
398
 
               + vss.getRemoteAddress() + ":" + vss.getRemotePort()
399
 
               + "]";
400
 
         else
401
 
            return "MultiplexServerInvoker[virtual]";
402
 
      }
403
 
      else
404
 
         if (serverSocket != null)
405
 
            return "MultiplexServerInvoker[master:"
406
 
               + serverSocket.getInetAddress() + ":" + serverSocket.getLocalPort()
407
 
               + "]";
408
 
         else
409
 
            return "MultiplexServerInvoker[master]";
410
 
   }
411
 
   
412
 
   
413
 
   protected void setup() throws Exception
414
 
   {
415
 
      originalBindPort = this.getLocator().getPort();
416
 
      super.setup();
417
 
      getParameters();
418
 
      setBindingInfo();
419
 
      
420
 
//      socketFactory = createSocketFactory(configuration);
421
 
//      if (socketFactory != null)
422
 
//         configuration.put(Multiplex.SOCKET_FACTORY, socketFactory);
423
 
      
424
 
      if (!configuration.isEmpty())
425
 
      {
426
 
         if (needsSocketGroupConfiguration)
427
 
         {
428
 
            try
429
 
            {
430
 
               configureSocketGroupParameters(configuration);
431
 
            }
432
 
            catch (IOException e)
433
 
            {
434
 
               log.error("error configuring socket group parameters", e);
435
 
               cleanup();
436
 
               throw e;
437
 
            }
438
 
         }
439
 
      }
440
 
   }
441
 
   
442
 
   
443
 
   /**
444
 
    * Finishes start up process when suitable bind and connect information is available.
445
 
    * For more information, see the Multiplex subsystem documentation at labs.jboss.org.
446
 
    */
447
 
   protected void finishStart() throws IOException
448
 
   {
449
 
      log.debug("entering finishStart()");
450
 
      
451
 
      if (isStarted())
452
 
         return;
453
 
      
454
 
      if (socketGroupInfo != null && connectSocketAddress == null)
455
 
      {
456
 
         InetAddress connectAddress = socketGroupInfo.getConnectAddress();
457
 
         int connectPort = socketGroupInfo.getConnectPort();
458
 
         connectSocketAddress = new InetSocketAddress(connectAddress, connectPort);
459
 
      }
460
 
      
461
 
      if (socketGroupInfo != null && addressPair == null)
462
 
      {
463
 
         String connectHost = socketGroupInfo.getConnectAddress().getHostName();
464
 
         int connectPort = socketGroupInfo.getConnectPort();
465
 
         addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
466
 
      }
467
 
      
468
 
      try
469
 
      {
470
 
         super.start();
471
 
      }
472
 
      catch(IOException e)
473
 
      {
474
 
         log.error("Error starting MultiplexServerInvoker.", e);
475
 
         cleanup();
476
 
      }
477
 
      
478
 
      if (running)
479
 
         log.debug("MultiplexServerInvoker started.");
480
 
     }
481
 
   
482
 
   
483
 
   
484
 
   /**
485
 
    * Called by MultiplexClientInvoker.createSocket() when it finds connection is
486
 
    * broken and binds virtual socket group to new bind port.
487
 
    * <p>
488
 
    * @param bindPort
489
 
    */
490
 
   protected void resetLocator(int bindPort)
491
 
   {
492
 
      this.bindPort = bindPort;
493
 
      InvokerLocator newLocator = new InvokerLocator(locator.getProtocol(),
494
 
                                                     locator.getHost(),
495
 
                                                     bindPort,
496
 
                                                     locator.getPath(),
497
 
                                                     locator.getParameters());
498
 
      
499
 
      InvokerRegistry.updateServerInvokerLocator(locator, newLocator);
500
 
      locator = newLocator;
501
 
   }
502
 
   
503
 
   
504
 
   protected void configureSocketGroupParameters(Map parameters) throws IOException
505
 
   {
506
 
      log.debug("entering configureSocketGroupParameters()");
507
 
      log.debug(locator);
508
 
 
509
 
      synchronized (SocketGroupInfo.class)
510
 
      {
511
 
         if (serverMultiplexId != null)
512
 
         {
513
 
            socketGroupInfo = (SocketGroupInfo) getSocketGroupMap().get(serverMultiplexId);
514
 
            if (socketGroupInfo != null)
515
 
            {
516
 
               rule1();
517
 
               return;
518
 
            }
519
 
         }
520
 
         
521
 
         if (multiplexConnectHost != null && !this.multiplexConnectPortIsSet)
522
 
            throw new IOException("multiplexConnectHost != null and multiplexConnectPort is not set");
523
 
         
524
 
         if (multiplexConnectHost == null && this.multiplexConnectPortIsSet)
525
 
            throw new IOException("multiplexConnectHost == null and multiplexConnectPort is set");
526
 
         
527
 
         // server rule 2.
528
 
         if (multiplexConnectHost != null)
529
 
         {
530
 
            rule2(multiplexConnectHost, multiplexConnectPort);
531
 
            return;
532
 
         }
533
 
         
534
 
         // server rule 3.
535
 
         if (serverMultiplexId != null)
536
 
         {
537
 
            rule3();
538
 
            return;
539
 
         }
540
 
         
541
 
         // server rule 4.
542
 
         rule4();
543
 
      }
544
 
   }
545
 
   
546
 
   
547
 
   protected static void createPrimingSocket(SocketGroupInfo socketGroupInfo,
548
 
                                             String connectHost, int connectPort,
549
 
                                             Map configuration, int timeout)
550
 
   throws IOException
551
 
   {
552
 
      createPrimingSocket(socketGroupInfo, connectHost, connectPort, null, -1, configuration, timeout);
553
 
   }
554
 
   
555
 
   
556
 
   protected static void createPrimingSocket(SocketGroupInfo socketGroupInfo,
557
 
                                             String connectHost, int connectPort,
558
 
                                             InetAddress bindAddress, int bindPort,
559
 
                                             Map configuration, int timeout)
560
 
   throws IOException
561
 
   {  
562
 
      log.debug("entering createPrimingSocket()");
563
 
      
564
 
      boolean needed = true;
565
 
      InetSocketAddress csa = new InetSocketAddress(connectHost, connectPort);
566
 
      InetSocketAddress bsa = null;
567
 
      
568
 
      if (bindAddress != null)
569
 
      {
570
 
         bsa = new InetSocketAddress(bindAddress, bindPort);
571
 
         needed = !MultiplexingManager.checkForShareableManagerByAddressPair(bsa, csa);
572
 
      }
573
 
      else
574
 
      {
575
 
         needed = !MultiplexingManager.checkForShareableManager(csa);
576
 
      }
577
 
      
578
 
      if (socketGroupInfo != null)
579
 
         socketGroupInfo.setPrimingSocketNeeded(needed);
580
 
      
581
 
      if (!needed)
582
 
      {
583
 
         log.debug("priming socket is not necessary");
584
 
         return;
585
 
      }
586
 
      
587
 
      // If the configuration Map has an SSL HandshakeCompletedListener, we register to
588
 
      // receive the HandshakeCompletedEvent with a HandshakeRepeater and, if the event
589
 
      // arrives within 60 seconds, we pass it on to the configured listener.  Otherwise,
590
 
      // HandshakeRepeater.waitForHandshake() will throw an SSLException. 
591
 
      Object obj = configuration.get(Client.HANDSHAKE_COMPLETED_LISTENER);
592
 
      HandshakeCompletedListener externalListener = null;
593
 
      HandshakeRepeater internalListener = null;
594
 
      if (obj != null && obj instanceof HandshakeCompletedListener)
595
 
      {
596
 
         externalListener = (HandshakeCompletedListener) obj;
597
 
         internalListener = new HandshakeRepeater(new InternalHandshakeListener());
598
 
         configuration.put(Multiplex.SSL_HANDSHAKE_LISTENER, internalListener);
599
 
      }
600
 
      
601
 
      VirtualSocket socket = new VirtualSocket(configuration);
602
 
      
603
 
      if (bindAddress != null)
604
 
         socket.connect(csa, bsa, timeout);
605
 
      else
606
 
         socket.connect(csa, timeout);
607
 
      
608
 
      MultiplexingManager manager = socket.getManager();
609
 
      
610
 
      if (externalListener != null)
611
 
      {
612
 
         if (manager.getHandshakeCompletedEvent() != null)
613
 
         {
614
 
            externalListener.handshakeCompleted(manager.getHandshakeCompletedEvent());
615
 
         }
616
 
         else
617
 
         {
618
 
            internalListener.waitForHandshake();
619
 
            externalListener.handshakeCompleted(handshakeCompletedEvent);
620
 
         }
621
 
      }
622
 
      
623
 
      if (!manager.waitForRemoteServerSocketRegistered())
624
 
         throw new IOException("error waiting for remote server socket to be registered");
625
 
      
626
 
      if (socketGroupInfo != null)
627
 
         socketGroupInfo.setPrimingSocket(socket);
628
 
      
629
 
      log.debug("created priming socket: " + socket.getLocalSocketId());
630
 
   }
631
 
   
632
 
 
633
 
   protected String getThreadName(int i)
634
 
   {
635
 
      String virtualTag = isVirtual ? "v" : "m";
636
 
      return "MultiplexServerInvoker#" + i + virtualTag + "-" + serverSocket.toString();
637
 
   }
638
 
 
639
 
 
640
 
   protected void processInvocation(Socket socket) throws Exception
641
 
   {
642
 
      if (isVirtual)
643
 
         super.processInvocation(socket);
644
 
      else
645
 
      {
646
 
         log.debug("creating VSS");
647
 
         ServerSocket ss = new VirtualServerSocket((VirtualSocket) socket, configuration);
648
 
         ss.setSoTimeout(getTimeout());
649
 
         List serverSockets = new ArrayList();
650
 
         serverSockets.add(ss);
651
 
         MultiplexServerInvoker si = new MultiplexServerInvoker(locator, configuration, serverSockets, socket, virtualServerInvokers);
652
 
         si.hasMaster = true;
653
 
         si.clientCallbackListener = clientCallbackListener;
654
 
         si.handlers = handlers;
655
 
         si.setMBeanServer(this.getMBeanServer());
656
 
         si.setServerSocketFactory(this.getServerSocketFactory());
657
 
         si.setSocketFactory(this.socketFactory);
658
 
         synchronized (virtualServerInvokers)
659
 
         {
660
 
            virtualServerInvokers.put(socket.getRemoteSocketAddress(), si);
661
 
         }
662
 
         si.connectionNotifier = connectionNotifier;
663
 
         si.create();
664
 
         si.start();
665
 
         log.debug("created virtual MultiplexServerInvoker: " + si);
666
 
      }
667
 
   }
668
 
 
669
 
  
670
 
   protected void cleanup()
671
 
   {  
672
 
      // If running == false, SocketServerInvoker doesn't want to call cleanup().
673
 
      if (running)
674
 
      {
675
 
         super.cleanup();
676
 
      }
677
 
      
678
 
      // If the Finalizer thread gets here after clean up has occurred, return.
679
 
      if (cleanedUp)
680
 
         return;
681
 
      
682
 
      cleanedUp = true;
683
 
      
684
 
      if (isVirtual)
685
 
      {
686
 
         if (connectPrimingSocket != null)
687
 
         {
688
 
            log.debug("connect priming != null");
689
 
            // If !virtualServerInvokers.containsKey(connectPrimingSocket.getRemoteSocketAddress()),
690
 
            // the master MultiplexServerInvoker might be iterating through virtualServerInvokers
691
 
            // and shutting them down.  This test avoids a NullPointerException.
692
 
            Object key = connectPrimingSocket.getRemoteSocketAddress();
693
 
            synchronized (virtualServerInvokers)
694
 
            {
695
 
               if (virtualServerInvokers.containsKey(key))
696
 
                  virtualServerInvokers.remove(key);
697
 
            }
698
 
            
699
 
            try
700
 
            {
701
 
               log.debug("MultiplexServerInvoker: closing connect priming socket");
702
 
               connectPrimingSocket.close();
703
 
            }
704
 
            catch (IOException e)
705
 
            {
706
 
               log.error("Error closing connect priming socket during cleanup upon stopping", e);
707
 
            }
708
 
         }
709
 
         else
710
 
         {
711
 
            log.debug("connect priming socket == null");
712
 
         }
713
 
         
714
 
         // Remove all callback handlers (if any ServerInvocationHandlers are registered).
715
 
         Iterator it = handlers.values().iterator();
716
 
         
717
 
         if (it.hasNext())
718
 
         {
719
 
            log.debug("removing callback handlers");
720
 
            ServerInvocationHandler defaultHandler = (ServerInvocationHandler) it.next();
721
 
            ServerInvocationHandler handler = null;
722
 
            ServerInvokerCallbackHandler callbackHandler = null;
723
 
            it = callbackHandlers.values().iterator();
724
 
            
725
 
            while (it.hasNext())
726
 
            {
727
 
               callbackHandler = (ServerInvokerCallbackHandler) it.next();
728
 
               String subsystem = callbackHandler.getSubsystem();
729
 
               
730
 
               if (subsystem == null)
731
 
                  handler = defaultHandler;
732
 
               else
733
 
                  handler = (ServerInvocationHandler) handlers.get(subsystem.toUpperCase());
734
 
               
735
 
               handler.removeListener(callbackHandler);
736
 
            }
737
 
         }
738
 
      }
739
 
      else
740
 
      {
741
 
//         Iterator it = virtualServerInvokers.values().iterator();
742
 
         Iterator it = null;
743
 
         synchronized (virtualServerInvokers)
744
 
         {
745
 
            it = new HashMap(virtualServerInvokers).values().iterator();
746
 
         }
747
 
         
748
 
         while (it.hasNext())
749
 
         {
750
 
            ServerInvoker serverInvoker = ((ServerInvoker) it.next());
751
 
            it.remove();
752
 
            serverInvoker.stop();
753
 
         }
754
 
      }
755
 
      
756
 
      if (socketGroupInfo != null)
757
 
      {
758
 
         synchronized (MultiplexServerInvoker.SocketGroupInfo.class)
759
 
         {
760
 
            socketGroupInfo.removeServerInvoker(this);
761
 
            VirtualSocket ps = null;
762
 
            
763
 
            if (socketGroupInfo.getClientInvokers().isEmpty())
764
 
            {
765
 
               log.debug("invoker group shutting down: " + socketGroupInfo.getSocketGroupId());
766
 
               
767
 
               if ((ps = socketGroupInfo.getPrimingSocket()) != null)
768
 
               {
769
 
                  // When the remote virtual MultiplexServerInvoker learns that the
770
 
                  // priming socket has closed, it will close its VirtualServerSocket,
771
 
                  // rendering unshareable the MultiplexingManager that underlies this
772
 
                  // socket group.  We mark it as unshareable immediately so that it will
773
 
                  // not be reused by any other socket group.
774
 
                  ps.getManager().unregisterShareable();
775
 
                  
776
 
                  log.debug("MultiplexServerInvoker: closing bind priming socket");
777
 
                  try
778
 
                  {
779
 
                     ps.close();
780
 
                  }
781
 
                  catch (IOException e)
782
 
                  {
783
 
                     log.error("Error closing bind priming socket during cleanup upon stopping", e);
784
 
                  }
785
 
               }
786
 
               
787
 
               serverMultiplexId = socketGroupInfo.getSocketGroupId();
788
 
               log.debug("serverMultiplexId: " + serverMultiplexId);
789
 
               if (serverMultiplexId != null)
790
 
               {
791
 
                  getSocketGroupMap().remove(serverMultiplexId);
792
 
                  log.debug("removed serverMultiplexId: " + serverMultiplexId);
793
 
                  log.debug("socketGroupInfo: " + getSocketGroupMap().get(serverMultiplexId));
794
 
               }
795
 
               
796
 
               // addressPair is set in finishStart().
797
 
               if (addressPair != null)
798
 
               {
799
 
                  getAddressPairMap().remove(addressPair);
800
 
               }
801
 
            }
802
 
         }
803
 
      }
804
 
   }
805
 
 
806
 
 
807
 
/**
808
 
 * In creating the server socket, <code>createServerSocket()</code> determines whether multiplexing
809
 
 * will be supported by this <code>ServerInvoker</code>. The determination is made according to the
810
 
 * presence or absence of certain parameters in the <code>ServerInvoker</code>'s locator.  In particular,
811
 
 * a <code>VirtualServerSocket</code>, which supports multiplexing, needs to connect to a
812
 
 * remote <code>MasterServerSocket</code> before it can begin to accept connection requests.
813
 
 * In order to know which <code>MasterServerSocket</code> to connect to,
814
 
 * it looks for parameters "connectHost" and "connectPort" in the locator.  The presence of these parameters
815
 
 * indicates that a <code>VirtualServerSocket</code> should be created, and their absence indicates that a
816
 
 * <code>MasterServerSocket</code>, which does not support multiplexing, should be created.
817
 
 *
818
 
 * @param bindPort
819
 
 * @param backlog
820
 
 * @param bindAddress
821
 
 * @return
822
 
 * @throws IOException
823
 
 */
824
 
   protected ServerSocket createServerSocket(int bindPort, int backlog, InetAddress bindAddress) throws IOException
825
 
//   private ServerSocket createServerSocket() throws IOException
826
 
   {
827
 
      // The following commented code represents an attempt to make an automatic determination as to whether
828
 
      // a VirtualServerSocket should be created.  The idea is to see if a ClientInvoker already
829
 
      // exists on the local port to which the new server socket wants to bind.  The existence of such a
830
 
      // ClientInvoker would indicate that multiplexing is desired.  However, it appears that a ClientInvoker
831
 
      // has no control over which local port(s) it uses.
832
 
 
833
 
      //    if (InvokerRegistry.isClientInvokerRegistered(getLocator()))
834
 
      //    {
835
 
      //       try
836
 
      //       {
837
 
      //          Invoker clientInvoker = InvokerRegistry.createClientInvoker(getLocator());
838
 
      //          InvokerLocator connectLocator = clientInvoker.getLocator();
839
 
      //          InetSocketAddress connectSocketAddress = new InetSocketAddress(connectLocator.getHost(), connectLocator.getPort());
840
 
      //          InetSocketAddress bindSocketAddress = new InetSocketAddress(bindAddress, serverBindPort);
841
 
      //          svrSocket = new VirtualServerSocket(connectSocketAddress, bindSocketAddress);
842
 
      //       }
843
 
      //       catch (Exception e)
844
 
      //       {
845
 
      //          throw new IOException(e.getMessage());
846
 
      //       }
847
 
      //    }
848
 
      
849
 
      // If this is a virtual MultiplexServerInvoker created by a master MultiplexServerInvoker,
850
 
      // then the server socket has already been created.
851
 
      if (serverSocket != null)
852
 
         return serverSocket;
853
 
      
854
 
      ServerSocket svrSocket = null;
855
 
 
856
 
      if (isVirtual)
857
 
      {
858
 
         InetSocketAddress bindSocketAddress = new InetSocketAddress(bindAddress, this.bindPort);
859
 
         svrSocket = new VirtualServerSocket(connectSocketAddress, bindSocketAddress, getTimeout(), configuration);
860
 
         svrSocket.setSoTimeout(getTimeout());
861
 
         
862
 
         if (socketGroupInfo != null)
863
 
            socketGroupInfo.setPrimingSocketNeeded(false);
864
 
      }
865
 
      else
866
 
      {
867
 
//         svrSocket = new MasterServerSocket(getServerSocketFactory(), bindPort, backlog, bindAddress);
868
 
         ServerSocketFactory ssf = getServerSocketFactory();
869
 
         if (ssf != null && !ssf.getClass().equals(ServerSocketFactory.getDefault().getClass()))
870
 
         {
871
 
            configuration.put(Multiplex.SERVER_SOCKET_FACTORY, ssf);
872
 
         }
873
 
         svrSocket = new MasterServerSocket(bindPort, backlog, bindAddress, configuration);
874
 
         svrSocket.setSoTimeout(getTimeout());
875
 
      }
876
 
 
877
 
      log.debug("Created " + svrSocket.getClass() + ": " + svrSocket);
878
 
      return svrSocket;
879
 
   }
880
 
 
881
 
 
882
 
   protected void rule1() throws IOException
883
 
   {
884
 
      log.debug("server rule 1");
885
 
      
886
 
      // If we get here, it's because a MultiplexClientInvoker created a SocketGroupInfo with matching
887
 
      // group id.  We want to make sure that it didn't get a bind address or bind port different
888
 
      // than the ones passed in through the parameters map.
889
 
      InetAddress socketGroupBindAddress = socketGroupInfo.getBindAddress();
890
 
      int socketGroupBindPort = socketGroupInfo.getBindPort();
891
 
      
892
 
      if (socketGroupBindAddress != null && !socketGroupBindAddress.equals(bindAddress))
893
 
      {
894
 
         String message = "socket group bind address (" + socketGroupBindAddress + 
895
 
                          ") does not match bind address (" + bindAddress + ")";
896
 
         log.error(message);
897
 
         socketGroupInfo = null;  // We don't belong to this group.
898
 
         throw new IOException(message);
899
 
      }
900
 
      
901
 
      if (socketGroupBindPort > 0 && originalBindPort > 0 && socketGroupBindPort != bindPort)
902
 
      {
903
 
         String message = "socket group bind port (" + socketGroupBindPort + 
904
 
                          ") does not match bind port (" + bindPort + ")";
905
 
         log.error(message);
906
 
         socketGroupInfo = null;  // We don't belong to this group.
907
 
         throw new IOException(message);
908
 
      }
909
 
      
910
 
      if (originalBindPort <= 0)
911
 
      {
912
 
         if (socketGroupBindPort > 0)
913
 
            bindPort = socketGroupBindPort;
914
 
         else
915
 
         {
916
 
            bindPort = PortUtil.findFreePort(bindHost);
917
 
            socketGroupBindPort = bindPort;
918
 
         }
919
 
         
920
 
         // re-write locator since the port is different
921
 
         InvokerLocator newLocator = new InvokerLocator(locator.getProtocol(), locator.getHost(), bindPort, locator.getPath(), locator.getParameters());
922
 
         // need to update the locator key used in the invoker registry
923
 
         InvokerRegistry.updateServerInvokerLocator(locator, newLocator);
924
 
         this.locator = newLocator;
925
 
      }
926
 
      
927
 
      isVirtual = true;
928
 
      InetAddress connectAddress = socketGroupInfo.getConnectAddress();
929
 
      int connectPort = socketGroupInfo.getConnectPort();
930
 
      connectSocketAddress = new InetSocketAddress(connectAddress, connectPort);
931
 
      socketGroupInfo.setBindAddress(bindAddress);
932
 
      socketGroupInfo.setBindPort(bindPort);
933
 
      socketGroupInfo.setServerInvoker(this);
934
 
      
935
 
      Iterator it = socketGroupInfo.getClientInvokers().iterator();
936
 
      while (it.hasNext())
937
 
      {
938
 
         ((MultiplexClientInvoker) it.next()).finishStart();
939
 
      }
940
 
      
941
 
      readyToStart = true;
942
 
 
943
 
      if (socketGroupInfo.getPrimingSocket() == null)
944
 
      {
945
 
         socketFactory = createSocketFactory(configuration);
946
 
         if (socketFactory != null)
947
 
            configuration.put(Multiplex.SOCKET_FACTORY, socketFactory);
948
 
         
949
 
         createPrimingSocket(socketGroupInfo, connectAddress.getHostName(), connectPort,
950
 
                             bindAddress, bindPort, configuration, getTimeout());
951
 
      }
952
 
 
953
 
      // We got socketGroupInfo by socketGroupId.  Make sure it is also stored by AddressPair.
954
 
      String connectHost = connectAddress.getHostName();
955
 
      addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
956
 
      addressPairMap.put(addressPair, socketGroupInfo);
957
 
   }
958
 
   
959
 
   
960
 
   protected void rule2(String connectHost, int connectPort)
961
 
   throws IOException
962
 
   {
963
 
      log.debug("server rule 2");
964
 
      isVirtual = true;
965
 
 
966
 
      connectSocketAddress = new InetSocketAddress(connectHost, connectPort);    
967
 
      addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
968
 
      socketGroupInfo = (SocketGroupInfo) addressPairMap.get(addressPair);
969
 
      
970
 
      // If socketGroupInfo exists, it's because it was created, along with a priming socket (if necessary),
971
 
      // by a MultiplexClientInvoker.
972
 
      if (socketGroupInfo != null)
973
 
      {
974
 
         // We got socketGroupInfo by AddressPair.  Make sure it is stored by socketGroupId, if we have one.
975
 
         if (serverMultiplexId != null)
976
 
         {
977
 
            String socketGroupSocketGroupId = socketGroupInfo.getSocketGroupId();
978
 
            
979
 
            if (socketGroupSocketGroupId != null && socketGroupSocketGroupId != serverMultiplexId)
980
 
            {
981
 
               String message = "socket group multiplexId (" + socketGroupSocketGroupId + 
982
 
                                ") does not match multiplexId (" + serverMultiplexId + ")";
983
 
               log.error(message);
984
 
               socketGroupInfo = null; // Assume we weren't meant to join this group.
985
 
               throw new IOException(message);
986
 
            }
987
 
               
988
 
            if (socketGroupSocketGroupId == null)
989
 
            {
990
 
               socketGroupInfo.setSocketGroupId(serverMultiplexId);
991
 
               getSocketGroupMap().put(serverMultiplexId, socketGroupInfo);
992
 
            }
993
 
         }
994
 
         
995
 
         socketGroupInfo.setBindAddress(bindAddress);
996
 
         socketGroupInfo.setBindPort(bindPort);
997
 
         socketGroupInfo.setServerInvoker(this);
998
 
         readyToStart = true;
999
 
         return;
1000
 
      }
1001
 
      
1002
 
      socketGroupInfo = new SocketGroupInfo();
1003
 
      socketGroupInfo.setBindAddress(bindAddress);
1004
 
      socketGroupInfo.setBindPort(bindPort);
1005
 
      socketGroupInfo.setServerInvoker(this);
1006
 
      
1007
 
      // Set connectAddress and connectPort to be able to test for inconsistencies with connect address
1008
 
      // and connect port determined by companion MultiplexClientInvoker.
1009
 
      InetAddress connectAddress = InetAddress.getByName(connectHost);
1010
 
      socketGroupInfo.setConnectAddress(connectAddress);
1011
 
      socketGroupInfo.setConnectPort(connectPort);
1012
 
      
1013
 
      socketFactory = createSocketFactory(configuration);
1014
 
      if (socketFactory != null)
1015
 
         configuration.put(Multiplex.SOCKET_FACTORY, socketFactory);
1016
 
      
1017
 
      createPrimingSocket(socketGroupInfo, connectHost, connectPort,
1018
 
                          bindAddress, bindPort, configuration, getTimeout());
1019
 
      addressPairMap.put(addressPair, socketGroupInfo);
1020
 
      
1021
 
      if (serverMultiplexId != null)
1022
 
      {
1023
 
         socketGroupInfo.setSocketGroupId(serverMultiplexId);
1024
 
         socketGroupMap.put(serverMultiplexId, socketGroupInfo);
1025
 
      }
1026
 
      
1027
 
      readyToStart = true;
1028
 
   }
1029
 
   
1030
 
   
1031
 
   protected void rule3() throws IOException
1032
 
   {
1033
 
      log.debug("server rule 3");
1034
 
      socketGroupInfo = new SocketGroupInfo();
1035
 
      socketGroupInfo.setSocketGroupId(serverMultiplexId);
1036
 
      socketGroupInfo.setServerInvoker(this);
1037
 
      socketGroupInfo.setBindAddress(bindAddress);
1038
 
      socketGroupInfo.setBindPort(bindPort);
1039
 
      socketGroupMap.put(serverMultiplexId, socketGroupInfo);
1040
 
      isVirtual = true;
1041
 
      readyToStart = false;
1042
 
   }
1043
 
   
1044
 
   
1045
 
   protected void rule4()
1046
 
   {
1047
 
      log.debug("server rule 4");
1048
 
      isVirtual = false;
1049
 
      readyToStart = true;
1050
 
   }
1051
 
   
1052
 
   
1053
 
   protected void refreshServerSocket() throws IOException
1054
 
   {
1055
 
      super.refreshServerSocket();
1056
 
   }
1057
 
   
1058
 
   /**
1059
 
    * Returns <code>ServerSocket</code> used to accept invocation requests.
1060
 
    * It is added to facilitate unit tests.
1061
 
    *
1062
 
    * @return <code>ServerSocket</code> used to accept invocation requests.
1063
 
    */
1064
 
   public ServerSocket getServerSocket()
1065
 
   {
1066
 
      return serverSocket;
1067
 
   }
1068
 
   
1069
 
   
1070
 
/**
1071
 
 * Provides access to a virtual <code>MultiplexServerInvoker</code> in a master
1072
 
 * <code>MultiplexServerInvoker</code>'s invoker farm.
1073
 
 */
1074
 
   public MultiplexServerInvoker getServerInvoker(InetSocketAddress address)
1075
 
   {
1076
 
      synchronized (virtualServerInvokers)
1077
 
      {
1078
 
         return (MultiplexServerInvoker) virtualServerInvokers.get(address);
1079
 
      }
1080
 
   }
1081
 
   
1082
 
   
1083
 
/**
1084
 
 * Provides access to all virtual <code>MultiplexServerInvoker</code>s in a master
1085
 
 * <code>MultiplexServerInvoker</code>'s invoker farm.
1086
 
 */
1087
 
   public Collection getServerInvokers()
1088
 
   {
1089
 
      synchronized (virtualServerInvokers)
1090
 
      {
1091
 
         return virtualServerInvokers.values();
1092
 
      }
1093
 
   }
1094
 
   
1095
 
   protected void setBindingInfo() throws IOException
1096
 
   {
1097
 
      String originalUri = getLocator().getOriginalURI();
1098
 
      String pastProtocol = originalUri.substring(originalUri.indexOf("://") + 3);
1099
 
      int colon = pastProtocol.indexOf(":");
1100
 
      int slash = pastProtocol.indexOf("/");
1101
 
      String originalHost = null;
1102
 
      int originalPort = 0;
1103
 
 
1104
 
      if(colon != -1)
1105
 
      {
1106
 
         originalHost = pastProtocol.substring(0, colon).trim();
1107
 
         
1108
 
         if(slash > -1)
1109
 
         {
1110
 
            originalPort = Integer.parseInt(pastProtocol.substring(colon + 1, slash));
1111
 
         }
1112
 
         else
1113
 
         {
1114
 
            originalPort = Integer.parseInt(pastProtocol.substring(colon + 1));
1115
 
         }
1116
 
      }
1117
 
      else
1118
 
      {
1119
 
         if(slash > -1)
1120
 
         {
1121
 
            originalHost = pastProtocol.substring(0, slash).trim();
1122
 
         }
1123
 
         else
1124
 
         {
1125
 
            originalHost = pastProtocol.substring(0).trim();
1126
 
         }
1127
 
      }
1128
 
 
1129
 
      bindHost = getServerBindAddress();
1130
 
      bindPort = getServerBindPort();
1131
 
      bindAddress = InetAddress.getByName(bindHost);   
1132
 
   }
1133
 
   
1134
 
   
1135
 
   protected void getParameters() throws Exception
1136
 
   {
1137
 
      if (configuration != null)
1138
 
         maxAcceptErrors
1139
 
            = Multiplex.getOneParameter(configuration,
1140
 
                                        "maxAcceptErrors",
1141
 
                                        Multiplex.MAX_ACCEPT_ERRORS,
1142
 
                                        Multiplex.MAX_ACCEPT_ERRORS_DEFAULT);
1143
 
      
1144
 
      if (configuration != null)
1145
 
         serverMultiplexId = (String) configuration.get(Multiplex.SERVER_MULTIPLEX_ID);
1146
 
      
1147
 
      if (configuration != null)
1148
 
         multiplexConnectHost = (String) configuration.get(Multiplex.MULTIPLEX_CONNECT_HOST);
1149
 
      
1150
 
      Object value = configuration.get(Multiplex.MULTIPLEX_CONNECT_PORT);
1151
 
      if (value != null)
1152
 
      {
1153
 
         if (value instanceof String)
1154
 
         {     
1155
 
            try
1156
 
            {
1157
 
               multiplexConnectPort = Integer.parseInt((String) value);
1158
 
               multiplexConnectPortIsSet = true;
1159
 
            }
1160
 
            catch (NumberFormatException e)
1161
 
            {
1162
 
               String errorMessage = "number format error for multiplexConnectPort: " + (String) value;
1163
 
               log.error(errorMessage);
1164
 
               throw new IOException(errorMessage);
1165
 
            }
1166
 
         }
1167
 
         else if (value instanceof Integer)
1168
 
         {
1169
 
            multiplexConnectPort = ((Integer) configuration.get(Multiplex.MULTIPLEX_CONNECT_PORT)).intValue();
1170
 
            multiplexConnectPortIsSet = true;
1171
 
         }
1172
 
         else
1173
 
         {
1174
 
            String errorMessage = "invalid object passed for multiplexConnectPort: " + value;
1175
 
            log.error(errorMessage);
1176
 
            throw new IOException(errorMessage);
1177
 
         }
1178
 
      }
1179
 
   }
1180
 
   
1181
 
   
1182
 
   /////////////////////////////////////////////////////////////////////////////////////
1183
 
   //                accessors for configurable Multiplex parameters                  //
1184
 
   /////////////////////////////////////////////////////////////////////////////////////
1185
 
   public int getInputBufferSize()
1186
 
   {
1187
 
      return inputBufferSize;
1188
 
   }
1189
 
 
1190
 
 
1191
 
   public void setInputBufferSize(int inputBufferSize)
1192
 
   {
1193
 
      this.inputBufferSize = inputBufferSize;
1194
 
      if (configuration != null)
1195
 
         configuration.put(Multiplex.INPUT_BUFFER_SIZE, new Integer(inputBufferSize));
1196
 
   }
1197
 
 
1198
 
 
1199
 
   public int getInputMaxErrors()
1200
 
   {
1201
 
      return inputMaxErrors;
1202
 
   }
1203
 
 
1204
 
 
1205
 
   public void setInputMaxErrors(int inputMaxErrors)
1206
 
   {
1207
 
      this.inputMaxErrors = inputMaxErrors;
1208
 
      if (configuration != null)
1209
 
         configuration.put(Multiplex.INPUT_MAX_ERRORS, new Integer(inputMaxErrors));
1210
 
   }
1211
 
 
1212
 
 
1213
 
   public int getMaxAcceptErrors()
1214
 
   {
1215
 
      return maxAcceptErrors;
1216
 
   }
1217
 
 
1218
 
 
1219
 
   public void setMaxAcceptErrors(int maxAcceptErrors)
1220
 
   {
1221
 
      this.maxAcceptErrors = maxAcceptErrors;
1222
 
      if (configuration != null)
1223
 
         configuration.put(Multiplex.MAX_ACCEPT_ERRORS, new Integer(maxAcceptErrors));
1224
 
   }
1225
 
 
1226
 
 
1227
 
   public String getMultiplexConnectHost()
1228
 
   {
1229
 
      return multiplexConnectHost;
1230
 
      
1231
 
   }
1232
 
 
1233
 
 
1234
 
// This method is useless.  See notes about paramters, above.
1235
 
//   public void setMultiplexConnectHost(String multiplexConnectHost)
1236
 
//   {
1237
 
//      this.multiplexConnectHost = multiplexConnectHost;
1238
 
//      if (configuration != null)
1239
 
//         configuration.put(Multiplex.MULTIPLEX_CONNECT_HOST, multiplexConnectHost);
1240
 
//   }
1241
 
 
1242
 
 
1243
 
   public int getMultiplexConnectPort()
1244
 
   {
1245
 
      return multiplexConnectPort;
1246
 
   }
1247
 
 
1248
 
 
1249
 
// This method is useless.  See notes about paramters, above.
1250
 
//   public void setMultiplexConnectPort(int multiplexConnectPort)
1251
 
//   {
1252
 
//      this.multiplexConnectPort = multiplexConnectPort;
1253
 
//      if (configuration != null)
1254
 
//         configuration.put(Multiplex.MULTIPLEX_CONNECT_PORT, new Integer(multiplexConnectPort));
1255
 
//   }
1256
 
   
1257
 
   
1258
 
   public int getOutputMaxChunkSize()
1259
 
   {
1260
 
      return outputMaxChunkSize;
1261
 
   }
1262
 
 
1263
 
 
1264
 
   public void setOutputMaxChunkSize(int outputMaxChunkSize)
1265
 
   {
1266
 
      this.outputMaxChunkSize = outputMaxChunkSize;
1267
 
      if (configuration != null)
1268
 
         configuration.put(Multiplex.OUTPUT_MAX_CHUNK_SIZE, new Integer(outputMaxChunkSize));  
1269
 
   }
1270
 
 
1271
 
 
1272
 
   public int getOutputMaxDataSlice()
1273
 
   {
1274
 
      return outputMaxDataSlice;
1275
 
   }
1276
 
 
1277
 
 
1278
 
   public void setOutputMaxDataSlice(int outputMaxDataSlice)
1279
 
   {
1280
 
      this.outputMaxDataSlice = outputMaxDataSlice;
1281
 
      if (configuration != null)
1282
 
         configuration.put(Multiplex.OUTPUT_MAX_DATA_SLICE, new Integer(outputMaxDataSlice));
1283
 
   }
1284
 
 
1285
 
 
1286
 
   public int getOutputMaxTimeSlice()
1287
 
   {
1288
 
      return outputMaxTimeSlice;
1289
 
   }
1290
 
 
1291
 
 
1292
 
   public void setOutputMaxTimeSlice(int outputMaxTimeSlice)
1293
 
   {
1294
 
      this.outputMaxTimeSlice = outputMaxTimeSlice;
1295
 
      if (configuration != null)
1296
 
         configuration.put(Multiplex.OUTPUT_MAX_TIME_SLICE, new Integer(outputMaxTimeSlice));
1297
 
   }
1298
 
 
1299
 
 
1300
 
   public int getOutputMessagePoolSize()
1301
 
   {
1302
 
      return outputMessagePoolSize;
1303
 
   }
1304
 
 
1305
 
 
1306
 
   public void setOutputMessagePoolSize(int outputMessagePoolSize)
1307
 
   {
1308
 
      this.outputMessagePoolSize = outputMessagePoolSize;
1309
 
      if (configuration != null)
1310
 
         configuration.put(Multiplex.OUTPUT_MESSAGE_POOL_SIZE, new Integer(outputMessagePoolSize));
1311
 
   }
1312
 
 
1313
 
 
1314
 
   public int getOutputMessageSize()
1315
 
   {
1316
 
      return outputMessageSize;
1317
 
   }
1318
 
 
1319
 
 
1320
 
   public void setOutputMessageSize(int outputMessageSize)
1321
 
   {
1322
 
      this.outputMessageSize = outputMessageSize;
1323
 
      if (configuration != null)
1324
 
         configuration.put(Multiplex.OUTPUT_MESSAGE_SIZE, new Integer(outputMessageSize));
1325
 
   }
1326
 
 
1327
 
 
1328
 
   public String getServerMultiplexId()
1329
 
   {
1330
 
      return serverMultiplexId;
1331
 
   }
1332
 
 
1333
 
 
1334
 
//   This method is useless.  See notes about paramters, above.
1335
 
//   public void setServerMultiplexId(String serverMultiplexId)
1336
 
//   {
1337
 
//      this.serverMultiplexId = serverMultiplexId;
1338
 
//      if (configuration != null)
1339
 
//         configuration.put(Multiplex.SERVER_MULTIPLEX_ID, serverMultiplexId);
1340
 
//   }
1341
 
   
1342
 
   
1343
 
   public int getShutdownMonitorPeriod()
1344
 
   {
1345
 
      return shutdownMonitorPeriod;
1346
 
   }
1347
 
 
1348
 
 
1349
 
   public void setShutdownMonitorPeriod(int shutdownMonitorPeriod)
1350
 
   {
1351
 
      this.shutdownMonitorPeriod = shutdownMonitorPeriod;
1352
 
      if (configuration != null)
1353
 
         configuration.put(Multiplex.SHUTDOWN_MONITOR_PERIOD, new Integer(shutdownMonitorPeriod));
1354
 
   }
1355
 
 
1356
 
 
1357
 
   public int getShutdownRefusalsMaximum()
1358
 
   {
1359
 
      return shutdownRefusalsMaximum;
1360
 
   }
1361
 
 
1362
 
 
1363
 
   public void setShutdownRefusalsMaximum(int shutdownRefusalsMaximum)
1364
 
   {
1365
 
      this.shutdownRefusalsMaximum = shutdownRefusalsMaximum;
1366
 
      if (configuration != null)
1367
 
         configuration.put(Multiplex.SHUTDOWN_REFUSALS_MAXIMUM, new Integer(shutdownRefusalsMaximum));
1368
 
   }
1369
 
 
1370
 
 
1371
 
   public int getShutdownRequestTimeout()
1372
 
   {
1373
 
      return shutdownRequestTimeout;
1374
 
   }
1375
 
 
1376
 
 
1377
 
   public void setShutdownRequestTimeout(int shutdownRequestTimeout)
1378
 
   {
1379
 
      this.shutdownRequestTimeout = shutdownRequestTimeout;
1380
 
      if (configuration != null)
1381
 
         configuration.put(Multiplex.SHUTDOWN_REQUEST_TIMEOUT, new Integer(shutdownRequestTimeout));
1382
 
   }
1383
 
 
1384
 
 
1385
 
   public int getStaticThreadsMonitorPeriod()
1386
 
   {
1387
 
      return staticThreadsMonitorPeriod;
1388
 
   }
1389
 
 
1390
 
 
1391
 
   public void setStaticThreadsMonitorPeriod(int staticThreadsMonitorPeriod)
1392
 
   {
1393
 
      this.staticThreadsMonitorPeriod = staticThreadsMonitorPeriod;
1394
 
      if (configuration != null)
1395
 
         configuration.put(Multiplex.STATIC_THREADS_MONITOR_PERIOD, new Integer(staticThreadsMonitorPeriod));
1396
 
   }
1397
 
 
1398
 
 
1399
 
   /**
1400
 
    * <code>SocketGroupInfo</code> holds all of the information for a single virtual socket group.
1401
 
    */
1402
 
   public static class SocketGroupInfo
1403
 
   {
1404
 
      private String                   socketGroupId;
1405
 
      private Set                      clientInvokers = new HashSet();
1406
 
      private MultiplexServerInvoker   serverInvoker;
1407
 
      private boolean                  primingSocketNeeded;
1408
 
      private VirtualSocket            primingSocket;
1409
 
      private InetAddress              connectAddress;
1410
 
      private int                      connectPort;
1411
 
      private InetAddress              bindAddress;
1412
 
      private int                      bindPort;
1413
 
      
1414
 
      public InetAddress getBindAddress()
1415
 
      {
1416
 
         return bindAddress;
1417
 
      }
1418
 
 
1419
 
      public void setBindAddress(InetAddress bindAddress)
1420
 
      {
1421
 
         this.bindAddress = bindAddress;
1422
 
      }
1423
 
 
1424
 
      public int getBindPort()
1425
 
      {
1426
 
         return bindPort;
1427
 
      }
1428
 
 
1429
 
      public void setBindPort(int bindPort)
1430
 
      {
1431
 
         this.bindPort = bindPort;
1432
 
      }
1433
 
      
1434
 
      public Set getClientInvokers()
1435
 
      {
1436
 
         return clientInvokers;
1437
 
      }
1438
 
      
1439
 
      public void addClientInvoker(MultiplexClientInvoker clientInvoker)
1440
 
      {
1441
 
         clientInvokers.add(clientInvoker);
1442
 
      }
1443
 
      
1444
 
      public void removeClientInvoker(MultiplexClientInvoker clientInvoker)
1445
 
      {  
1446
 
         clientInvokers.remove(clientInvoker);
1447
 
      }
1448
 
      
1449
 
      public InetAddress getConnectAddress()
1450
 
      {
1451
 
         return connectAddress;
1452
 
      }
1453
 
  
1454
 
      public void setConnectAddress(InetAddress connectAddress)
1455
 
      {
1456
 
         this.connectAddress = connectAddress;
1457
 
      }
1458
 
  
1459
 
      public int getConnectPort()
1460
 
      {
1461
 
         return connectPort;
1462
 
      }
1463
 
 
1464
 
      public void setConnectPort(int connectPort)
1465
 
      {
1466
 
         this.connectPort = connectPort;
1467
 
      }
1468
 
      
1469
 
      public boolean getPrimingSocketNeeded()
1470
 
      {
1471
 
         return primingSocketNeeded;
1472
 
      }
1473
 
      
1474
 
      public void setPrimingSocketNeeded(boolean primingSocketNeeded)
1475
 
      {
1476
 
         this.primingSocketNeeded = primingSocketNeeded;
1477
 
      }
1478
 
      
1479
 
      public VirtualSocket getPrimingSocket()
1480
 
      {
1481
 
         return primingSocket;
1482
 
      }
1483
 
      
1484
 
      public void setPrimingSocket(VirtualSocket primingSocket)
1485
 
      {
1486
 
         this.primingSocket = primingSocket;
1487
 
      }
1488
 
 
1489
 
      public String getSocketGroupId()
1490
 
      {
1491
 
         return socketGroupId;
1492
 
      }
1493
 
      
1494
 
      public void setSocketGroupId(String socketGroupId)
1495
 
      {
1496
 
         this.socketGroupId = socketGroupId;
1497
 
      }
1498
 
      
1499
 
      public MultiplexServerInvoker getServerInvoker()
1500
 
      {
1501
 
         return serverInvoker;
1502
 
      }
1503
 
      
1504
 
      public void removeServerInvoker(MultiplexServerInvoker serverInvoker)
1505
 
      {
1506
 
         if (this.serverInvoker != serverInvoker)
1507
 
         {
1508
 
            String message = "Attempt to remove unknown MultiplexServerInvoker: " +
1509
 
            "(" + bindAddress + "," + bindPort + ")->(" + 
1510
 
                  connectAddress + "," + connectPort + ")";
1511
 
            log.error(message);
1512
 
         }
1513
 
         
1514
 
         this.serverInvoker = null;
1515
 
      }
1516
 
 
1517
 
      public void setServerInvoker(MultiplexServerInvoker serverInvoker) throws IOException
1518
 
      {
1519
 
         if (this.serverInvoker != null && serverInvoker != null)
1520
 
         {
1521
 
            String message = "Second MultiplexServerInvoker attempting to join invoker group: " +
1522
 
                             "(" + bindAddress + "," + bindPort + ")->(" + 
1523
 
                                   connectAddress + "," + connectPort + ")";
1524
 
            log.error(message);
1525
 
            throw new IOException(message);
1526
 
         }
1527
 
         
1528
 
         this.serverInvoker = serverInvoker;
1529
 
      }
1530
 
   }
1531
 
 
1532
 
   
1533
 
   protected static class InternalHandshakeListener implements HandshakeCompletedListener
1534
 
   {
1535
 
      public void handshakeCompleted(HandshakeCompletedEvent event)
1536
 
      {
1537
 
         handshakeCompletedEvent = event;
1538
 
      }  
1539
 
   }
1540
 
}
 
 
b'\\ No newline at end of file'