dk.netarkivet.common.distribute
Class JMSConnection

java.lang.Object
  extended by dk.netarkivet.common.distribute.JMSConnection
All Implemented Interfaces:
CleanupIF, javax.jms.ExceptionListener
Direct Known Subclasses:
JMSConnectionSunMQ

public abstract class JMSConnection
extends java.lang.Object
implements javax.jms.ExceptionListener, CleanupIF

Handles the communication with a JMS broker. Note on Thread-safety: the methods and fields of JMSConnection are not accessed by multiple threads (though JMSConnection itself creates threads). Thus no synchronization is needed on methods and fields of JMSConnection. A shutdown hook is also added, which closes the connection. Class JMSConnection is now also a exceptionhandler for the JMS Connections


Field Summary
protected  java.lang.Thread closeHook
          Shutdown hook that closes the JMS connection.
protected  javax.jms.Connection connection
          The JMS Connection.
protected  java.util.concurrent.locks.ReentrantReadWriteLock connectionLock
          Lock for the connection.
protected static java.lang.String CONSUMER_KEY_SEPARATOR
          Separator used in the consumer key.
protected  java.util.Map<java.lang.String,javax.jms.MessageConsumer> consumers
          Map for caching message consumers (topic-subscribers and queue-receivers).
protected static JMSConnection instance
          Singleton pattern is be used for this class.
(package private) static int JMS_MAXTRIES
          The number to times to (re)try whenever a JMSException is thrown.
protected  java.util.Map<java.lang.String,javax.jms.MessageListener> listeners
          Map for caching message listeners (topic-subscribers and queue-receivers).
protected  java.util.Map<java.lang.String,javax.jms.MessageProducer> producers
          Map for caching message producers.
protected  javax.jms.Session session
          The Session handling messages sent to / received from the NetarchiveSuite queues and topics.
 
Constructor Summary
protected JMSConnection()
          Class constructor.
 
Method Summary
 void cleanup()
          Clean up.
 javax.jms.QueueBrowser createQueueBrowser(ChannelID queueID)
          Creates a QueueBrowser object to peek at the messages on the specified queue.
protected abstract  javax.jms.ConnectionFactory getConnectionFactory()
          Should be implemented according to a specific JMS broker.
protected static java.lang.String getConsumerKey(java.lang.String channel, javax.jms.MessageListener messageListener)
          Generate a consumerkey based on the given channel name and messageListener.
protected abstract  javax.jms.Destination getDestination(java.lang.String destinationName)
          Should be implemented according to a specific JMS broker.
abstract  javax.jms.QueueSession getQueueSession()
          Provides a QueueSession instance.
protected  void initConnection()
          Initializes the JMS connection.
abstract  void onException(javax.jms.JMSException e)
          Exceptionhandler for the JMSConnection.
protected  void reconnect()
          Do a reconnect to the JMSbroker.
 void removeListener(ChannelID mq, javax.jms.MessageListener ml)
          Removes the specified MessageListener from the given queue or topic.
 void reply(NetarkivetMessage msg)
          Submit an object to the reply queue.
 void resend(NetarkivetMessage msg, ChannelID to)
          Sends a message msg to the channel defined by the parameter to - NOT the channel defined in the message.
 void send(NetarkivetMessage msg)
          Submit an object to the destination queue.
protected  void sendMessage(NetarkivetMessage nMsg, ChannelID to)
          Submit an ObjectMessage to the destination channel.
 void setListener(ChannelID mq, javax.jms.MessageListener ml)
          Method adds a listener to the given queue or topic.
static NetarkivetMessage unpack(javax.jms.Message msg)
          Unwraps a NetarkivetMessage from an ObjectMessage.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CONSUMER_KEY_SEPARATOR

protected static final java.lang.String CONSUMER_KEY_SEPARATOR
Separator used in the consumer key. Separates the ChannelName from the MessageListener.toString().

See Also:
Constant Field Values

JMS_MAXTRIES

static final int JMS_MAXTRIES
The number to times to (re)try whenever a JMSException is thrown.


connection

protected javax.jms.Connection connection
The JMS Connection.


session

protected javax.jms.Session session
The Session handling messages sent to / received from the NetarchiveSuite queues and topics.


producers

protected final java.util.Map<java.lang.String,javax.jms.MessageProducer> producers
Map for caching message producers.


consumers

protected final java.util.Map<java.lang.String,javax.jms.MessageConsumer> consumers
Map for caching message consumers (topic-subscribers and queue-receivers).


listeners

protected final java.util.Map<java.lang.String,javax.jms.MessageListener> listeners
Map for caching message listeners (topic-subscribers and queue-receivers).


connectionLock

protected final java.util.concurrent.locks.ReentrantReadWriteLock connectionLock
Lock for the connection. Locked for read on adding/removing listeners and sending messages. Locked for write when connection, releasing and reconnecting.


closeHook

protected java.lang.Thread closeHook
Shutdown hook that closes the JMS connection.


instance

