package org.jboss.mq.il.uil2;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.net.ServerSocketFactory;
import org.jboss.mq.il.Invoker;
import org.jboss.mq.il.ServerIL;
import org.jboss.mq.il.ServerILJMXService;
import org.jboss.mq.il.uil2.msgs.MsgTypes;
import org.jboss.mq.il.uil2.msgs.BaseMsg;
import org.jboss.security.SecurityDomain;
import org.jboss.system.server.ServerConfigUtil;
public class UILServerILService extends ServerILJMXService
implements MsgTypes, Runnable, UILServerILServiceMBean
{
final static int SO_TIMEOUT = 5000;
private Invoker server;
private String securityDomain;
private String clientSocketFactoryName;
private ServerSocketFactory serverSocketFactory;
private ServerSocket serverSocket;
private UILServerIL serverIL;
private boolean running;
private int serverBindPort = 0;
private InetAddress bindAddress = null;
private Thread acceptThread;
private InetAddress clientAddress;
private boolean enableTcpNoDelay = false;
private int readTimeout = 0;
private int bufferSize = 1;
private int chunkSize = 0x40000000;
private Properties connectionProperties;
public Properties getClientConnectionProperties()
{
return connectionProperties;
}
public ServerIL getServerIL()
{
return serverIL;
}
public void run()
{
boolean trace = log.isTraceEnabled();
while (running)
{
Socket socket = null;
SocketManager socketMgr = null;
try
{
socket = serverSocket.accept();
if( trace )
log.trace("Accepted connection: "+socket);
socket.setSoTimeout(readTimeout);
socket.setTcpNoDelay(enableTcpNoDelay);
socketMgr = new SocketManager(socket);
ServerSocketManagerHandler handler = new ServerSocketManagerHandler(server, socketMgr);
socketMgr.setHandler(handler);
socketMgr.setBufferSize(bufferSize);
socketMgr.setChunkSize(chunkSize);
socketMgr.start(server.getThreadGroup());
}
catch (IOException e)
{
if (running)
log.warn("Failed to setup client connection", e);
}
catch(Throwable e)
{
if (running || trace)
log.warn("Unexpected error in setup of client connection", e);
}
}
}
public void startService() throws Exception
{
super.startService();
running = true;
this.server = lookupJMSServer();
if (serverSocketFactory == null)
serverSocketFactory = ServerSocketFactory.getDefault();
if (securityDomain != null)
{
try
{
InitialContext ctx = new InitialContext();
Class ssfClass = serverSocketFactory.getClass();
SecurityDomain domain = (SecurityDomain) ctx.lookup(securityDomain);
Class[] parameterTypes = {SecurityDomain.class};
Method m = ssfClass.getMethod("setSecurityDomain", parameterTypes);
Object[] args = {domain};
m.invoke(serverSocketFactory, args);
}
catch (NoSuchMethodException e)
{
log.error("Socket factory does not support setSecurityDomain(SecurityDomain)");
}
catch (Exception e)
{
log.error("Failed to setSecurityDomain=" + securityDomain + " on socket factory");
}
}
serverSocket = serverSocketFactory.createServerSocket(serverBindPort, 50, bindAddress);
InetAddress socketAddress = serverSocket.getInetAddress();
log.info("JBossMQ UIL service available at : " + socketAddress + ":" + serverSocket.getLocalPort());
acceptThread = new Thread(server.getThreadGroup(), this, "UILServerILService Accept Thread");
acceptThread.start();
socketAddress = ServerConfigUtil.fixRemoteAddress(socketAddress);
if( clientAddress != null )
socketAddress = clientAddress;
serverIL = new UILServerIL(socketAddress, serverSocket.getLocalPort(),
clientSocketFactoryName, enableTcpNoDelay, bufferSize, chunkSize);
connectionProperties = super.getClientConnectionProperties();
connectionProperties.setProperty(UILServerILFactory.CLIENT_IL_SERVICE_KEY, UILClientILService.class.getName());
connectionProperties.setProperty(UILServerILFactory.UIL_PORT_KEY, "" + serverSocket.getLocalPort());
connectionProperties.setProperty(UILServerILFactory.UIL_ADDRESS_KEY, "" + socketAddress.getHostAddress());
connectionProperties.setProperty(UILServerILFactory.UIL_TCPNODELAY_KEY, enableTcpNoDelay ? "yes" : "no");
connectionProperties.setProperty(UILServerILFactory.UIL_BUFFERSIZE_KEY, "" + bufferSize);
connectionProperties.setProperty(UILServerILFactory.UIL_CHUNKSIZE_KEY, "" + chunkSize);
connectionProperties.setProperty(UILServerILFactory.UIL_RECEIVE_REPLIES_KEY, "No");
bindJNDIReferences();
BaseMsg.setUseJMSServerMsgIDs(true);
}
public void stopService()
{
try
{
running = false;
unbindJNDIReferences();
if (serverSocket != null)
{
serverSocket.close();
}
}
catch (Exception e)
{
log.error("Exception occured when trying to stop UIL Service: ", e);
}
}
public int getServerBindPort()
{
return serverBindPort;
}
public void setServerBindPort(int serverBindPort)
{
this.serverBindPort = serverBindPort;
}
public String getBindAddress()
{
String addr = "0.0.0.0";
if (bindAddress != null)
addr = bindAddress.getHostName();
return addr;
}
public void setBindAddress(String host) throws UnknownHostException
{
if (host == null || host.length() == 0)
bindAddress = null;
else
bindAddress = InetAddress.getByName(host);
}
public InetAddress getClientAddress()
{
return clientAddress;
}
public void setClientAddress(InetAddress addr)
{
clientAddress = addr;
}
public boolean getEnableTcpNoDelay()
{
return enableTcpNoDelay;
}
public void setEnableTcpNoDelay(boolean enableTcpNoDelay)
{
this.enableTcpNoDelay = enableTcpNoDelay;
}
public int getBufferSize()
{
return bufferSize;
}
public void setBufferSize(int size)
{
this.bufferSize = size;
}
public int getChunkSize()
{
return chunkSize;
}
public void setChunkSize(int size)
{
this.chunkSize = size;
}
public int getReadTimeout()
{
return readTimeout;
}
public void setReadTimeout(int timeout)
{
this.readTimeout = timeout;
}
public String getClientSocketFactory()
{
return clientSocketFactoryName;
}
public void setClientSocketFactory(String name)
{
this.clientSocketFactoryName = name;
}
public void setServerSocketFactory(String name) throws Exception
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class ssfClass = loader.loadClass(name);
serverSocketFactory = (ServerSocketFactory) ssfClass.newInstance();
}
public String getServerSocketFactory()
{
String name = null;
if (serverSocketFactory != null)
name = serverSocketFactory.getClass().getName();
return name;
}
public void setSecurityDomain(String domainName)
{
this.securityDomain = domainName;
}
public String getSecurityDomain()
{
return this.securityDomain;
}
}