public class AMQProtocolHandler extends Object implements ProtocolEngine
There is a 1:1 mapping between an AMQProtocolHandler and an AMQConnection. The connection class is
exposed to the end user of the AMQP client API, and also implements the JMS Connection API, so provides the public
API calls through which an individual connection can be manipulated. This protocol handler talks to the network
through MINA, in a behind the scenes role; it is not an exposed part of the client API.
There is a 1:many mapping between an AMQProtocolHandler and a set of AMQSessions. At the MINA level,
there is one session per connection. At the AMQP level there can be many channels which are also called sessions in
JMS parlance. The AMQSessions are managed through an AMQProtocolSession instance. The protocol
session is similar to the MINA per-connection session, except that it can span the lifecycle of multiple MINA sessions
in the event of failover. See below for more information about this.
Mina provides a session container that can be used to store/retrieve arbitrary objects as String named
attributes. A more convenient, type-safe, container for session data is provided in the form of
AMQProtocolSession.
A common way to use MINA is to have a single instance of the event handler, and for MINA to pass in its session object with every event, and for per-connection data to be held in the MINA session (perhaps using a type-safe wrapper as described above). This event handler is different, because dealing with failover complicates things. To the end client of an AMQConnection, a failed over connection is still handled through the same connection instance, but behind the scenes a new transport connection, and MINA session will have been created. The MINA session object cannot be used to track the state of the fail-over process, because it is destroyed and a new one is created, as the old connection is shutdown and a new one created. For this reason, an AMQProtocolHandler is created per AMQConnection and the protocol session data is held outside of the MINA IOSession.
This handler is responsible for setting up the filter chain to filter all events for this handler through. The filter chain is set up as a stack of event handers that perform the following functions (working upwards from the network traffic at the bottom), handing off incoming events to an asynchronous thread pool to do the work, optionally handling secure sockets encoding/decoding, encoding/decoding the AMQP format itself.
TODO Use a single handler instance, by shifting everything to do with the 'protocol session' state, including failover state, into AMQProtocolSession, and tracking that from AMQConnection? The lifecycles of AMQProtocolSesssion and AMQConnection will be the same, so if there is high cohesion between them, they could be merged, although there is sense in keeping the session model separate. Will clarify things by having data held per protocol handler, per protocol session, per network connection, per channel, in separate classes, so that lifecycles of the fields match lifecycles of their containing objects.
| Constructor and Description |
|---|
AMQProtocolHandler(AMQConnection con)
Creates a new protocol handler, associated with the specified client connection instance.
|
| Modifier and Type | Method and Description |
|---|---|
void |
blockUntilNotFailingOver() |
void |
closeConnection(long timeout)
Closes the connection.
|
void |
closed()
Called when the network connection is closed.
|
void |
closeSession(AMQSession session) |
StateWaiter |
createWaiter(Set<AMQState> states) |
void |
exception(Throwable cause)
Invoked when any exception is thrown by the NetworkDriver
|
void |
failover(String host,
int port) |
void |
failoverInProgress() |
AMQShortString |
generateQueueName() |
AMQConnection |
getConnection() |
CountDownLatch |
getFailoverLatch() |
long |
getLastReadTime() |
long |
getLastWriteTime() |
SocketAddress |
getLocalAddress() |
MethodRegistry |
getMethodRegistry() |
NetworkConnection |
getNetworkConnection() |
byte |
getProtocolMajorVersion() |
byte |
getProtocolMinorVersion() |
AMQProtocolSession |
getProtocolSession() |
ProtocolVersion |
getProtocolVersion() |
long |
getReadBytes() |
SocketAddress |
getRemoteAddress() |
protected Sender<ByteBuffer> |
getSender() |
AMQStateManager |
getStateManager() |
ProtocolVersion |
getSuggestedProtocolVersion() |
long |
getWrittenBytes() |
void |
heartbeatBodyReceived() |
void |
methodBodyReceived(int channelId,
AMQBody bodyFrame) |
void |
notifyFailoverStarting() |
void |
propagateExceptionToAllWaiters(Exception e)
There are two cases where we have other threads potentially blocking for events to be handled by this class.
|
void |
propagateExceptionToFrameListeners(Exception e)
This caters for the case where we only need to propagate an exception to the the frame listeners to interupt any
protocol level waits.
|
void |
readerIdle() |
void |
received(ByteBuffer msg) |
void |
setFailoverLatch(CountDownLatch failoverLatch) |
void |
setFailoverState(FailoverState failoverState) |
void |
setHeartbeatListener(HeartbeatListener listener) |
void |
setMaxFrameSize(long frameMax) |
void |
setNetworkConnection(NetworkConnection network) |
void |
setNetworkConnection(NetworkConnection network,
Sender<ByteBuffer> sender) |
void |
setStateManager(AMQStateManager stateManager) |
AMQMethodEvent |
syncWrite(AMQFrame frame,
Class responseClass)
More convenient method to write a frame and wait for it's response.
|
AMQMethodEvent |
syncWrite(AMQFrame frame,
Class responseClass,
long timeout)
More convenient method to write a frame and wait for it's response.
|
AMQMethodEvent |
writeCommandFrameAndWaitForReply(AMQFrame frame,
BlockingMethodFrameListener listener)
Convenience method that writes a frame to the protocol session and waits for a particular response.
|
AMQMethodEvent |
writeCommandFrameAndWaitForReply(AMQFrame frame,
BlockingMethodFrameListener listener,
long timeout)
Convenience method that writes a frame to the protocol session and waits for a particular response.
|
void |
writeFrame(AMQDataBlock frame) |
void |
writeFrame(AMQDataBlock frame,
boolean flush) |
void |
writerIdle() |
public AMQProtocolHandler(AMQConnection con)
con - The client connection that this is the event handler for.public void closed()
TODO Clarify: presumably exceptionCaught is called when the client is sending during a connection failure and not otherwise? The above comment doesn't make that clear.
closed in interface ProtocolEngineclosed in interface Receiver<ByteBuffer>public void readerIdle()
readerIdle in interface ProtocolEnginereaderIdle in interface TransportActivitypublic void writerIdle()
writerIdle in interface ProtocolEnginewriterIdle in interface TransportActivitypublic void exception(Throwable cause)
exception in interface Receiver<ByteBuffer>public void propagateExceptionToAllWaiters(Exception e)
e - the exception to propagatepropagateExceptionToFrameListeners(java.lang.Exception)public void propagateExceptionToFrameListeners(Exception e)
FailoverHandler.
Once the FailoverHandler has re-established the connection then the listeners will be able to re-attempt
their protocol request and so listen again for the correct frame.e - the exception to propagatepublic void notifyFailoverStarting()
public void failoverInProgress()
public void received(ByteBuffer msg)
received in interface Receiver<ByteBuffer>public void methodBodyReceived(int channelId,
AMQBody bodyFrame)
throws AMQException
AMQExceptionpublic StateWaiter createWaiter(Set<AMQState> states) throws AMQException
AMQExceptionpublic void writeFrame(AMQDataBlock frame)
public void writeFrame(AMQDataBlock frame, boolean flush)
public AMQMethodEvent writeCommandFrameAndWaitForReply(AMQFrame frame, BlockingMethodFrameListener listener) throws AMQException, FailoverException
frame - listener - the blocking listener. Note the calling thread will block.AMQExceptionFailoverExceptionpublic AMQMethodEvent writeCommandFrameAndWaitForReply(AMQFrame frame, BlockingMethodFrameListener listener, long timeout) throws AMQException, FailoverException
frame - listener - the blocking listener. Note the calling thread will block.AMQExceptionFailoverExceptionpublic AMQMethodEvent syncWrite(AMQFrame frame, Class responseClass) throws AMQException, FailoverException
AMQExceptionFailoverExceptionpublic AMQMethodEvent syncWrite(AMQFrame frame, Class responseClass, long timeout) throws AMQException, FailoverException
AMQExceptionFailoverExceptionpublic void closeSession(AMQSession session) throws AMQException
AMQExceptionpublic void closeConnection(long timeout)
throws AMQException
If a failover exception occurs whilst closing the connection it is ignored, as the connection is closed anyway.
timeout - The timeout to wait for an acknowledgment to the close request.AMQException - If the close fails for any reason.public long getReadBytes()
getReadBytes in interface ProtocolEnginepublic long getWrittenBytes()
getWrittenBytes in interface ProtocolEnginepublic void failover(String host, int port)
public void blockUntilNotFailingOver()
throws InterruptedException
InterruptedExceptionpublic AMQShortString generateQueueName()
public CountDownLatch getFailoverLatch()
public void setFailoverLatch(CountDownLatch failoverLatch)
public AMQConnection getConnection()
public AMQStateManager getStateManager()
public void setStateManager(AMQStateManager stateManager)
public AMQProtocolSession getProtocolSession()
public void setFailoverState(FailoverState failoverState)
public byte getProtocolMajorVersion()
public byte getProtocolMinorVersion()
public MethodRegistry getMethodRegistry()
public ProtocolVersion getProtocolVersion()
public SocketAddress getRemoteAddress()
getRemoteAddress in interface ProtocolEnginepublic SocketAddress getLocalAddress()
getLocalAddress in interface ProtocolEnginepublic void setNetworkConnection(NetworkConnection network)
public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender)
setNetworkConnection in interface ProtocolEnginepublic long getLastReadTime()
getLastReadTime in interface TransportActivitypublic long getLastWriteTime()
getLastWriteTime in interface TransportActivityprotected Sender<ByteBuffer> getSender()
public NetworkConnection getNetworkConnection()
public ProtocolVersion getSuggestedProtocolVersion()
public void setHeartbeatListener(HeartbeatListener listener)
public void heartbeatBodyReceived()
public void setMaxFrameSize(long frameMax)
Copyright © 2006–2014 The Apache Software Foundation. All rights reserved.