dk.i1.diameter.node
Class NodeManager

Object
  extended by dk.i1.diameter.node.NodeManager
All Implemented Interfaces:
ConnectionListener, MessageDispatcher
Direct Known Subclasses:
SessionManager, SimpleSyncClient

public class NodeManager
extends Object
implements MessageDispatcher, ConnectionListener

A Node manager. The NodeManager class manages a Node instance and keeps track of connections and in-/our-going messages and their end-to-end and hop-by-hop identifiers. You can build proxies, redirect agents, servers and clients on top of it. NodeManager is meant to be subclassed and subclasses should override handleRequest() and handleAnswer()

If your needs are even simpler then have a look at SimpleSyncClient and SessionManager

NodeManager instances logs with the name "dk.i1.diameter.node", so you can get detailed logging (including hex-dumps of incoming and outgoing packets) by putting "dk.i1.diameter.node.level = ALL" into your log.properties file (or equivalent)

What happens when acting as a server:

  1. The Node instance receives a message (request)
  2. The message is passed to handleRequest()
  3. handleRequest() processes the message (this is where your code is meant to be)
  4. handleRequest() creates an answer message. Among other things it uses Message.prepareAnswer(Message)
  5. answer() is called
  6. The answer is passed down to the Node instance which then sends or queues the message

What happens when acting as a client:

  1. sendRequest(Message,Peer[],Object) is called
  2. The request is passed down to the Node instance which sends or queues it
  3. The sendRequest() call returns
  4. Some time passesThe Node instance receives the answer
  5. The answer is passed to handleAnswer(). This is where your code is meant to be)

What happens when acting as a proxy or a relay:

  1. The Node instance receives a message (request)
  2. The message is passed to handleRequest()
  3. Your implementation of handleRequest() decides to forward the request
  4. forwardRequest() is called with a state object that among other things remembers the ConnectionKey and the hop-by-hop identifier
  5. The request is passed down to the Node instance which sends or queues it
  6. The forwardRequest() call returns
  7. The handleRequest() returns
  8. Some time passes
  9. The Node instance receives the answer
  10. The answer is passed to handleAnswer(). This is where your code is meant to be)
  11. Your code detects that the answer must be forward back to where the request came from.
  12. Your code restores the hop-by-hop identifier
  13. forwardAnswer() is called.
  14. The answer is passed down to the Node instance which then sends or queues the message


Constructor Summary
NodeManager(NodeSettings settings)
          Constructor for NodeManager.
NodeManager(NodeSettings settings, NodeValidator node_validator)
          Constructor for NodeManager.
 
Method Summary
protected  void answer(Message answer, ConnectionKey connkey)
          Answer a request.
protected  void forwardAnswer(Message answer, ConnectionKey connkey)
          Forward an answer.
protected  void forwardRequest(Message request, ConnectionKey connkey, Object state)
          Forward a request.
protected  void forwardRequest(Message request, ConnectionKey connkey, Object state, long timeout)
          Forward a request.
 void handle(ConnectionKey connkey, Peer peer, boolean up)
          Handle a a connection state change.
 boolean handle(Message msg, ConnectionKey connkey, Peer peer)
          Handle an incoming message.
protected  void handleAnswer(Message answer, ConnectionKey answer_connkey, Object state)
          Handle an answer.
protected  void handleRequest(Message request, ConnectionKey connkey, Peer peer)
          Handle a request.
 Node node()
          Returns the embedded node
 void sendRequest(Message request, ConnectionKey connkey, Object state)
          Sends a request.
 void sendRequest(Message request, ConnectionKey connkey, Object state, long timeout)
          Sends a request.
 void sendRequest(Message request, Peer[] peers, Object state)
          Sends a request.
 void sendRequest(Message request, Peer[] peers, Object state, long timeout)
          Sends a request.
 NodeSettings settings()
          Returns the node settings
 void start()
          Start the node manager.
 void stop()
          Stop the node manager immediately.
 void stop(long grace_time)
          Stop the node manager.
 void waitForConnection()
          Wait until at least one connection has been established.
 void waitForConnection(long timeout)
          Wait until at least one connection has been established or until the timeout expires.
 void waitForConnectionTimeout(long timeout)
          Wait until at least one connection has been established or until the timeout expires.
 
Methods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

NodeManager

public NodeManager(NodeSettings settings)
Constructor for NodeManager. A Node instance is constructed using the specified settings, and the internal state is initialized.


NodeManager

public NodeManager(NodeSettings settings,
                   NodeValidator node_validator)
Constructor for NodeManager. A Node instance is constructed using the specified settings, node validator (can be null) and the internal state is initialized.

Since:
0.9.4
Method Detail

start

public void start()
           throws java.io.IOException,
                  UnsupportedTransportProtocolException
