Apache Hedwig provides an efficient mechanism for supporting application-defined message filtering.
Most message-oriented middleware (MOM) products treat messages as lightweight entities that consist of a header and a payload. The header contains fields used for message routing and identification; the payload contains the application data being sent.
Hedwig messages follow a similar template, being composed of following parts:
Header- All messages support both system defined fields and application defined property values. Properties provide an efficient mechanism for supporting application-defined message filtering.
Body- Hedwig considers the message body as a opaque binary blob.
SrcRegion- Indicates where the message comes from.
MessageSeqId- The unique message sequence id assigned by Hedwig.
A Message object contains a built-in facility for supporting application-defined property values. In effect, this provides a mechanism for adding application-specific header fields to a message.
By using properties and message filters, an application can have Hedwig select, or filter, messages on its behalf using application-specific criteria.
Property names must be a String and must not be null, while property values are binary blobs. The flexibility of binary blobs allows applications to define their own serialize/deserialize functions, allowing structured data to be stored in the message header.
A Message Filter allows an application to specify, via header properties, the messages it is interested in. Only messages which pass validation of a Message Filter, specified by a subscriber, are be delivered to the subscriber.
A message filter could be run either on the server side or on the client side. For both server side and client side, a Message Filter implementation needs to implement the following two interfaces:
setSubscriptionPreferences(topic, subscriberId, preferences): The subscription preferences of the subscriber will be passed to message filter when it was attached to its subscription either on the server-side or on the client-side.
testMessage(message): Used to test whether a particular message passes the filter or not.
The subscription preferences are used to specify the messages that the user is interested in. The message filter uses the subscription preferences to decide which messages are passed to the user.
Take a book store(using topic BookStore) as an example:
A ClientMessageFilter runs on the client side. Each subscriber can write its own filter and pass it as a parameter when starting delivery ( startDelivery(topic, subscriberId, messageHandler, messageFilter) ).
A ServerMessageFilter runs on the server side (a hub server). A hub server instantiates a server message filter, by means of reflection, using the message filter class specified in the subscription preferences which are provided by the subscriber. Since ServerMessageFilter__s run on the hub server, all filtered-out messages are never delivered to client, reducing unnecessary network traffic. Hedwig uses a implementation of __ServerMessageFilter to filter unnecessary message deliveries between regions.
Since hub servers use reflection to instantiate a ServerMessageFilter, an implementation of ServerMessageFilter needs to implement two additional methods:
initialize(conf): Initialize the message filter before filtering messages.
uninitialize(): Uninitialize the message filter to release resources used by the message filter.
For the hub server to load the message filter, the implementation class must be in the server's classpath at startup.
It depends on application requirements. Using a ServerMessageFilter will reduce network traffic by filtering unnecessary messages, but it would compete for resources on the hub server(CPU, memory, etc). Conversely, __ClientMessageFilter__s have the advantage of inducing no extra load on the hub server, but at the price of higher network utilization. A filter can be installed both at the server side and on the client; Hedwig does not restrict this.