public final class RouterSessionManager extends SessionManager
SessionManager
which have behavior specific to a router node, such as security context
management, virtual session multiplexing and management, integration with
the node's router, and server-side socket connection handling.
An inner class manages new, incoming socket connections, creating a new message transport queue for each. These resources are likewise cleaned up when each connection is finished.
This class is not instantiated directly. A singleton instance is created
using the SessionManagerFactory.createRouterNode(BootstrapConfig)
factory method. This instance is later retrieved with SessionManager.get()
.
Modifier and Type | Class and Description |
---|---|
private static class |
RouterSessionManager.Incoming
This class performs all long running tasks with an incoming connection,
such as authentication and queue initialization.
|
Modifier and Type | Field and Description |
---|---|
private java.util.Set<java.net.InetAddress> |
allHosts
All host addresses on all network interfaces for the local machine.
|
private static java.lang.ThreadGroup |
connThreads
Thread group for the connection threads.
|
private static java.util.Map<Queue,RouterSessionManager.Incoming> |
incomingMap
Map of queues to contexts pending direct session creation.
|
private java.net.ServerSocket |
insecure
Server socket upon which all INSECURE client connections arrive.
|
private java.util.concurrent.CountDownLatch |
ready
Signals when the network portions of the server are ready.
|
private javax.net.ssl.SSLServerSocket |
secure
Server socket upon which all secure client connections arrive.
|
private boolean |
shutdown
Shutdown flag.
|
activeSession, addressUseCount, appServers, config, identityByQueue, lock, LOG, secMgr, sessionsByQueue, shutdownDone, topology, virtualControlByContext, virtualLocksByQueue, virtualSessionsByContext
Constructor and Description |
---|
RouterSessionManager()
Constructor which enforces the singleton pattern.
|
Modifier and Type | Method and Description |
---|---|
(package private) java.lang.Object |
abortSessionInit(Queue queue)
Cleanup session state before initialization.
|
int |
authenticateRemote(java.lang.String identity,
int peerID,
Queue queue)
Called by a requester to authenticate a virtual session.
|
Session |
connectVirtual(BootstrapConfig config,
SessionListener notify)
Establish a virtual (multiplexed) connection to a network node at the
given address.
|
Session |
connectVirtual(java.net.InetSocketAddress address,
java.lang.String certAlias,
SessionListener notify,
java.lang.String account)
Establish a virtual (multiplexed) connection to a network node at the
given address.
|
protected boolean |
createDirectSession(Queue queue)
Create a direct session for the given queue and register it with the
session manager.
|
private java.net.ServerSocket |
createServerSocket(boolean isSecure,
int port)
|
protected boolean |
deregisterSession(BaseSession session)
Deregister a session with the session manager.
|
protected void |
dropInitialContext()
Release the initial security context assigned to the calling thread.
|
javax.net.ssl.SSLServerSocket |
getSSLSocket()
Expose the SSLServerSocket so the port and other parameters
used by the socket can be exposed to logic outside this class
|
protected void |
init()
Perform any special initialization which is not handled by the default
(common) logic.
|
boolean |
isLocalNode(java.net.InetSocketAddress address)
Convenience method to detect whether the given socket address represents
the current node.
|
boolean |
isRouter()
Convenience method to detect whether this session manager operates on a
router node.
|
void |
listen(SessionListener notify)
Listen for incoming socket connections, authenticate each new
connection, and establish a new queue for each authenticated connection.
|
private void |
listenWorker(SessionListener notify,
java.net.ServerSocket input,
java.lang.String logtxt)
Core listening loop for incoming socket connections.
|
protected void |
restoreContext()
Restore the current thread's security context to whatever it was before
it was last explicitly set.
|
protected void |
setContext(BaseSession session)
Set the security context for the current thread, using the security
context stored in the given session.
|
protected void |
setContext(Queue queue)
Set the security context for the current thread, using the session
identified by the given queue.
|
protected void |
setContext(RoutingKey key,
Queue queue)
Set the security context for the current thread, using the session
identified by the given routing key or transport queue.
|
protected void |
setInitialContext()
Initialize security context switching for the calling thread.
|
protected void |
terminateInput()
Close the server's socket if it was ever initialized.
|
void |
terminateRemote(int contextID)
Called by a requester to terminate a virtual session.
|
java.lang.String |
toString()
Return a string representation of the internal state of this object,
primarily for debugging purposes.
|
void |
waitUntilReady()
Block the calling thread until the network portions of the server are fully initialized.
|
callAuthenticateRemote, config, connectDirect, connectDirect, connectVirtual, createQueue, deregisterAsyncThread, endSession, executeInContext, get, getAppServer, getInterruptHandler, getNodeAddress, getRemoteAddress, getSecurityPlugin, getSession, getSessionContexts, initialize, isAsyncThread, isLeaf, isVirtualSession, nextContextID, notifyTermination, processEcho, queueStopped, registerAsyncThread, registerSession, setInterruptHandler, shutdown, terminateSessions, terminateVirtual, waitForShutdown
private static final java.lang.ThreadGroup connThreads
private static final java.util.Map<Queue,RouterSessionManager.Incoming> incomingMap
private javax.net.ssl.SSLServerSocket secure
private java.net.ServerSocket insecure
private java.util.Set<java.net.InetAddress> allHosts
private boolean shutdown
private java.util.concurrent.CountDownLatch ready
RouterSessionManager()
java.lang.IllegalStateException
- if called more than once per JVM instance.java.lang.NullPointerException
- if config
is null
.public javax.net.ssl.SSLServerSocket getSSLSocket()
SSLServerSocket
.public boolean isRouter()
isRouter
in class SessionManager
true
.public boolean isLocalNode(java.net.InetSocketAddress address)
isLocalNode
in class SessionManager
address
- Socket address to check.true
if an address match is detected, else
false
.public Session connectVirtual(java.net.InetSocketAddress address, java.lang.String certAlias, SessionListener notify, java.lang.String account) throws java.lang.Exception
This method is called by the requester side to establish a virtual session. The first time it must connect to a particular destination, a message transport queue is established. This requires authentication between two router nodes, which is the first level of a two-level authentication process. Thereafter, requests for additional sessions with that endpoint use the existing queue, and communications are multiplexed by context ID.
Once a transport is available, the current user's account identifier is
used to authenticate at the remote node. This user authentication
represents the second level of authentication. On the remote side, if
authentication is successful (the account must be registered under the
same ID on the remote side, and have sufficient rights to authenticate),
the other "half" of the virtual session is established on the remote
side. A unique context ID is assigned to that session and is returned
to the requester. This context ID is used to establish a virtual
session (RequesterSession
) on this side. This ID is later used
in outbound messages to multiplex communications over the shared queue.
This method creates an in-memory BootstrapConfig
object to
enable the first level of authentication, which is certificate-based.
Configuration entries are populated as follows (note that some values
are retrieved from the BootstrapConfig
instance set by
SessionManager.initialize(BootstrapConfig)
; this version of the
configuration is referred to below as the default config):
address
parameter
address
parameter
true
only if
certAlias
is non-null
, otherwise is left
unset, which defaults to false
with the security
manager; if true
, forces certificate-based
validation of the providing server
certAlias
parameter, if that parameter is non-null
, otherwise
is left unset; this is necessary to allow the security manager to
check the correct truststore for the providing server, if
certification-based validation of the providing server is desired
connectVirtual
in class SessionManager
address
- Socket address of remote network node.certAlias
- Alias of certificate to be read from trust store to enable
certificate-based, server-to-server authentication. This
should match the server ID of the remote node. May be
null
, which indicates requesting server does not
validate providing server's certificate.notify
- Session listener to be notified of session events.account
- Explicit account to authenticate on the remote side. May be null
.java.lang.Exception
- if there are any errors reading configuration, creating a
queue, or authenticating the user session remotely.public Session connectVirtual(BootstrapConfig config, SessionListener notify) throws java.lang.Exception
This method is called by the requester side to establish a virtual session. The first time it must connect to a particular destination, a message transport queue is established. This requires authentication between two router nodes, which is the first level of a two-level authentication process. Thereafter, requests for additional sessions with that endpoint use the existing queue, and communications are multiplexed by context ID.
Once a transport is available, the current user's account identifier is
used to authenticate at the remote node. This user authentication
represents the second level of authentication. On the remote side, if
authentication is successful (the account must be registered under the
same ID on the remote side, and have sufficient rights to authenticate),
the other "half" of the virtual session is established on the remote
side. A unique context ID is assigned to that session and is returned
to the requester. This context ID is used to establish a virtual
session (RequesterSession
) on this side. This ID is later used
in outbound messages to multiplex communications over the shared queue.
This method is synchronized so, if multiple clients are calling this method, only one of them will create the connection.
connectVirtual
in class SessionManager
config
- Bootstrap configuration information which contains at least
enough information to make a virtual connection from this node
to another. See connectVirtual(BootstrapConfig, SessionListener)
for details.notify
- Session listener to be notified of session events.java.lang.Exception
- if there are any errors reading configuration, creating a
queue, or authenticating the user session remotely.public void waitUntilReady() throws java.lang.InterruptedException
waitUntilReady
in class SessionManager
java.lang.InterruptedException
public void listen(SessionListener notify) throws java.lang.Exception
Depending on which modes (secure/insecure) are enabled, this method will start one or two socket listening loops. The insecure socket can be used to obtain better performance but must only be used in cases where the network transport is known to be secure. This is notoriously difficult to ensure and so such usage should be avoided if at all possible.
If both insecure and secure sockets are used, a second thread will be launched to implement the secure listening loop.
listen
in class SessionManager
notify
- Session listener to be notified of session events.java.lang.Exception
- if there is any configuration error, or error creating a server
socket.public java.lang.String toString()
toString
in class SessionManager
Object.toString()
public int authenticateRemote(java.lang.String identity, int peerID, Queue queue) throws java.lang.IllegalAccessException
authenticateRemote
in class SessionManager
identity
- Account identifier for the requesting party.peerID
- Value which uniquely identifies the security context of the
requesting party. This will be used in communications from
the provider side of the connection.queue
- Message transport queue for the provider side of the
connection.java.lang.IllegalAccessException
- if authentication is not successful.public void terminateRemote(int contextID)
terminateRemote
in class SessionManager
contextID
- Value which uniquely identifies the security context of the
requesting party.protected void init() throws ConfigurationException
init
in class SessionManager
java.lang.IllegalStateException
- if the router node is already listening for connections.ConfigurationException
- if any configuration error occurs during initialization.protected boolean createDirectSession(Queue queue)
createDirectSession
in class SessionManager
queue
- Underlying message transport for the new session.true
if the session initialized successfully.protected void terminateInput()
terminateInput
in class SessionManager
protected boolean deregisterSession(BaseSession session)
If the session being deregistered is the last session to use its queue, this fact is indicated by the method's return value.
The parent's implementation is overridden here to permit additional cleanup necessary for this implementation. However, this implementation first invokes the parent's.
deregisterSession
in class SessionManager
session
- Session being deregistered.true
if the session's underlying queue is still
needed by other sessions; false
if this was the
last session using its queue, and the queue can now be stopped.protected void setContext(RoutingKey key, Queue queue)
setContext
in class SessionManager
key
- Routing key for an incoming message.queue
- Message transport queue.protected void setContext(Queue queue)
setContext
in class SessionManager
queue
- Queue which uniquely identifies the session whose security
context is to be used.java.lang.IllegalArgumentException
- if there is not exactly one session for the given queue.protected void setContext(BaseSession session)
setContext
in class SessionManager
session
- Session whose security context is to be associated with the
current thread.protected void restoreContext()
restoreContext
in class SessionManager
protected void setInitialContext()
setInitialContext
in class SessionManager
protected void dropInitialContext()
dropInitialContext
in class SessionManager
java.lang.Object abortSessionInit(Queue queue)
queue
- The queue that represents the partially initialized session
to be cleaned up.private void listenWorker(SessionListener notify, java.net.ServerSocket input, java.lang.String logtxt)
notify
- Session listener to be notified of session events.input
- The socket on which to listen.logtxt
- A description of the listening loop suitable for a logfile.private java.net.ServerSocket createServerSocket(boolean isSecure, int port) throws java.lang.Exception
secure
or insecure
.isSecure
- Determines whether the created socket should be secure.port
- The port which the socket should listen to.java.lang.Exception
- if an error has occurred while creating server socket.