| UILServerIL.java |
/*
* JBoss, the OpenSource J2EE WebOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.mq.il.uil2;
import java.io.Serializable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ConnectException;
import java.net.Socket;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.TemporaryQueue;
import javax.jms.TemporaryTopic;
import javax.jms.Topic;
import javax.net.SocketFactory;
import org.jboss.logging.Logger;
import org.jboss.mq.AcknowledgementRequest;
import org.jboss.mq.Connection;
import org.jboss.mq.ConnectionToken;
import org.jboss.mq.DurableSubscriptionID;
import org.jboss.mq.SpyDestination;
import org.jboss.mq.SpyMessage;
import org.jboss.mq.TransactionRequest;
import org.jboss.mq.il.ServerIL;
import org.jboss.mq.il.uil2.msgs.MsgTypes;
import org.jboss.mq.il.uil2.msgs.ConnectionTokenMsg;
import org.jboss.mq.il.uil2.msgs.EnableConnectionMsg;
import org.jboss.mq.il.uil2.msgs.GetIDMsg;
import org.jboss.mq.il.uil2.msgs.TemporaryDestMsg;
import org.jboss.mq.il.uil2.msgs.AcknowledgementRequestMsg;
import org.jboss.mq.il.uil2.msgs.AddMsg;
import org.jboss.mq.il.uil2.msgs.BrowseMsg;
import org.jboss.mq.il.uil2.msgs.CheckIDMsg;
import org.jboss.mq.il.uil2.msgs.CheckUserMsg;
import org.jboss.mq.il.uil2.msgs.CloseMsg;
import org.jboss.mq.il.uil2.msgs.CreateDestMsg;
import org.jboss.mq.il.uil2.msgs.DeleteTemporaryDestMsg;
import org.jboss.mq.il.uil2.msgs.DeleteSubscriptionMsg;
import org.jboss.mq.il.uil2.msgs.PingMsg;
import org.jboss.mq.il.uil2.msgs.ReceiveMsg;
import org.jboss.mq.il.uil2.msgs.SubscribeMsg;
import org.jboss.mq.il.uil2.msgs.TransactMsg;
import org.jboss.mq.il.uil2.msgs.UnsubscribeMsg;
/** The UILServerIL is created on the server and copied to the client during
* connection factory lookups. It represents the transport interface to the
* JMS server.
*
* @author Scott.Stark@jboss.org
* @version $Revision: 1.7.2.1 $
*/
public class UILServerIL
implements Cloneable, MsgTypes, Serializable, ServerIL
{
/** @since 1.7, at least jboss-3.2.5, jboss-4.0.0 */
private static final long serialVersionUID = 853594001646066224L;
private static Logger log = Logger.getLogger(UILServerIL.class);
/** The org.jboss.mq.il.uil2.useServerHost system property allows a client to
* to connect to the host name rather than the ip address
*/
private final static String USE_SERVER_HOST = "org.jboss.mq.il.uil2.useServerHost";
/** The org.jboss.mq.il.uil2.localAddr system property allows a client to
*define the local interface to which its sockets should be bound
*/
private final static String LOCAL_ADDR = "org.jboss.mq.il.uil2.localAddr";
/** The org.jboss.mq.il.uil2.localPort system property allows a client to
*define the local port to which its sockets should be bound
*/
private final static String LOCAL_PORT = "org.jboss.mq.il.uil2.localPort";
/** The org.jboss.mq.il.uil2.serverAddr system property allows a client to
* override the address to which it attempts to connect to. This is useful
* for networks where NAT is ocurring between the client and jms server.
*/
private final static String SERVER_ADDR = "org.jboss.mq.il.uil2.serverAddr";
/** The org.jboss.mq.il.uil2.serverPort system property allows a client to
* override the port to which it attempts to connect. This is useful for
* for networks where port forwarding is ocurring between the client and jms
* server.
*/
private final static String SERVER_PORT = "org.jboss.mq.il.uil2.serverPort";
/** The org.jboss.mq.il.uil2.retryCount controls the number of attempts to
* retry connecting to the jms server. Retries are only made for
* java.net.ConnectException failures. A value <= 0 means no retry atempts
* will be made.
*/
private final static String RETRY_COUNT = "org.jboss.mq.il.uil2.retryCount";
/** The org.jboss.mq.il.uil2.retryDelay controls the delay in milliseconds
* between retries due to ConnectException failures.
*/
private final static String RETRY_DELAY = "org.jboss.mq.il.uil2.retryDelay";
/** The server host name/IP to connect to as defined by the jms server.
*/
private InetAddress addr;
/** The server port to connect to as defined by the jms server.
*/
private int port;
/** The name of the class implementing the javax.net.SocketFactory to
* use for creating the client socket.
*/
private String socketFactoryName;
/**
* If the TcpNoDelay option should be used on the socket.
*/
private boolean enableTcpNoDelay = false;
/**
* The buffer size.
*/
private int bufferSize;
/**
* The chunk size.
*/
private int chunkSize;
/** The local interface name/IP to use for the client
*/
private transient InetAddress localAddr;
/** The local port to use for the client
*/
private transient int localPort;
/**
* Description of the Field
*/
protected transient Socket socket;
/**
* Description of the Field
*/
protected transient SocketManager socketMgr;
/**
*
* @param addr
* @param port
* @param socketFactoryName
* @param enableTcpNoDelay
* @param bufferSize
* @param chunkSize
* @throws Exception
*/
public UILServerIL(InetAddress addr, int port, String socketFactoryName,
boolean enableTcpNoDelay, int bufferSize, int chunkSize)
throws Exception
{
this.addr = addr;
this.port = port;
this.socketFactoryName = socketFactoryName;
this.enableTcpNoDelay = enableTcpNoDelay;
this.bufferSize = bufferSize;
this.chunkSize = chunkSize;
}
/**
* Sets the ConnectionToken attribute of the UILServerIL object
*
* @param dest The new ConnectionToken value
* @exception Exception Description of Exception
*/
public void setConnectionToken(ConnectionToken dest)
throws Exception
{
ConnectionTokenMsg msg = new ConnectionTokenMsg(dest);
getSocketMgr().sendMessage(msg);
}
/**
* Sets the Enabled attribute of the UILServerIL object
*
* @param dc The new Enabled value
* @param enabled The new Enabled value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void setEnabled(ConnectionToken dc, boolean enabled)
throws JMSException, Exception
{
EnableConnectionMsg msg = new EnableConnectionMsg(enabled);
getSocketMgr().sendMessage(msg);
}
/**
* Gets the ID attribute of the UILServerIL object
*
* @return The ID value
* @exception Exception Description of Exception
*/
public String getID()
throws Exception
{
GetIDMsg msg = new GetIDMsg();
getSocketMgr().sendMessage(msg);
String id = msg.getID();
return id;
}
/**
* Gets the TemporaryQueue attribute of the UILServerIL object
*
* @param dc Description of Parameter
* @return The TemporaryQueue value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public TemporaryQueue getTemporaryQueue(ConnectionToken dc)
throws JMSException, Exception
{
TemporaryDestMsg msg = new TemporaryDestMsg(true);
getSocketMgr().sendMessage(msg);
TemporaryQueue dest = msg.getQueue();
return dest;
}
/**
* Gets the TemporaryTopic attribute of the UILServerIL object
*
* @param dc Description of Parameter
* @return The TemporaryTopic value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public TemporaryTopic getTemporaryTopic(ConnectionToken dc)
throws JMSException, Exception
{
TemporaryDestMsg msg = new TemporaryDestMsg(false);
getSocketMgr().sendMessage(msg);
TemporaryTopic dest = msg.getTopic();
return dest;
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param item Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void acknowledge(ConnectionToken dc, AcknowledgementRequest item)
throws JMSException, Exception
{
AcknowledgementRequestMsg msg = new AcknowledgementRequestMsg(item);
getSocketMgr().sendMessage(msg);
}
/**
* Adds a feature to the Message attribute of the UILServerIL object
*
* @param dc The feature to be added to the Message attribute
* @param val The feature to be added to the Message attribute
* @exception Exception Description of Exception
*/
public void addMessage(ConnectionToken dc, SpyMessage val)
throws Exception
{
AddMsg msg = new AddMsg(val);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param dest Description of Parameter
* @param selector Description of Parameter
* @return Description of the Returned Value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public SpyMessage[] browse(ConnectionToken dc, Destination dest, String selector)
throws JMSException, Exception
{
BrowseMsg msg = new BrowseMsg(dest, selector);
getSocketMgr().sendMessage(msg);
SpyMessage[] msgs = msg.getMessages();
return msgs;
}
/**
* #Description of the Method
*
* @param id Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void checkID(String id)
throws JMSException, Exception
{
CheckIDMsg msg = new CheckIDMsg(id);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param username Description of Parameter
* @param password Description of Parameter
* @return Description of the Returned Value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public String checkUser(String username, String password)
throws JMSException, Exception
{
CheckUserMsg msg = new CheckUserMsg(username, password, false);
getSocketMgr().sendMessage(msg);
String clientID = msg.getID();
return clientID;
}
/**
* Authenticate the user
*
* @param username Description of Parameter
* @param password Description of Parameter
* @return a sessionID
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public String authenticate(String username, String password)
throws JMSException, Exception
{
CheckUserMsg msg = new CheckUserMsg(username, password, true);
getSocketMgr().sendMessage(msg);
String sessionID = msg.getID();
return sessionID;
}
/**
* #Description of the Method
*
* @return Description of the Returned Value
* @exception CloneNotSupportedException Description of Exception
*/
public Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
/**
* Need to clone because there are instance variables tha can get clobbered.
* All Multiple connections can NOT share the same JVMServerIL object
*
* @return Description of the Returned Value
* @exception Exception Description of Exception
*/
public ServerIL cloneServerIL()
throws Exception
{
return (ServerIL)clone();
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void connectionClosing(ConnectionToken dc)
throws JMSException, Exception
{
CloseMsg msg = new CloseMsg();
try
{
getSocketMgr().sendMessage(msg);
}
catch (IOException ignored)
{
}
destroyConnection();
}
/**
* #Description of the Method
*
* @param dc - the destination connection token
* @param destName - the name of the destination
* @return
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public Queue createQueue(ConnectionToken dc, String destName)
throws JMSException, Exception
{
CreateDestMsg msg = new CreateDestMsg(destName, true);
getSocketMgr().sendMessage(msg);
Queue dest = msg.getQueue();
return dest;
}
/**
* #Description of the Method
*
* @param dc - the destination connection token
* @param destName - the name of the destination
* @return Description of the Returned Value
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public Topic createTopic(ConnectionToken dc, String destName)
throws JMSException, Exception
{
CreateDestMsg msg = new CreateDestMsg(destName, false);
getSocketMgr().sendMessage(msg);
Topic dest = msg.getTopic();
return dest;
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param dest Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void deleteTemporaryDestination(ConnectionToken dc, SpyDestination dest)
throws JMSException, Exception
{
DeleteTemporaryDestMsg msg = new DeleteTemporaryDestMsg(dest);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param id Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void destroySubscription(ConnectionToken dc,DurableSubscriptionID id)
throws JMSException, Exception
{
DeleteSubscriptionMsg msg = new DeleteSubscriptionMsg(id);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param clientTime Description of Parameter
* @exception Exception Description of Exception
*/
public void ping(ConnectionToken dc, long clientTime)
throws Exception
{
PingMsg msg = new PingMsg(clientTime, true);
msg.getMsgID();
getSocketMgr().sendReply(msg);
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param subscriberId Description of Parameter
* @param wait Description of Parameter
* @return Description of the Returned Value
* @exception Exception Description of Exception
*/
public SpyMessage receive(ConnectionToken dc, int subscriberId, long wait)
throws Exception, Exception
{
ReceiveMsg msg = new ReceiveMsg(subscriberId, wait);
getSocketMgr().sendMessage(msg);
SpyMessage reply = msg.getMessage();
return reply;
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param s Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void subscribe(ConnectionToken dc, org.jboss.mq.Subscription s)
throws JMSException, Exception
{
SubscribeMsg msg = new SubscribeMsg(s);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param dc Description of Parameter
* @param t Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void transact(org.jboss.mq.ConnectionToken dc, TransactionRequest t)
throws JMSException, Exception
{
TransactMsg msg = new TransactMsg(t);
getSocketMgr().sendMessage(msg);
}
/**
* #Description of the Method
*
* @param dc - the destination connection token
* @param subscriptionID Description of Parameter
* @exception JMSException Description of Exception
* @exception Exception Description of Exception
*/
public void unsubscribe(ConnectionToken dc, int subscriptionID)
throws JMSException, Exception
{
UnsubscribeMsg msg = new UnsubscribeMsg(subscriptionID);
getSocketMgr().sendMessage(msg);
}
final SocketManager getSocketMgr()
throws Exception
{
if( socketMgr == null )
createConnection();
return socketMgr;
}
/**
* #Description of the Method
*
* @exception Exception Description of Exception
*/
protected void checkConnection()
throws Exception
{
if (socketMgr == null)
{
createConnection();
}
}
/**
* Used to establish a new connection to the server
*
* @exception Exception Description of Exception
*/
protected void createConnection()
throws Exception
{
boolean tracing = log.isTraceEnabled();
if( tracing )
log.trace("Connecting to : "+addr+":"+port);
/** Attempt to load the socket factory and if this fails, use the
* default socket factory impl.
*/
SocketFactory socketFactory = null;
if( socketFactoryName != null )
{
try
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class factoryClass = loader.loadClass(socketFactoryName);
socketFactory = (SocketFactory) factoryClass.newInstance();
}
catch(Exception e)
{
log.debug("Failed to load socket factory: "+socketFactoryName, e);
}
}
// Use the default socket factory
if( socketFactory == null )
{
socketFactory = SocketFactory.getDefault();
}
// Look for a local address and port as properties
String tmp = getProperty(LOCAL_ADDR);
if( tmp != null )
this.localAddr = InetAddress.getByName(tmp);
tmp = getProperty(LOCAL_PORT);
if( tmp != null )
this.localPort = Integer.parseInt(tmp);
// Look for client side overrides of the server address/port
InetAddress serverAddr = addr;
int serverPort = port;
tmp = getProperty(SERVER_ADDR);
if( tmp != null )
serverAddr = InetAddress.getByName(tmp);
tmp = getProperty(SERVER_PORT);
if( tmp != null )
serverPort = Integer.parseInt(tmp);
String useHostNameProp = getProperty(USE_SERVER_HOST);
String serverHost = serverAddr.getHostAddress();
if (Boolean.valueOf(useHostNameProp).booleanValue())
serverHost = serverAddr.getHostName();
if( tracing )
{
log.trace("Connecting with addr="+serverHost+", port="+serverPort
+ ", localAddr="+localAddr+", localPort="+localPort
+ ", socketFactory="+socketFactory
+ ", enableTcpNoDelay="+enableTcpNoDelay
+ ", bufferSize="+bufferSize
+ ", chunkSize="+chunkSize
);
}
int retries = 0;
// Default to 10 retries, no delay in the absence of user override
int maxRetries = 10;
tmp = getProperty(RETRY_COUNT);
if( tmp != null )
maxRetries = Integer.parseInt(tmp);
long retryDelay = 0;
tmp = getProperty(RETRY_DELAY);
if( tmp != null )
{
retryDelay = Long.parseLong(tmp);
if( retryDelay < 0 )
retryDelay = 0;
}
if( tracing )
log.trace("Begin connect loop, maxRetries="+maxRetries+", delay="+retryDelay);
while (true)
{
try
{
if( localAddr != null )
socket = socketFactory.createSocket(serverHost, port, localAddr, localPort);
else
socket = socketFactory.createSocket(serverHost, port);
break;
}
catch (ConnectException e)
{
if (++retries > maxRetries)
throw e;
if( tracing )
log.trace("Failed to connect, retries="+retries, e);
}
try
{
Thread.sleep(retryDelay);
}
catch(InterruptedException e)
{
break;
}
}
socket.setTcpNoDelay(enableTcpNoDelay);
socketMgr = new SocketManager(socket);
socketMgr.setBufferSize(bufferSize);
socketMgr.setChunkSize(chunkSize);
socketMgr.start(Connection.getThreadGroup());
}
/**
* Used to close the current connection with the server
*
*/
protected void destroyConnection()
{
try
{
if( socket != null )
{
try
{
socketMgr.stop();
}
finally
{
socket.close();
}
}
}
catch(IOException ignore)
{
}
}
private String getProperty(String name)
{
String value = null;
try
{
value = System.getProperty(name);
}
catch (Throwable ignored)
{
log.trace("Cannot retrieve system property " + name);
}
return value;
}
}
| UILServerIL.java |