Home Contact

 A Generic Framework for Context-Aware Applications.

Abstract

In WildCAT general introduction, we present how, using symlinks and remote paths, multiple contexts, possibly distant, may interact. In this tutorial, after describing the different protocol communications used between the remote contexts, we describe the code and the configuration of two context running on different JVMs and interacting.

Communication between remote contexts

    According to the mode, the communication protocol varies:
  • Pull mode relies on a synchronous communication;
  • Push mode relies on a asynchronous communication.
Remote contexts are accessed through dispatchers. Two alternative dispatchers are provided: one based on both RMI and JMS (used by default), and an other fully implemented with JMS. If these dispatchers have the same implemention of push mode, they differ over the pull mode. Indeed, the RMI-JMS dispatcher uses RMI through CMI to perform synchronous operations, while the full-JMS dispatcher defines a layer to add synchronism on top of JMS.

RMI-JMS dispatcher

Distributed registry

Each WildCAT context is connected to a collocated registry in wich it binds its own RMI stub identified by its context name. Thanks to CMI, all the stubs and topics can be retrieved by simply looking up into its own registry!

full-JMS dispatcher

Single registry

Each WildCAT context is connected to a remote registry in wich it retrieves the connection factories needed to connect itself to topics and queues.

Example

Hierarchy

Let's consider the example hierarchy presented in the image. The hierarchy shows two distinct contexts nammed node1 and node2 (so creative, isn't it). The link from context node1 to context node2 depict a symbolic link.

JMS provider

Here we assume, a JMS provider is up and running and accept connections at rmi://jmshost:jmsport. The JMS provider must exposes both a Queue and a Topic connection factory. Supposing the factories are exposed as JQCF and respectively JTCF.

Numerous implementations of JMS providers exist. The actual process of setting up and running a JMS provider is out of the scope of this tutorial. As a note, we successfuly using both the openJMS and the Joram provider with WildCAT.

The code

Let's consider the very simple code for creating and building both hierarchies.

node2

First the code of the node2:

public class Node2 {

    public static void main (String[] args) {
    
        System.setProperty("org.ow2.wildcat.configuration", "/wildcat.node2.properties");
        Context ctx = ContextFactory.getDefaultFactory().createContext("node2");
        ctx.registerListeners("select * from WEvent", new UpdateListener () {
            void update (EventBean[] nevents, EventBean[] oevents) {
                for (EventBean bean : nevents) {
                    System.out.println("---> " + bean.getUnderlying().toString());
                }
            }
        });
        
        ctx.export();
        
        ctx.createResource("self://creating/node2/dummy/hierarchy");
    }
}

The code first sets the "org.ow2.wildcat.configuration" system properties to point node2 hierarchy configuration file. Then it instanciate a context nammed "node2" through the default ContextFactory. Then it register the "usual" show me everything listener. After that, the "export" method render the context visible to remote contexts.

node1

The code of the node1:

public class Node1 {

    public static void main (String[] args) {
    
        System.setProperty("org.ow2.wildcat.configuration", "/wildcat.node1.properties");
        Context ctx = ContextFactory.getDefaultFactory().createContext("node1");
        ctx.registerListeners("select * from WEvent", new UpdateListener () {
            void update (EventBean[] nevents, EventBean[] oevents) {
                for (EventBean bean : nevents) {
                    System.out.println("---> " + bean.getUnderlying().toString());
                }
            }
        });
        
        ctx.export();
        
        ctx.createResource("self://creating/node1/dummy/hierarchy");
        ctx.createSymlink("self://node2", "node2://any/resource/in/node2/hierarchy");
    }
}

node1's code is very similar to node2's one. Indeed, context creation and configuation are identical. The code also must export the context using the "export" method. Finally the interaction between, node1 and node2 is made by the creation of the symlink between the two.

The configuration

Let's now consider the two configuration files (when the full-JMS dispatcher is used):

Node2

org.ow2.wildcat.remote.jms_provider_url=tcp://jmshost:jmsport
org.ow2.wildcat.remote.queue_connection_factory=JMSQueueConnectionFactory
org.ow2.wildcat.remote.topic_connection_factory=JMSTopicConnectionFactory

org.ow2.wildcat.remote.dispatcher_name=dispatcher2

Node1

org.ow2.wildcat.remote.jms_provider_url=tcp://jmshost:jmsport
org.ow2.wildcat.remote.queue_connection_factory=JMSQueueConnectionFactory
org.ow2.wildcat.remote.topic_connection_factory=JMSTopicConnectionFactory

org.ow2.wildcat.remote.dispatcher_name=dispatcher1

Both file first defines the JMS provider url and both Topic and Queue connection factory names.

Finally, and most importantly is the name of the dispatcher. A dispatcher is the JMS frontend used in between communicating contexts. Each dispatcher must have a unique names and dispatcher and context must not have identical names. Here, we simply nammed our dispatcher dispatcher1 and dispatcher2.

Conclusion

In this tutorial, we have shown how to configure and set-up a WildCAT "distributed" deploiement where two contexts communicate through JMS.