org.sandev.tools.util
Class AuthorizedJMSMessager

java.lang.Object
  extended byorg.sandev.tools.util.DirectCallMessager
      extended byorg.sandev.tools.util.AuthorizedJMSMessager
All Implemented Interfaces:
javax.jms.MessageListener, org.sandev.basics.nodecommon.Messager

public class AuthorizedJMSMessager
extends DirectCallMessager
implements javax.jms.MessageListener

A Messager implementation that sends nonlocal secure messages over JMS, and everything else via DirectCallMessager. So if you are doing a secure, synchronous call to node not in the same process space

  1. The message goes to the local Authorizer, which serializes and encrypts the message, creating an AuthWrapper instance with the payload text.
  2. The AuthWrapper.message text is sent to the topic idenfified by the remote Authorizer instance name, and the process waits for a a response on a temporary topic.
  3. The remote Messager receives the incoming request, creating an AuthWrapper and sending it to its local Authorizer, which decrypts and reconstitutes the payload message.
  4. The payload message is delivered to the target node, which returns a response message.
  5. The response message is serialized and encrypted, creating an AuthWrapper message to be returned.
  6. The remote Messager takes the AuthWrapper.message text and sends it back on the temporary topic
  7. The original sending Messager creates an AuthWrapper instance with the returned text, which the local Authorizer then decrypts and reconstitutes the returned message.

Remote secure send is analogous but does not wait for any return value. All calls within the same process space go over the DirectCallMessager.

Whether a node can receive via JMS is determined by whether its instance name is found in the EntryPointsCSV global param. Only those node instances will be set up as JMS listener topics. Any given destination that is not the name of a local node is assumed to be an outbound topic send.


Field Summary
protected  javax.jms.TopicConnection connection
          Our topic connection.
protected  javax.naming.Context context
          The JNDI context we use for looking up JMS related stuff.
static java.lang.String ERRORPREFIX
          When we have a framework failure that prevents us from returning an actual message, return this text followed by any descriptive details.
static java.lang.String EXTERNALRECEIVERSCSV
          The name of the global config parameter containing the comma separated list of node instance names that receive messages from outside their local runtime environment.
static java.lang.String EXTERNALSENDONLYCSV
          The name of the global config parameter containing the comma separated list of node instance names that only send messages to outside their local runtime environment.
protected  boolean isReceiver
          True if this instance receives messages from outside of the local runtime environment.
protected  boolean isSender
          True if this instance sends messages outside of the local runtime environment.
static java.lang.String JMS_CONTEXTFACTORYCLASS
          The name of the global config parameter containing the fully qualified name of the JMS context factory class.
static java.lang.String JMS_CONTEXTPROVIDERURL
          The name of the global config parameter containing the URL of the context provider.
static java.lang.String JMS_TIMEOUTSECONDS
          The name of the global config parameter containing the number of seconds that JMS should wait before timing out.
protected  java.lang.String name
          The name of our topic, which is the same as our node instance name.
protected  int responseTimeoutMillis
          The maximum number of milliseconds to wait for a remote call response before timing out.
protected  javax.jms.TopicSession session
          We use a single TopicSession for receiving since we are not doing JMS transactions
 
Fields inherited from class org.sandev.tools.util.DirectCallMessager
ourInstance, ourNode, subTable
 
Fields inherited from interface org.sandev.basics.nodecommon.Messager
MODE_DIRECT, MODE_INVALID, MODE_SECURE, OPTIMIZE_IF_POSSIBLE, OPTIMIZE_NEVER, WIRE_BASICSECURITY, WIRE_SECURECOMMS, WIRE_TRANSPORTONLY
 
Constructor Summary
AuthorizedJMSMessager()
           
 
Method Summary
protected  javax.jms.TopicConnection getConnection()
          Return the connection or throw if it is null.
protected  javax.jms.TopicSession getSession()
          Return the session or throw if it is null.
 int getWireSecurity()
          Returns WIRE_BASICSECURITY.
 void init(org.sandev.basics.nodecommon.Messageable node, org.sandev.basics.structs.NodeInstance instance)
           
protected  void initConnection()
          initializer for connection
protected  void initContext(org.sandev.basics.nodecommon.SandRoot sandRoot)
          initializer for context
protected  void initResponseTimeoutMillis(org.sandev.basics.nodecommon.SandRoot sandRoot)
          initializer for responseTimeoutMillis
