| Title: Hedwig Message Filter |
| Notice: Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. You may |
| obtain a copy of the License at "http://www.apache.org/licenses/LICENSE-2.0":http://www.apache.org/licenses/LICENSE-2.0. |
| . |
| . |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an "AS IS" |
| BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| implied. See the License for the specific language governing permissions |
| and limitations under the License. |
| . |
| . |
| |
| h1. Message Filter |
| |
| Apache Hedwig provides an efficient mechanism for supporting application-defined __message filtering__. |
| |
| h2. Message |
| |
| 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. |
| |
| h3. Message Header Properties |
| |
| 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. |
| |
| h2. Message Filter |
| |
| 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: |
| |
| # User A may only care about History books. He subscribes to __BookStore__ with his custom preferences : type="History". |
| # User B may only care about Romance books. He subscribes to __BookStore__ with his custom preferences : type="Romance". |
| # A new book arrives at the book store; a message is sent to __BookStore__ with type="History" in its header |
| # The message is then delivered to __BookStore__'s subscribers. |
| # Subscriber A filters the message by checking messages' header to accept those messages whose type is "History". |
| # Subscriber B filters out the message, as the type does not match its preferences. |
| |
| h3. Client Message Filter. |
| |
| 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)__ ). |
| |
| h3. Server Message Filter. |
| |
| 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. |
| |
| h3. Which message filter should be used? |
| |
| 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. |
| |