package org.jboss.mq.il.oil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
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.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;
public final class OILServerIL
implements java.io.Serializable,
java.lang.Cloneable,
org.jboss.mq.il.ServerIL
{
static final long serialVersionUID = 5576846920031604128L;
private static Logger log = Logger.getLogger(OILServerIL.class);
private final static String LOCAL_ADDR = "org.jboss.mq.il.oil.localAddr";
private final static String LOCAL_PORT = "org.jboss.mq.il.oil.localPort";
private InetAddress addr;
private int port;
private String socketFactoryName;
private boolean enableTcpNoDelay = false;
private transient InetAddress localAddr;
private transient int localPort;
private transient ObjectInputStream in;
private transient ObjectOutputStream out;
private transient Socket socket;
public OILServerIL(InetAddress addr, int port,
String socketFactoryName, boolean enableTcpNoDelay)
{
this.addr = addr;
this.port = port;
this.socketFactoryName = socketFactoryName;
this.enableTcpNoDelay = enableTcpNoDelay;
}
public synchronized void setConnectionToken(ConnectionToken dest)
throws Exception
{
checkConnection();
out.writeByte(OILConstants.SET_SPY_DISTRIBUTED_CONNECTION);
out.writeObject(dest);
waitAnswer();
}
public synchronized void setEnabled(ConnectionToken dc, boolean enabled)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.SET_ENABLED);
out.writeBoolean(enabled);
waitAnswer();
}
public synchronized String getID()
throws Exception
{
checkConnection();
out.writeByte(OILConstants.GET_ID);
return (String)waitAnswer();
}
public synchronized TemporaryQueue getTemporaryQueue(ConnectionToken dc)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.GET_TEMPORARY_QUEUE);
return (TemporaryQueue)waitAnswer();
}
public synchronized TemporaryTopic getTemporaryTopic(ConnectionToken dc)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.GET_TEMPORARY_TOPIC);
return (TemporaryTopic)waitAnswer();
}
public synchronized void acknowledge(ConnectionToken dc, AcknowledgementRequest item)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.ACKNOWLEDGE);
item.writeExternal(out);
waitAnswer();
}
public synchronized void addMessage(ConnectionToken dc, SpyMessage val)
throws Exception
{
checkConnection();
out.writeByte(OILConstants.ADD_MESSAGE);
SpyMessage.writeMessage(val, out);
waitAnswer();
}
public synchronized SpyMessage[] browse(ConnectionToken dc, Destination dest, String selector)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.BROWSE);
out.writeObject(dest);
out.writeObject(selector);
return (SpyMessage[])waitAnswer();
}
public synchronized void checkID(String ID)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.CHECK_ID);
out.writeObject(ID);
waitAnswer();
}
public synchronized String checkUser(String userName, String password)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.CHECK_USER);
out.writeObject(userName);
out.writeObject(password);
return (String)waitAnswer();
}
public synchronized String authenticate(String userName, String password)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.AUTHENTICATE);
out.writeObject(userName);
out.writeObject(password);
return (String)waitAnswer();
}
public Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
public ServerIL cloneServerIL()
throws Exception
{
return (ServerIL)clone();
}
public synchronized void connectionClosing(ConnectionToken dc)
throws JMSException, Exception
{
try
{
checkConnection();
out.writeByte(OILConstants.CONNECTION_CLOSING);
waitAnswer();
}
finally
{
destroyConnection();
}
}
public synchronized Queue createQueue(ConnectionToken dc, String dest)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.CREATE_QUEUE);
out.writeObject(dest);
return (Queue)waitAnswer();
}
public synchronized Topic createTopic(ConnectionToken dc, String dest)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.CREATE_TOPIC);
out.writeObject(dest);
return (Topic)waitAnswer();
}
public synchronized void deleteTemporaryDestination(ConnectionToken dc, SpyDestination dest)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.DELETE_TEMPORARY_DESTINATION);
out.writeObject(dest);
waitAnswer();
}
public synchronized void destroySubscription(ConnectionToken dc,DurableSubscriptionID id)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.DESTROY_SUBSCRIPTION);
out.writeObject(id);
waitAnswer();
}
public synchronized void ping(ConnectionToken dc, long clientTime)
throws Exception
{
checkConnection();
out.writeByte(OILConstants.PING);
out.writeLong(clientTime);
waitAnswer();
}
public synchronized SpyMessage receive(ConnectionToken dc, int subscriberId, long wait)
throws Exception, Exception
{
checkConnection();
out.writeByte(OILConstants.RECEIVE);
out.writeInt(subscriberId);
out.writeLong(wait);
return (SpyMessage)waitAnswer();
}
public synchronized void subscribe(ConnectionToken dc, org.jboss.mq.Subscription s)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.SUBSCRIBE);
out.writeObject(s);
waitAnswer();
}
public synchronized void transact(org.jboss.mq.ConnectionToken dc, TransactionRequest t)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.TRANSACT);
t.writeExternal(out);
waitAnswer();
}
public synchronized void unsubscribe(ConnectionToken dc, int subscriptionId)
throws JMSException, Exception
{
checkConnection();
out.writeByte(OILConstants.UNSUBSCRIBE);
out.writeInt(subscriptionId);
waitAnswer();
}
private void checkConnection()
throws Exception
{
if (socket == null)
{
createConnection();
}
}
private void createConnection()
throws Exception
{
boolean tracing = log.isTraceEnabled();
if( tracing )
log.trace("Connecting to : "+addr+":"+port);
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);
}
}
if( socketFactory == null )
{
socketFactory = SocketFactory.getDefault();
}
String tmp = System.getProperty(LOCAL_ADDR);
if( tmp != null )
this.localAddr = InetAddress.getByName(tmp);
tmp = System.getProperty(LOCAL_PORT);
if( tmp != null )
this.localPort = Integer.parseInt(tmp);
if( tracing )
{
log.trace("Connecting with addr="+addr+", port="+port
+ ", localAddr="+localAddr+", localPort="+localPort
+ ", socketFactory="+socketFactory);
}
if( localAddr != null )
socket = socketFactory.createSocket(addr, port, localAddr, localPort);
else
socket = socketFactory.createSocket(addr, port);
socket.setTcpNoDelay(enableTcpNoDelay);
in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
out = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
out.flush();
}
private void destroyConnection()
throws Exception
{
try
{
out.close();
in.close();
}
finally
{
socket.close();
}
}
private Object waitAnswer()
throws Exception
{
out.reset();
out.flush();
int val = in.readByte();
if (val == OILConstants.SUCCESS)
{
return null;
}
if (val == OILConstants.SUCCESS_OBJECT)
{
return in.readObject();
}
else
{
Exception e = (Exception)in.readObject();
throw e;
}
}
}