protected  void initSession()
          initializer for session
 void onMessage(javax.jms.Message msg)
          Receive a JMS message, sick it into an AuthWrapper and pass it to the node.
 org.sandev.basics.structs.SandMessage query(org.sandev.basics.structs.SandMessage msg, java.lang.String recipientInstanceName, int optimize, int mode, java.lang.String localAuthorizerInstanceName)
          Try this as a local query, and then try remote if that fails.
 void queryReceiver(org.sandev.basics.nodecommon.Messageable node, java.lang.String messageClass, java.lang.String localAuthorizerInstanceName)
          Just calls through to the superclass.
 void send(org.sandev.basics.structs.SandMessage msg, int optimize, int mode, java.lang.String localAuthorizerInstanceName)
          Send the given message.
 void shutdown()
          Close down the connection, which closes the session, producers and consumers.
 void subscribe(org.sandev.basics.nodecommon.Messageable node, java.lang.String msgClass, java.lang.String sender, int optimize, int mode, java.lang.String localAuth, org.sandev.basics.structs.SandAttrVal[] matchDescription)
          Call the superclass if this is a local node, otherwise subscribe to the topic name given as the sender parameter.
 void unsubscribe(org.sandev.basics.nodecommon.Messageable node, java.lang.String msgClass, java.lang.String sender, int optimize, int mode, java.lang.String localAuth)
          Undo the identified subscription.
 
Methods inherited from class org.sandev.tools.util.DirectCallMessager
addSubscriber, doQuery, doSend, doSend, doSubscribe, doUnsubscribe, error, getImplementationWireSecurity, getMessageable, getOurInstance, getOurNode, getSubTable, info, removeSubscriber, setOurInstance, setOurNode
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

EXTERNALRECEIVERSCSV

public static final java.lang.String EXTERNALRECEIVERSCSV
The name of the global config parameter containing the comma separated list of node instance names that receive messages from outside their local runtime environment.

See Also:
Constant Field Values

EXTERNALSENDONLYCSV

public static final java.lang.String EXTERNALSENDONLYCSV
The name of the global config parameter containing the comma separated list of node instance names that only send messages to outside their local runtime environment.

See Also:
Constant Field Values

JMS_TIMEOUTSECONDS

public static final java.lang.String JMS_TIMEOUTSECONDS
The name of the global config parameter containing the number of seconds that JMS should wait before timing out.

See Also:
Constant Field Values

JMS_CONTEXTFACTORYCLASS

public static final java.lang.String JMS_CONTEXTFACTORYCLASS
The name of the global config parameter containing the fully qualified name of the JMS context factory class.

See Also:
Constant Field Values

JMS_CONTEXTPROVIDERURL

public static final java.lang.String JMS_CONTEXTPROVIDERURL
The name of the global config parameter containing the URL of the context provider.

See Also:
Constant Field Values

ERRORPREFIX

public static final java.lang.String ERRORPREFIX
When we have a framework failure that prevents us from returning an actual message, return this text followed by any descriptive details.

See Also:
Constant Field Values

context

protected javax.naming.Context context
The JNDI context we use for looking up JMS related stuff.


connection

protected javax.jms.TopicConnection connection
Our topic connection. We re-use the same connection.


session

protected javax.jms.TopicSession session
We use a single TopicSession for receiving since we are not doing JMS transactions


responseTimeoutMillis

protected int responseTimeoutMillis
The maximum number of milliseconds to wait for a remote call response before timing out.


name

protected java.lang.String name
The name of our topic, which is the same as our node instance name. This is set directly by the init method.


isSender

protected boolean isSender
True if this instance sends messages outside of the local runtime environment. Defaults to false. Set by the init method.


isReceiver

protected boolean isReceiver
True if this instance receives messages from outside of the local runtime environment. Defaults to false. Set by the init method.

Constructor Detail

AuthorizedJMSMessager

public AuthorizedJMSMessager()
Method Detail

initContext

protected void initContext(org.sandev.basics.nodecommon.SandRoot sandRoot)
                    throws org.sandev.basics.nodecommon.MessagerException
initializer for context

Throws:
org.sandev.basics.nodecommon.MessagerException

initConnection

protected void initConnection()
                       throws org.sandev.basics.nodecommon.MessagerException
initializer for connection

Throws:
org.sandev.basics.nodecommon.MessagerException

getConnection

protected javax.jms.TopicConnection getConnection()
                                           throws org.sandev.basics.nodecommon.MessagerException
Return the connection or throw if it is null. On a computer without JMS installed, or working offline from a JMS server, the topic connection won't be initialized. This method checks if the context is null and throws a MessagerException which is better than an NPE.

Throws:
org.sandev.basics.nodecommon.MessagerException

initSession

protected void initSession()
                    throws org.sandev.basics.nodecommon.MessagerException
initializer for session

Throws:
org.sandev.basics.nodecommon.MessagerException

