Remote Observation Module

Version 4.2 by Vincent Massol on 2011/05/05 09:25

Provides the ability to automatically send and receive events through the network.

rom.png

Features

  • api to start/stop channels at runtime
  • add custom event converter
  • add custom network adapter implementation (default is based on JGroups)

Quick Example

Start/stop channel

RemoteObservationManager rom = componentManager.lookup(RemoteObservationManager.class);

// stop the channel with identifier channelid, the channel with configuration file channelid.xml
rom.stopChannel("channelid");
// start the channel with identifier channelid, the configuration file is releaded
rom.startChannel("channelid");

Extension

Remote event manage is extendable in many ways depending of the need.

Add custom event converter

Each time an event is generated locally or received from network, Remote Event Manager try to converter it to the other side. By default a support of all document events and any fully serializable event is provided but since it's possible to add any kind of local event Remote Event Manager also provide a way to provide converter for any kind of event as well.

There is two kinf of converter:

  • the local to remote event converter: org.xwiki.observation.remote.converter.LocalEventConverter
  • the remote to local event converter: org.xwiki.observation.remote.converter.RemoteEventConverter

Most of the time when adding a new event you will need to make conversion both ways. The common way to do this is by extending AbstractEventConverter which provide a default priority and implements both LocalEventConverter and RemoteEventConverter.

public class ViewEventConverter extends AbstractEventConverter
{
   public int getPriority()
   {
       // default priority level
       return 1000;
   }

   public boolean toRemote(LocalEventData localEvent, RemoteEventData remoteEvent)
   {
       if (localEvent.getEvent() instanceof ActionExecutionEvent) {
            ActionExecutionEvent event = (ActionExecutionEvent) localEvent.getEvent();

           if ("view".equals(event.getActionName())) {
               // fill the remote event
               remoteEvent.setEvent(event);
           }

           return true;
       }

       return false;
   }

   public boolean fromRemote(RemoteEventData remoteEvent, LocalEventData localEvent)
   {
       if (localEvent.getEvent() instanceof ActionExecutionEvent) {
            ActionExecutionEvent event = (ActionExecutionEvent) localEvent.getEvent();

           if ("view".equals(event.getActionName())) {
               // fill the local event
               localEvent.setEvent(event);
           }

           return true;
       }

       return false;
   }
}

toRemote and fromRemote work the same way: converter manager call them in the priority order one by one and stop when the methods return true. If the converter event data is empty it mean the event should not be sent for remote event or given to Observation Manager for local events.

This converter is a combination local event converter and remote event converter. It's possible to implement just local or just remote. For example one would want to filter some kind of events or document.

Add custom network adaptor

The default implementation is based on JGroups, it possible to change just the network communication part easily by providing a new implementation of org.xwiki.observation.remote.NetworkAdapter and setting the role hint of this new component as value of the property observation.remote.networkadapter in the file xwiki.properties.

Provide custom JGroups listener

In JGroups based implementation it's possible to provide to set the Receiver to use channel by channel. This is useful for example to make a channel readonly when you want to send events in a public UDP broadcast and not do two ways clustering.

To do this implements the component interface org.xwiki.observation.remote.jgroups.JGroupsReceiver and make the role hint having the same name as the channel.

@Component("public")
public class PublicJGroupsReceiver implements JGroupsReceiver
{
   public byte[] getState()
   {
       return null;
   }

   public void receive(Message msg)
   {
       // do nothing, it's a readonly public channel
   }

   public void setState(byte[] state)
   {

   }

   public void block()
   {

   }

   public void suspect(Address suspectedMbr)
   {

   }

   public void viewAccepted(View newView)
   {

   }
}

JGroups

See http://www.jgroups.org and http://www.jboss.org/community/wiki/JGroups for more documentation on JGroups and its configuration files.

Debugging

There are types of logs you can enable to diagnose issues with clustering:

  • XWiki cluster logs
  • JGroups cluster logs

For both you'll need to edit the Log4J configuration (see Logging).

To enable XWiki cluster logs, add:

log4j.logger.org.xwiki.observation.remote=trace

To enable JGroups cluster logs, see the JGroups Logging Article.

Tutorial

Get Connected