protected static JMSConnection instance
Singleton pattern is be used for this class. This is the one and only instance.

Constructor Detail

JMSConnection

protected JMSConnection()
Class constructor.

Method Detail

getConnectionFactory

protected abstract javax.jms.ConnectionFactory getConnectionFactory()
                                                             throws javax.jms.JMSException
Should be implemented according to a specific JMS broker.

Returns:
QueueConnectionFactory
Throws:
javax.jms.JMSException - If unable to get QueueConnectionFactory

getDestination

protected abstract javax.jms.Destination getDestination(java.lang.String destinationName)
                                                 throws javax.jms.JMSException
Should be implemented according to a specific JMS broker.

Parameters:
destinationName - the name of the wanted Queue
Returns:
The destination. Note that the implementation should make sure that this is a Queue or a Topic, as required by the NetarchiveSuite design. Channels.isTopic(String)
Throws:
javax.jms.JMSException - If unable to get a destination.

onException

public abstract void onException(javax.jms.JMSException e)
Exceptionhandler for the JMSConnection. Implemented according to a specific JMS broker. Should try to reconnect if at all possible.

Specified by:
onException in interface javax.jms.ExceptionListener
Parameters:
e - a JMSException

initConnection

protected void initConnection()
                       throws IOFailure
Initializes the JMS connection. Creates and starts connection and session. Adds a shutdown hook that closes down JMSConnection. Adds this object as ExceptionListener for the connection.

Throws:
IOFailure - if initialization fails.

send

public final void send(NetarkivetMessage msg)
Submit an object to the destination queue. This method cannot be overridden. Override the method sendMessage to change functionality.

Parameters:
msg - The NetarkivetMessage to send to the destination queue (null not allowed)
Throws:
ArgumentNotValid - if nMsg is null.
IOFailure - if the operation failed.

resend

public final void resend(NetarkivetMessage msg,
                         ChannelID to)
Sends a message msg to the channel defined by the parameter to - NOT the channel defined in the message.

Parameters:
msg - Message to be sent
to - The destination channel

reply

public final void reply(NetarkivetMessage msg)
Submit an object to the reply queue.

Parameters:
msg - The NetarkivetMessage to send to the reply queue (null not allowed)
Throws:
ArgumentNotValid - if nMsg is null.
PermissionDenied - if message nMsg has not been sent yet.
IOFailure - if unable to reply.

setListener

public void setListener(ChannelID mq,
                        javax.jms.MessageListener ml)
                 throws IOFailure
Method adds a listener to the given queue or topic.

Parameters:
mq - the messagequeue to listen to
ml - the messagelistener
Throws:
IOFailure - if the operation failed.

removeListener

public void removeListener(ChannelID mq,
                           javax.jms.MessageListener ml)
                    throws IOFailure
Removes the specified MessageListener from the given queue or topic.

Parameters:
mq - the given queue or topic
ml - a messagelistener
Throws:
IOFailure - On network trouble

createQueueBrowser

public javax.jms.QueueBrowser createQueueBrowser(ChannelID queueID)
                                          throws javax.jms.JMSException
Creates a QueueBrowser object to peek at the messages on the specified queue.

Parameters:
queueID - The ChannelID for a specified queue.
Returns:
A new QueueBrowser instance with access to the specified queue
Throws:
javax.jms.JMSException - If unable to create the specified queue browser

getQueueSession

public abstract javax.jms.QueueSession getQueueSession()
                                                throws javax.jms.JMSException
Provides a QueueSession instance. Functionality for retrieving a QueueSession object isen't available on the generic JMSConnectionFactory

Returns:
A QueueSession object connected to the current JMS broker
Throws:
javax.jms.JMSException - Failure to retrieve the QueueBrowser JMS Browser

cleanup

public void cleanup()
Clean up. Remove close connection, remove shutdown hook and null the instance.

Specified by:
cleanup in interface CleanupIF

unpack

public static NetarkivetMessage unpack(javax.jms.Message msg)
                                throws ArgumentNotValid
Unwraps a NetarkivetMessage from an ObjectMessage.

Parameters:
msg - a javax.jms.ObjectMessage
Returns:
a NetarkivetMessage
Throws:
ArgumentNotValid - when msg in valid or format of JMS Object message is invalid

sendMessage

protected void sendMessage(NetarkivetMessage nMsg,
                           ChannelID to)
                    throws IOFailure
Submit an ObjectMessage to the destination channel.

Parameters:
nMsg - the NetarkivetMessage to be wrapped and send as an ObjectMessage
to - the destination channel
Throws:
IOFailure - if message failed to be sent.

reconnect

protected void reconnect()
Do a reconnect to the JMSbroker. Does absolutely nothing, if already in the process of reconnecting.


getConsumerKey

protected static java.lang.String getConsumerKey(java.lang.String channel,
                                                 javax.jms.MessageListener messageListener)
Generate a consumerkey based on the given channel name and messageListener.

Parameters:
channel - Channel name
messageListener - a messageListener
Returns:
the generated consumerkey.