Start the node manager. Starts the embedded Node. For details about UnsupportedTransportProtocolException see Node.start()

Throws:
java.io.IOException
UnsupportedTransportProtocolException

stop

public void stop()
Stop the node manager immediately. Implemented as stop(0)


stop

public void stop(long grace_time)
Stop the node manager. Stops the embedded Node and call handleAnswer() with null messages for outstanding requests.

Parameters:
grace_time - Maximum time (milliseconds) to wait for connections to close gracefully.
Since:
grace_time parameter introduced in 0.9.3

waitForConnection

public void waitForConnection()
                       throws InterruptedException
Wait until at least one connection has been established. Waits until at least one connection to a peer has been established and capability-exchange has finished.

Throws:
InterruptedException
Since:
0.9.1

waitForConnection

public void waitForConnection(long timeout)
                       throws InterruptedException
Wait until at least one connection has been established or until the timeout expires. Waits until at least one connection to a peer has been established and capability-exchange has finished, or the specified timeout has expired.

Parameters:
timeout - The maximum time to wait in milliseconds.
Throws:
InterruptedException
Since:
0.9.1

waitForConnectionTimeout

public void waitForConnectionTimeout(long timeout)
                              throws InterruptedException,
                                     ConnectionTimeoutException
Wait until at least one connection has been established or until the timeout expires. Waits until at least one connection to a peer has been established and capability-exchange has finished, or the specified timeout has expired. If the timeout expires then a InterruptedException is thrown.

Parameters:
timeout - The maximum time to wait in milliseconds.
Throws:
InterruptedException - If the timeout expires without any connection established.
ConnectionTimeoutException
Since:
0.9.6.5

node

public Node node()
Returns the embedded node


settings

public NodeSettings settings()
Returns the node settings


handleRequest

protected void handleRequest(Message request,
                             ConnectionKey connkey,
                             Peer peer)
Handle a request. This method is called when a request arrives. It is meant to be overridden by a subclass. This implementation rejects all requests.

Please note that the handleRequest() method is called by the networking thread and messages from other peers cannot be received until the method returns. If the handleRequest() method needs to do any lengthy processing then it should implement a message queue, put the message into the queue, and return. The requests can then be processed by a worker thread pool without stalling the networking layer.

Parameters:
request - The incoming request.
connkey - The connection from where the request came.
peer - The peer that sent the request. This is not the originating peer but the peer directly connected to us that sent us the request.

handleAnswer

protected void handleAnswer(Message answer,
                            ConnectionKey answer_connkey,
                            Object state)
Handle an answer. This method is called when an answer arrives. It is meant to be overridden in a subclass.

Please note that the handleAnswer() method is called by the networking thread and messages from other peers cannot be received until the method returns. If the handleAnswer() method needs to do any lengthy processing then it should implement a message queue, put the message into the queue, and return. The answers can then be processed by a worker thread pool without stalling the networking layer.

Parameters:
answer - The answer message. Null if the connection broke.
answer_connkey - The connection from where the answer came.
state - The state object passed to sendRequest() or forwardRequest()

answer

protected final void answer(Message answer,
                            ConnectionKey connkey)
                     throws NotAnAnswerException
Answer a request. The answer is sent to the connection. If the connection has been lost in the meantime it is ignored.

Parameters:
answer - The answer message.
connkey - The connection to send the answer to.
Throws:
NotAnAnswerException - If the answer has the R bit set in the header.

forwardRequest

protected final void forwardRequest(Message request,
                                    ConnectionKey connkey,
                                    Object state)
                             throws StaleConnectionException,
                                    NotARequestException,
                                    NotProxiableException
Forward a request. Forward the request to the specified connection. The request will automatically get a route-record added if not already present. This method is meant to be called from handleRequest().

Parameters:
request - The request to forward
connkey - The connection to use
state - A state object that will be passed to handleAnswer() when the answer arrives. You should remember the ingoing connection and hop-by-hop identifier
Throws:
NotARequestException - If the request does not have the R bit set in the header.
NotProxiableException - If the request does not have the P bit set in the header.
StaleConnectionException - If the ConnectionKey refers to a lost connection.

forwardRequest

protected final void forwardRequest(Message request,
                                    ConnectionKey connkey,
                                    Object state,
                                    long timeout)
                             throws StaleConnectionException,
                                    NotARequestException,
                                    NotProxiableException
Forward a request. Forward the request to the specified connection. The request will automatically get a route-record added if not already present. This method is meant to be called from handleRequest().

Parameters:
request - The request to forward
connkey - The connection to use
state - A state object that will be passed to handleAnswer() when the answer arrives. You should remember the ingoing connection and hop-by-hop identifier
timeout - Timeout in milliseconds, -1 means no timeout
Throws:
NotARequestException - If the request does not have the R bit set in the header.
NotProxiableException - If the request does not have the P bit set in the header.
StaleConnectionException - If the ConnectionKey refers to a lost connection.
Since:
0.9.6.8 timeout parameter introduced

