/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.remoting.transport.multiplex;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.net.SocketFactory;
import org.jboss.logging.Logger;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
import org.jboss.remoting.transport.multiplex.utility.AddressPair;
import org.jboss.remoting.transport.socket.SocketServerInvoker;
import org.jboss.remoting.util.socket.RemotingSSLSocketFactory;
/**
* @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
* @author <a href="mailto:r.sigal@computer.org">Ron Sigal</a>
*/
public class MultiplexServerInvoker extends SocketServerInvoker
implements MultiplexInvokerConstants, Runnable, VirtualSocket.DisconnectListener
{
protected static final Logger log = Logger.getLogger(MultiplexServerInvoker.class);
private static Map socketGroupMap = new HashMap();
private static Map addressPairMap = new HashMap();
private boolean isVirtual = false;
private Map virtualServerInvokers;
private Socket connectPrimingSocket;
private String socketGroupId;
private SocketGroupInfo socketGroupInfo;
private AddressPair addressPair;
private String bindHost;
private int bindPort;
private int originalBindPort;
private InetAddress bindAddress;
private InetSocketAddress connectSocketAddress;
private boolean readyToStart = true;
private boolean needsSocketGroupConfiguration = true;
private boolean cleanedUp;
private SocketFactory socketFactory;
/**
* FIXME Comment this
*
* @return
*/
public static Map getAddressPairMap()
{
return addressPairMap;
}
/**
* FIXME Comment this
*
* @return
*/
public static Map getSocketGroupMap()
{
return socketGroupMap;
}
/**
*
* Create a new MultiplexServerInvoker.
*
* @param locator
*/
public MultiplexServerInvoker(InvokerLocator locator)
{
super(locator);
virtualServerInvokers = Collections.synchronizedMap(new HashMap());
}
/**
*
* Create a new MultiplexServerInvoker.
*
* @param locator
* @param configuration
*/
public MultiplexServerInvoker(InvokerLocator locator, Map configuration) throws IOException
{
super(locator, configuration);
virtualServerInvokers = Collections.synchronizedMap(new HashMap());
}
/**
*
* Create a new MultiplexServerInvoker.
* @param locator
* @param configuration
* @param serverSocket
* @param virtualServerInvokers TODO
* @param primintSocket TODO
*/
protected MultiplexServerInvoker(InvokerLocator locator, Map configuration,
ServerSocket serverSocket, Socket socket,
Map virtualServerInvokers)
{
super(locator, configuration);
this.serverSocket = serverSocket;
connectPrimingSocket = socket;
this.virtualServerInvokers = virtualServerInvokers;
isVirtual = true;
needsSocketGroupConfiguration = false;
((VirtualSocket) connectPrimingSocket).addDisconnectListener(this);
}
/**
* Each implementation of the remote client invoker should have
* a default data type that is uses in the case it is not specified
* in the invoker locator uri.
*
* @return
*/
protected String getDefaultDataType()
{
return SerializableMarshaller.DATATYPE;
}
//TODO: -TME Need to check on synchronization after initial hook up
public void start() throws IOException
{
socketFactory = createSocketFactory(configuration);
setBindingInfo();
if (!configuration.isEmpty())
{
if (needsSocketGroupConfiguration)
{
try
{
configureSocketGroupParameters(configuration);
}
catch (IOException e)
{
cleanup();
throw e;
}
}
}
if (readyToStart)
finishStart();
}
public void run()
{
if(trace)
{
log.trace("Started execution of method run");
}
while(running)
{
try
{
if(trace)
{
log.trace("Socket is going to be accepted");
}
Socket socket = serverSocket.accept();
if(trace)
{
log.trace("Accepted: " + socket);
}
processInvocation(socket);
}
catch (SocketTimeoutException e)
{
if(running)
{
// If remote MultiplexClientInvoker and optional callback MultiplexServerInvoker
// have shutdown, it's safe to stop.
if (connectPrimingSocket != null && ((VirtualSocket)connectPrimingSocket).hasReceivedDisconnectMessage())
{
log.debug("Client has closed: shutting down");
stop();
return;
}
}
}
catch (javax.net.ssl.SSLException e)
{
log.error("SSLServerSocket error", e);
return;
}
catch(Throwable ex)
{
if(running)
{
log.error("Failed to accept socket connection", ex);
}
}
}
}
public boolean isSafeToShutdown()
{
return (connectPrimingSocket == null || ((VirtualSocket) connectPrimingSocket).hasReceivedDisconnectMessage());
}
public void notifyDisconnected(VirtualSocket virtualSocket)
{
if (virtualSocket != connectPrimingSocket)
{
log.error("notified about disconnection of unrecognized virtual socket");
return;
}
log.debug("remote peer socket has closed: stopping");
stop();
}
public void stop()
{
// If running == false, super.stop() will not call cleanup().
// However, MultiplexServerInvoker could have stuff to clean up
// (socket group information) even if it didn't start.
if (!running)
cleanup();
super.stop();
}
protected void setup() throws Exception
{
originalBindPort = this.getLocator().getPort();
super.setup();
}
/**
* FIXME Comment this
*
*
*/
protected void finishStart() throws IOException
{
log.debug("entering finishStart()");
if (isStarted())
return;
if (socketGroupInfo != null && connectSocketAddress == null)
{
InetAddress connectAddress = socketGroupInfo.getConnectAddress();
int connectPort = socketGroupInfo.getConnectPort();
connectSocketAddress = new InetSocketAddress(connectAddress, connectPort);
}
if (socketGroupInfo != null && addressPair == null)
{
String connectHost = socketGroupInfo.getConnectAddress().getHostName();
int connectPort = socketGroupInfo.getConnectPort();
addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
}
try
{
super.start();
}
catch(IOException e)
{
log.error("Error starting MultiplexServerInvoker.", e);
cleanup();
}
if (running)
log.debug("MultiplexServerInvoker started.");
}
protected void configureSocketGroupParameters(Map parameters) throws IOException
{
log.debug("entering configureSocketGroupParameters()");
log.debug(locator);
String connectHost;
String connectPortString;
int connectPort = -1;
InetAddress connectAddress;
socketGroupId = (String) parameters.get(SERVER_MULTIPLEX_ID_KEY);
synchronized (SocketGroupInfo.class)
{
if (socketGroupId != null && (socketGroupInfo = (SocketGroupInfo) getSocketGroupMap().get(socketGroupId)) != null)
{
// server rule 1.
log.debug("server rule 1");
// If we get here, it's because a MultiplexClientInvoker created a SocketGroupInfo with matching
// group id. We want to make sure that it didn't get a bind address or bind port different
// than the ones passed in through the parameters map.
InetAddress socketGroupBindAddress = socketGroupInfo.getBindAddress();
int socketGroupBindPort = socketGroupInfo.getBindPort();
if (socketGroupBindAddress != null && !socketGroupBindAddress.equals(bindAddress))
{
String message = "socket group bind address (" + socketGroupBindAddress +
") does not match bind address (" + bindAddress + ")";
log.error(message);
socketGroupInfo = null; // We don't belong to this group.
throw new IOException(message);
}
// For future implementation of anonymous port.
// if (socketGroupBindPort > 0 && originalBindPort > 0 && socketGroupBindPort != bindPort)
if (socketGroupBindPort > 0 && socketGroupBindPort != bindPort)
{
String message = "socket group bind port (" + socketGroupBindPort +
") does not match bind port (" + bindPort + ")";
log.error(message);
socketGroupInfo = null; // We don't belong to this group.
throw new IOException(message);
}
// For future implementation of anonymous port.
// if (originalBindPort <= 0 && socketGroupBindPort > 0)
// {
// bindPort = socketGroupBindPort;
// // re-write locator since the port is different
// InvokerLocator newLocator = new InvokerLocator(locator.getProtocol(), locator.getHost(), bindPort, locator.getPath(), locator.getParameters());
// // need to update the locator key used in the invoker registry
// InvokerRegistry.updateServerInvokerLocator(locator, newLocator);
// this.locator = newLocator;
// }
isVirtual = true;
connectAddress = socketGroupInfo.getConnectAddress();
connectPort = socketGroupInfo.getConnectPort();
connectSocketAddress = new InetSocketAddress(connectAddress, connectPort);
socketGroupInfo.setBindAddress(bindAddress);
socketGroupInfo.setBindPort(bindPort);
socketGroupInfo.setServerInvoker(this);
Iterator it = socketGroupInfo.getClientInvokers().iterator();
while (it.hasNext())
{
((MultiplexClientInvoker) it.next()).finishStart();
}
readyToStart = true;
if (socketGroupInfo.getPrimingSocket() == null)
createPrimingSocket(socketGroupInfo, connectAddress.getHostName(), connectPort,
bindAddress, bindPort, socketFactory, getTimeout());
// We got socketGroupInfo by socketGroupId. Make sure it is also stored by AddressPair.
connectHost = connectAddress.getHostName();
addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
addressPairMap.put(addressPair, socketGroupInfo);
return;
}
connectHost = (String) parameters.get(MULTIPLEX_CONNECT_HOST_KEY);
connectPortString = (String) parameters.get(MULTIPLEX_CONNECT_PORT_KEY);
if (connectHost != null && connectPortString == null)
{
throw new IOException("multiplexConnectHost != null and multiplexConnectPort == null");
}
if (connectHost == null && connectPortString != null)
{
throw new IOException("multiplexConnectHost == null and multiplexConnectPort != null");
}
// server rule 2.
if (connectHost != null)
{
log.debug("server rule 2");
isVirtual = true;
try
{
connectPort = Integer.parseInt(connectPortString);
}
catch (NumberFormatException e)
{
throw new IOException("number format error for callbackPort: " + connectPortString);
}
connectSocketAddress = new InetSocketAddress(connectHost, connectPort);
addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
socketGroupInfo = (SocketGroupInfo) addressPairMap.get(addressPair);
// If socketGroupInfo exists, it's because it was created, along with a priming socket (if necessary),
// by a MultiplexClientInvoker.
if (socketGroupInfo != null)
{
// We got socketGroupInfo by AddressPair. Make sure it is stored by socketGroupId, if we have one.
if (socketGroupId != null)
{
String socketGroupSocketGroupId = socketGroupInfo.getSocketGroupId();
if (socketGroupSocketGroupId != null && socketGroupSocketGroupId != socketGroupId)
{
String message = "socket group multiplexId (" + socketGroupSocketGroupId +
") does not match multiplexId (" + socketGroupId + ")";
log.error(message);
socketGroupInfo = null; // Assume we weren't meant to join this group.
throw new IOException(message);
}
if (socketGroupSocketGroupId == null)
{
socketGroupInfo.setSocketGroupId(socketGroupId);
getSocketGroupMap().put(socketGroupId, socketGroupInfo);
}
}
socketGroupInfo.setBindAddress(bindAddress);
socketGroupInfo.setBindPort(bindPort);
socketGroupInfo.setServerInvoker(this);
readyToStart = true;
return;
}
socketGroupInfo = new SocketGroupInfo();
socketGroupInfo.setBindAddress(bindAddress);
socketGroupInfo.setBindPort(bindPort);
socketGroupInfo.setServerInvoker(this);
// Set connectAddress and connectPort to be able to test for inconsistencies with connect address
// and connect port determined by companion MultiplexClientInvoker.
connectAddress = InetAddress.getByName(connectHost);
socketGroupInfo.setConnectAddress(connectAddress);
socketGroupInfo.setConnectPort(connectPort);
createPrimingSocket(socketGroupInfo, connectHost, connectPort,
bindAddress, bindPort, socketFactory, getTimeout());
addressPairMap.put(addressPair, socketGroupInfo);
if (socketGroupId != null)
{
socketGroupInfo.setSocketGroupId(socketGroupId);
socketGroupMap.put(socketGroupId, socketGroupInfo);
}
readyToStart = true;
return;
}
// server rule 3.
if (socketGroupId != null)
{
log.debug("server rule 3");
socketGroupInfo = new SocketGroupInfo();
socketGroupInfo.setSocketGroupId(socketGroupId);
socketGroupInfo.setServerInvoker(this);
socketGroupInfo.setBindAddress(bindAddress);
socketGroupInfo.setBindPort(bindPort);
socketGroupMap.put(socketGroupId, socketGroupInfo);
isVirtual = true;
readyToStart = false;
return;
}
// server rule 4.
log.debug("server rule 4");
isVirtual = false;
readyToStart = true;
}
}
protected static void createPrimingSocket(SocketGroupInfo socketGroupInfo,
String connectHost, int connectPort,
SocketFactory socketFactory, int timeout)
throws IOException
{
createPrimingSocket(socketGroupInfo, connectHost, connectPort, null, -1, socketFactory, timeout);
}
protected static void createPrimingSocket(SocketGroupInfo socketGroupInfo,
String connectHost, int connectPort,
InetAddress bindAddress, int bindPort,
SocketFactory socketFactory, int timeout)
throws IOException
{
log.debug("entering createPrimingSocket()");
boolean needed = true;
InetSocketAddress csa = new InetSocketAddress(connectHost, connectPort);
InetSocketAddress bsa = null;
if (bindAddress != null)
{
bsa = new InetSocketAddress(bindAddress, bindPort);
needed = !MultiplexingManager.checkForShareableManagerByAddressPair(bsa, csa);
}
else
{
needed = !MultiplexingManager.checkForShareableManager(csa);
}
if (socketGroupInfo != null)
socketGroupInfo.setPrimingSocketNeeded(needed);
if (!needed)
{
log.debug("priming socket is not necessary");
return;
}
VirtualSocket socket = new VirtualSocket();
socket.setSocketFactory(socketFactory);
if (bindAddress != null)
socket.connect(csa, bsa, timeout);
else
socket.connect(csa, timeout);
if (socketGroupInfo != null)
socketGroupInfo.setPrimingSocket(socket);
MultiplexingManager manager = socket.getManager();
if (!manager.waitForRemoteServerSocketRegistered())
throw new IOException("error waiting for remote server socket to be registered");
log.debug("created priming socket");
}
protected String getThreadName(int i)
{
String virtualTag = isVirtual ? "v" : "m";
return "MultiplexServerInvoker#" + i + virtualTag + "-" + serverSocket.toString();
}
protected void processInvocation(Socket socket) throws Exception
{
if (isVirtual)
super.processInvocation(socket);
else
{
log.debug("creating VSS");
ServerSocket ss = new VirtualServerSocket((VirtualSocket) socket);
ss.setSoTimeout(getTimeout());
MultiplexServerInvoker si = new MultiplexServerInvoker(locator, getConfiguration(), ss, socket, virtualServerInvokers);
si.clientCallbackListener = clientCallbackListener;
si.handlers = handlers;
virtualServerInvokers.put(socket.getRemoteSocketAddress(), si);
si.create();
si.start();
log.debug("created virtual MultiplexServerInvoker: " + si);
}
}
protected void cleanup()
{
log.debug("entering MultiplexServerInvoker.cleanup()");
// If running == false, SocketServerInvoker doesn't want to call cleanup().
if (running)
super.cleanup();
// If the Finalizer thread gets here after clean up has occurred, return.
if (cleanedUp)
return;
cleanedUp = true;
if (isVirtual)
{
if (connectPrimingSocket != null)
{
// If !virtualServerInvokers.containsKey(connectPrimingSocket.getRemoteSocketAddress()),
// the master MultiplexServerInvoker might be iterating through virtualServerInvokers
// and shutting them down. This test avoids a NullPointerException.
Object key = connectPrimingSocket.getRemoteSocketAddress();
if (virtualServerInvokers.containsKey(key))
virtualServerInvokers.remove(key);
try
{
log.debug("MultiplexServerInvoker: closing connect priming socket");
connectPrimingSocket.close();
}
catch (IOException e)
{
log.error("Error closing connect priming socket during cleanup upon stopping", e);
}
}
else
{
log.info("connect priming socket == null");
}
// Remove all callback handlers (if any ServerInvocationHandlers are registered).
Iterator it = handlers.values().iterator();
if (it.hasNext())
{
ServerInvocationHandler defaultHandler = (ServerInvocationHandler) it.next();
ServerInvocationHandler handler = null;
ServerInvokerCallbackHandler callbackHandler = null;
it = callbackHandlers.values().iterator();
while (it.hasNext())
{
callbackHandler = (ServerInvokerCallbackHandler) it.next();
String subsystem = callbackHandler.getSubsystem();
if (subsystem == null)
handler = defaultHandler;
else
handler = (ServerInvocationHandler) handlers.get(subsystem.toUpperCase());
handler.removeListener(callbackHandler);
}
}
}
else
{
Iterator it = virtualServerInvokers.values().iterator();
while (it.hasNext())
{
ServerInvoker serverInvoker = ((ServerInvoker) it.next());
it.remove();
serverInvoker.stop();
}
}
if (socketGroupInfo != null)
{
synchronized (MultiplexServerInvoker.SocketGroupInfo.class)
{
socketGroupInfo.removeServerInvoker(this);
Socket ps = null;
if (socketGroupInfo.getClientInvokers().isEmpty())
{
log.debug("invoker group shutting down: " + socketGroupInfo.getSocketGroupId());
if ((ps = socketGroupInfo.getPrimingSocket()) != null)
{
log.debug("MultiplexServerInvoker: closing bind priming socket");
try
{
ps.close();
}
catch (IOException e)
{
log.error("Error closing bind priming socket during cleanup upon stopping", e);
}
}
socketGroupId = socketGroupInfo.getSocketGroupId();
if (socketGroupId != null)
{
getSocketGroupMap().remove(socketGroupId);
}
// addressPair is set in finishStart().
if (addressPair != null)
{
getAddressPairMap().remove(addressPair);
}
}
}
}
}
/**
* In creating the server socket, <code>createServerSocket()</code> determines whether multiplexing
* will be supported by this <code>ServerInvoker</code>. The determination is made according to the
* presence or absence of certain parameters in the <code>ServerInvoker</code>'s locator. In particular,
* a <code>VirtualServerSocket</code>, which supports multiplexing, needs to connect to a
* remote <code>MasterServerSocket</code> before it can begin to accept connection requests.
* In order to know which <code>MasterServerSocket</code> to connect to,
* it looks for parameters "connectHost" and "connectPort" in the locator. The presence of these parameters
* indicates that a <code>VirtualServerSocket</code> should be created, and their absence indicates that a
* <code>MasterServerSocket</code>, which does not support multiplexing, should be created.
*
* @param bindPort
* @param backlog
* @param bindAddress
* @return
* @throws IOException
*/
protected ServerSocket createServerSocket(int bindPort, int backlog, InetAddress bindAddress) throws IOException
// private ServerSocket createServerSocket() throws IOException
{
// The following commented code represents an attempt to make an automatic determination as to whether
// a VirtualServerSocket should be created. The idea is to see if a ClientInvoker already
// exists on the local port to which the new server socket wants to bind. The existence of such a
// ClientInvoker would indicate that multiplexing is desired. However, it appears that a ClientInvoker
// has no control over which local port(s) it uses.
// if (InvokerRegistry.isClientInvokerRegistered(getLocator()))
// {
// try
// {
// Invoker clientInvoker = InvokerRegistry.createClientInvoker(getLocator());
// InvokerLocator connectLocator = clientInvoker.getLocator();
// InetSocketAddress connectSocketAddress = new InetSocketAddress(connectLocator.getHost(), connectLocator.getPort());
// InetSocketAddress bindSocketAddress = new InetSocketAddress(bindAddress, serverBindPort);
// svrSocket = new VirtualServerSocket(connectSocketAddress, bindSocketAddress);
// }
// catch (Exception e)
// {
// throw new IOException(e.getMessage());
// }
// }
// If this is a virtual MultiplexServerInvoker created by a master MultiplexServerInvoker,
// then the server socket has already been created.
if (serverSocket != null)
return serverSocket;
ServerSocket svrSocket = null;
if (isVirtual)
{
InetSocketAddress bindSocketAddress = new InetSocketAddress(bindAddress, bindPort);
svrSocket = new VirtualServerSocket(connectSocketAddress, bindSocketAddress, getTimeout());
svrSocket.setSoTimeout(getTimeout());
if (socketGroupInfo != null)
socketGroupInfo.setPrimingSocketNeeded(false);
}
else
{
svrSocket = new MasterServerSocket(getServerSocketFactory(), bindPort, backlog, bindAddress);
}
log.debug("Created " + svrSocket.getClass() + ": " + svrSocket);
return svrSocket;
}
/**
* Returns <code>ServerSocket</code> used to accept invocation requests.
* It is added to facilitate unit tests.
*
* @return <code>ServerSocket</code> used to accept invocation requests.
*/
public ServerSocket getServerSocket()
{
return serverSocket;
}
/**
* FIXME Comment this
*
* @param address
* @return
*/
public MultiplexServerInvoker getServerInvoker(InetSocketAddress address)
{
return (MultiplexServerInvoker) virtualServerInvokers.get(address);
}
/**
* FIXME Comment this
*
* @return
*/
public Collection getServerInvokers()
{
return virtualServerInvokers.values();
}
/**
* FIXME Comment this
*
*
*/
protected void setBindingInfo() throws IOException
{
String originalUri = getLocator().getOriginalURI();
String pastProtocol = originalUri.substring(originalUri.indexOf("://") + 3);
int colon = pastProtocol.indexOf(":");
int slash = pastProtocol.indexOf("/");
String originalHost = null;
int originalPort = 0;
if(colon != -1)
{
originalHost = pastProtocol.substring(0, colon).trim();
if(slash > -1)
{
originalPort = Integer.parseInt(pastProtocol.substring(colon + 1, slash));
}
else
{
originalPort = Integer.parseInt(pastProtocol.substring(colon + 1));
}
}
else
{
if(slash > -1)
{
originalHost = pastProtocol.substring(0, slash).trim();
}
else
{
originalHost = pastProtocol.substring(0).trim();
}
}
bindHost = getServerBindAddress();
bindPort = getServerBindPort();
bindAddress = InetAddress.getByName(bindHost);
}
/**
* If any configuration parameters relate to the construction of a RemotingSSLSocketFactory,
* create one.
*
* @param configuration
* @return
*/
protected SocketFactory createSocketFactory(Map configuration) throws IOException
{
if (configuration == null)
return null;
if (configuration.get(RemotingSSLSocketFactory.REMOTING_ALGORITHM) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_KEY_ALIAS) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_KEY_STORE_FILE_PATH) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_KEY_STORE_PASSWORD) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_KEY_STORE_TYPE) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_TRUST_ALGORITHM) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_TRUST_STORE_FILE_PATH) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_TRUST_STORE_PASSWORD) != null ||
configuration.get(RemotingSSLSocketFactory.REMOTING_TRUST_STORE_TYPE) != null
)
return new RemotingSSLSocketFactory(configuration);
else
return null;
}
public static class SocketGroupInfo
{
private String socketGroupId;
private Set clientInvokers = new HashSet();
private MultiplexServerInvoker serverInvoker;
private boolean primingSocketNeeded;
private VirtualSocket primingSocket;
private InetAddress connectAddress;
private int connectPort;
private InetAddress bindAddress;
private int bindPort;
public InetAddress getBindAddress()
{
return bindAddress;
}
public void setBindAddress(InetAddress bindAddress)
{
this.bindAddress = bindAddress;
}
public int getBindPort()
{
return bindPort;
}
public void setBindPort(int bindPort)
{
this.bindPort = bindPort;
}
public Set getClientInvokers()
{
return clientInvokers;
}
public void addClientInvoker(MultiplexClientInvoker clientInvoker)
{
clientInvokers.add(clientInvoker);
}
public void removeClientInvoker(MultiplexClientInvoker clientInvoker)
{
clientInvokers.remove(clientInvoker);
}
public InetAddress getConnectAddress()
{
return connectAddress;
}
public void setConnectAddress(InetAddress connectAddress)
{
this.connectAddress = connectAddress;
}
public int getConnectPort()
{
return connectPort;
}
public void setConnectPort(int connectPort)
{
this.connectPort = connectPort;
}
public boolean getPrimingSocketNeeded()
{
return primingSocketNeeded;
}
public void setPrimingSocketNeeded(boolean primingSocketNeeded)
{
this.primingSocketNeeded = primingSocketNeeded;
}
public VirtualSocket getPrimingSocket()
{
return primingSocket;
}
public void setPrimingSocket(VirtualSocket primingSocket)
{
this.primingSocket = primingSocket;
}
public String getSocketGroupId()
{
return socketGroupId;
}
public void setSocketGroupId(String socketGroupId)
{
this.socketGroupId = socketGroupId;
}
public MultiplexServerInvoker getServerInvoker()
{
return serverInvoker;
}
public void removeServerInvoker(MultiplexServerInvoker serverInvoker)
{
if (this.serverInvoker != serverInvoker)
{
String message = "Attempt to remove unknown MultiplexServerInvoker: " +
"(" + bindAddress + "," + bindPort + ")->(" +
connectAddress + "," + connectPort + ")";
log.error(message);
}
this.serverInvoker = null;
}
public void setServerInvoker(MultiplexServerInvoker serverInvoker) throws IOException
{
if (this.serverInvoker != null && serverInvoker != null)
{
String message = "Second MultiplexServerInvoker attempting to join invoker group: " +
"(" + bindAddress + "," + bindPort + ")->(" +
connectAddress + "," + connectPort + ")";
log.error(message);
throw new IOException(message);
}
this.serverInvoker = serverInvoker;
}
}
}