getSession

protected javax.jms.TopicSession getSession()
                                     throws org.sandev.basics.nodecommon.MessagerException
Return the session or throw if it is null. On a computer without JMS installed, or working offline from a JMS server, the session is not going to be initialized. This method checks if the session is null and throws a MessagerException which is better than an NPE.

Throws:
org.sandev.basics.nodecommon.MessagerException

initResponseTimeoutMillis

protected void initResponseTimeoutMillis(org.sandev.basics.nodecommon.SandRoot sandRoot)
                                  throws org.sandev.basics.nodecommon.MessagerException
initializer for responseTimeoutMillis

Throws:
org.sandev.basics.nodecommon.MessagerException

init

public void init(org.sandev.basics.nodecommon.Messageable node,
                 org.sandev.basics.structs.NodeInstance instance)
          throws org.sandev.basics.nodecommon.MessagerException
Specified by:
init in interface org.sandev.basics.nodecommon.Messager
Overrides:
init in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

shutdown

public void shutdown()
Close down the connection, which closes the session, producers and consumers.

Specified by:
shutdown in interface org.sandev.basics.nodecommon.Messager
Overrides:
shutdown in class DirectCallMessager

send

public void send(org.sandev.basics.structs.SandMessage msg,
                 int optimize,
                 int mode,
                 java.lang.String localAuthorizerInstanceName)
          throws org.sandev.basics.nodecommon.MessagerException
Send the given message. Always call the direct subscriber send, only publish outbound messages if we are a remote sender and the outbound send is secure.

Specified by:
send in interface org.sandev.basics.nodecommon.Messager
Overrides:
send in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

subscribe

public void subscribe(org.sandev.basics.nodecommon.Messageable node,
                      java.lang.String msgClass,
                      java.lang.String sender,
                      int optimize,
                      int mode,
                      java.lang.String localAuth,
                      org.sandev.basics.structs.SandAttrVal[] matchDescription)
               throws org.sandev.basics.nodecommon.MessagerException
Call the superclass if this is a local node, otherwise subscribe to the topic name given as the sender parameter.

Specified by:
subscribe in interface org.sandev.basics.nodecommon.Messager
Overrides:
subscribe in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

unsubscribe

public void unsubscribe(org.sandev.basics.nodecommon.Messageable node,
                        java.lang.String msgClass,
                        java.lang.String sender,
                        int optimize,
                        int mode,
                        java.lang.String localAuth)
                 throws org.sandev.basics.nodecommon.MessagerException
Undo the identified subscription. See comments under subscribe.

Specified by:
unsubscribe in interface org.sandev.basics.nodecommon.Messager
Overrides:
unsubscribe in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

query

public org.sandev.basics.structs.SandMessage query(org.sandev.basics.structs.SandMessage msg,
                                                   java.lang.String recipientInstanceName,
                                                   int optimize,
                                                   int mode,
                                                   java.lang.String localAuthorizerInstanceName)
                                            throws org.sandev.basics.nodecommon.MessagerException
Try this as a local query, and then try remote if that fails.

Specified by:
query in interface org.sandev.basics.nodecommon.Messager
Overrides:
query in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

queryReceiver

public void queryReceiver(org.sandev.basics.nodecommon.Messageable node,
                          java.lang.String messageClass,
                          java.lang.String localAuthorizerInstanceName)
                   throws org.sandev.basics.nodecommon.MessagerException
Just calls through to the superclass. Since the local authorizer is by definition local, we leave this to the DirectCallMessager.

Specified by:
queryReceiver in interface org.sandev.basics.nodecommon.Messager
Overrides:
queryReceiver in class DirectCallMessager
Throws:
org.sandev.basics.nodecommon.MessagerException

getWireSecurity

public int getWireSecurity()
Returns WIRE_BASICSECURITY. This messager is intended to run over a secure communications channel, because it does not provide any snoop-proofing itself. If run over an insecure channel, then the effective security will be WIRE_TRANSPORTONLY, without change to any of the functionality.

This Messager implementation always calls local Authorizers for serialization and encryption, so it is never WIRE_SECURECOMMS.

Specified by:
getWireSecurity in interface org.sandev.basics.nodecommon.Messager
Overrides:
getWireSecurity in class DirectCallMessager

onMessage

public void onMessage(javax.jms.Message msg)
Receive a JMS message, sick it into an AuthWrapper and pass it to the node. If the JMS message has a replyTo destination set, then this is a query. Otherwise this is an async delivery.

If all goes well to the extent that we get a message back, then that message gets serialized, encrypted, and returned. Otherwise

Specified by:
onMessage in interface javax.jms.MessageListener