forwardAnswer

protected final void forwardAnswer(Message answer,
                                   ConnectionKey connkey)
                            throws StaleConnectionException,
                                   NotAnAnswerException,
                                   NotProxiableException
Forward an answer. Forward the answer to to the specified connection. The answer will automatically get a route-record added. This method is meant to be called from handleAnswer(). Remember to restore the hop-by-hop-identifier on the message before calling this function.

Parameters:
answer - The answer to forward
connkey - The connection to use
Throws:
NotAnAnswerException - If the answer has the R bit set in the header.
NotProxiableException - If the answer does not have the P bit set in the header. This indicates that there is something completely wrong with either the message, the peer or your application
StaleConnectionException - If the ConnectionKey refers to a lost connection.

sendRequest

public final void sendRequest(Message request,
                              ConnectionKey connkey,
                              Object state)
                       throws StaleConnectionException,
                              NotARequestException
Sends a request. A request initiated by this node is sent to the specified connection. The hop-by-hop identifier of the message is set. This is not symmetric with the other sendRequest method.

Parameters:
request - The request.
connkey - The connection to use.
state - A state object that will be passed to handleAnswer() when the answer arrives.
Throws:
NotARequestException - If the request does not have the R bit set in the header.
StaleConnectionException - If the ConnectionKey refers to a lost connection.

sendRequest

public final void sendRequest(Message request,
                              ConnectionKey connkey,
                              Object state,
                              long timeout)
                       throws StaleConnectionException,
                              NotARequestException
Sends a request. A request initiated by this node is sent to the specified connection. The hop-by-hop identifier of the message is set. This is not symmetric with the other sendRequest method.

Parameters:
request - The request.
connkey - The connection to use.
state - A state object that will be passed to handleAnswer() when the answer arrives.
timeout - Timeout in milliseconds, -1 means no timeout
Throws:
NotARequestException - If the request does not have the R bit set in the header.
StaleConnectionException - If the ConnectionKey refers to a lost connection.
Since:
0.9.6.8 timeout parameter introduced

sendRequest

public final void sendRequest(Message request,
                              Peer[] peers,
                              Object state)
                       throws NotRoutableException,
                              NotARequestException
Sends a request. The request is sent to one of the peers and an optional state object is remembered. Please note that handleAnswer() for this request may get called before this method returns. This can happen if the peer is very fast and the OS thread scheduler decides to schedule the networking thread. The end-to-end identifier of the message is set. This is not symmetric with the other sendRequest method.

Parameters:
request - The request to send.
peers - The candidate peers
state - A state object to be remembered. This will be passed to the handleAnswer() method when the answer arrives.
Throws:
NotARequestException - If the request does not have the R bit set in the header.
NotRoutableException - If the message could not be sent to any of the peers.

sendRequest

public final void sendRequest(Message request,
                              Peer[] peers,
                              Object state,
                              long timeout)
                       throws NotRoutableException,
                              NotARequestException
Sends a request. The request is sent to one of the peers and an optional state object is remembered. Please note that handleAnswer() for this request may get called before this method returns. This can happen if the peer is very fast and the OS thread scheduler decides to schedule the networking thread. The end-to-end identifier of the message is set. This is not symmetric with the other sendRequest method.

Parameters:
request - The request to send.
peers - The candidate peers
state - A state object to be remembered. This will be passed to the handleAnswer() method when the answer arrives.
timeout - Timeout in milliseconds, -1 means no timeout
Throws:
NotARequestException - If the request does not have the R bit set in the header.
NotRoutableException - If the message could not be sent to any of the peers.
Since:
0.9.6.8 timeout parameter introduced

handle

public final boolean handle(Message msg,
                            ConnectionKey connkey,
                            Peer peer)
Handle an incoming message. This implementation calls handleRequest(), or matches an answer to an outstanding request and calls handleAnswer(). Subclasses should not override this method.

Specified by:
handle in interface MessageDispatcher
Parameters:
msg - The incoming message
connkey - The connection key
peer - The peer of the connection. This is not necessarily the host that originated the message (the message can have gone via proxies)
Returns:
True if the message was processed. False otherwise, in which case the Node will respond with a error to the peer (if the message was a request).

handle

public final void handle(ConnectionKey connkey,
                         Peer peer,
                         boolean up)
Handle a a connection state change. If the connection has been lost this implementation calls handleAnswer(null,...) for outstanding requests on the connection. Subclasses should not override this method.

Specified by:
handle in interface ConnectionListener
Parameters:
connkey - The connection key.
peer - The peer the connection is to.
up - True if the connection has been established. False if the connection has been lost.