| <!DOCTYPE html> |
| <!-- |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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 |
| |
| 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. |
| --> |
| <html> |
| <head> |
| <title>Apache BookKeeper - Hedwig Message Filter</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <!-- Bootstrap --> |
| <link href="/archives/css/bootstrap.min.css" rel="stylesheet"> |
| <link href="/archives/css/bootstrap-responsive.min.css" rel="stylesheet"> |
| <link href="/archives/css/styles.css" rel="stylesheet"> |
| </head> |
| <body> |
| <header class="navbar navbar-inverse navbar-static-top" role="banner"> |
| <div class="container"> |
| <div class="navbar-header hidden-xs hidden-sm"> |
| <a class="navbar-brand navbar-logo" href="/archives/"><img class="img-responsive" src="/archives/img/bookkeeper_blk40.png" alt="Bookkeeper Logo" /></a> |
| </div> |
| <div class="navbar-header"> |
| <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| <a class="navbar-brand" href="/archives/">Apache BookKeeper</a> |
| </div> |
| <nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation"> |
| <ul class="nav navbar-nav"> |
| <li><a href="/archives/releases.html">Download</a></li> |
| |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Documentation<span class="caret"></span></a> |
| <ul class="dropdown-menu" role="menu"> |
| <li><a href="/archives/docs/master">Latest (master)</a></li> |
| <li><ul> |
| <li><a href="/archives/docs/master/apidocs">Java API docs</a></li> |
| <li><a href="/archives/docs/master/bookkeeperTutorial.html">Tutorial</a></li> |
| <li><a href="/archives/docs/master/bookkeeperConfig.html">Admin guide</a></li> |
| </ul><li> |
| <li><a href="/archives/docs/r4.4.0">Release 4.4.0</a></li> |
| <li class="divider"></li> |
| <li>Older releases</li> |
| <li><a href="/archives/docs/r4.3.2">Release 4.3.2</a></li> |
| <li><a href="/archives/docs/r4.3.1">Release 4.3.1</a></li> |
| <li><a href="/archives/docs/r4.3.0">Release 4.3.0</a></li> |
| <li><a href="/archives/docs/r4.2.4">Release 4.2.4</a></li> |
| <li><a href="/archives/docs/r4.2.3">Release 4.2.3</a></li> |
| <li><a href="/archives/docs/r4.2.2">Release 4.2.2</a></li> |
| <li><a href="/archives/docs/r4.2.1">Release 4.2.1</a></li> |
| <li><a href="/archives/docs/r4.2.0">Release 4.2.0</a></li> |
| <li><a href="/archives/docs/r4.1.0">Release 4.1.0</a></li> |
| <li><a href="/archives/docs/r4.0.0">Release 4.0.0</a></li> |
| </ul> |
| </li> |
| |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Get Involved<span class="caret"></span></a> |
| <ul class="dropdown-menu" role="menu"> |
| <li><a href="/archives/lists.html">Mailing Lists</a></li> |
| <li><a href="/archives/irc.html">IRC</a></li> |
| <li><a href="/archives/svn.html">Version Control</a></li> |
| <li><a href="https://issues.apache.org/jira/browse/BOOKKEEPER">Issue Tracker</a></li> |
| </ul> |
| </li> |
| |
| <li><a href="https://cwiki.apache.org/confluence/display/BOOKKEEPER/Index">Wiki</a></li> |
| <!--<li><a href="#">Hedwig</a></li>//--> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Project Info<span class="caret"></span></a> |
| <ul class="dropdown-menu" role="menu"> |
| <li><a href="/archives/credits.html">Who are we?</a></li> |
| <li><a href="/archives/bylaws.html">Bylaws</a></li> |
| <li><a href="http://www.apache.org/licenses/">License</a></li> |
| <li class="divider"></li> |
| <li><a href="/archives/privacy.html">Privacy Policy</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsership</a></li> |
| <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| </ul> |
| </li> |
| </ul> |
| <script> |
| (function() { |
| var cx = '017580107654524087317:iqnsyimpydg'; |
| var gcse = document.createElement('script'); |
| gcse.type = 'text/javascript'; |
| gcse.async = true; |
| gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + |
| '//www.google.com/cse/cse.js?cx=' + cx; |
| var s = document.getElementsByTagName('script')[0]; |
| s.parentNode.insertBefore(gcse, s); |
| })(); |
| </script> |
| |
| <div class="navbar-form navbar-right visible-lg" id="googlebox"> |
| <gcse:searchbox-only></gcse:searchbox-only> |
| </div> |
| </nav> |
| </div> |
| </header> |
| <div class="container"> |
| |
| <h1>Message Filter</h1> |
| |
| <p>Apache Hedwig provides an efficient mechanism for supporting application-defined <i>message filtering</i>.</p> |
| |
| <h2>Message</h2> |
| |
| <p>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.</p> |
| |
| <p>Hedwig messages follow a similar template, being composed of following parts:</p> |
| |
| <ul> |
| <li><code>Header</code> - All messages support both system defined fields and application defined property values. Properties provide an efficient mechanism for supporting application-defined message filtering.</li> |
| <li><code>Body</code> - Hedwig considers the message body as a opaque binary blob.</li> |
| <li><code>SrcRegion</code> - Indicates where the message comes from.</li> |
| <li><code>MessageSeqId</code> - The unique message sequence id assigned by Hedwig.</li> |
| </ul> |
| |
| <h3>Message Header Properties</h3> |
| |
| <p>A <i>Message</i> 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.</p> |
| |
| <p>By using properties and <i>message filters</i>, an application can have Hedwig select, or filter, messages on its behalf using application-specific criteria.</p> |
| |
| <p>Property names must be a <i>String</i> 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.</p> |
| |
| <h2>Message Filter</h2> |
| |
| <p>A <i>Message Filter</i> allows an application to specify, via header properties, the messages it is interested in. Only messages which pass validation of a <i>Message Filter</i>, specified by a subscriber, are be delivered to the subscriber.</p> |
| |
| <p>A message filter could be run either on the <i>server side</i> or on the <i>client side</i>. For both <i>server side</i> and <i>client side</i>, a <i>Message Filter</i> implementation needs to implement the following two interfaces:</p> |
| |
| <ul> |
| <li><code>setSubscriptionPreferences(topic, subscriberId, preferences)</code>: The <i>subscription preferences</i> 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.</li> |
| <li><code>testMessage(message)</code>: Used to test whether a particular message passes the filter or not.</li> |
| </ul> |
| |
| <p>The <i>subscription preferences</i> are used to specify the messages that the user is interested in. The <i>message filter</i> uses the <i>subscription preferences</i> to decide which messages are passed to the user.</p> |
| |
| <p>Take a book store(using topic <i>BookStore</i>) as an example:</p> |
| |
| <ol> |
| <li>User A may only care about History books. He subscribes to <i>BookStore</i> with his custom preferences : type="History".</li> |
| <li>User B may only care about Romance books. He subscribes to <i>BookStore</i> with his custom preferences : type="Romance".</li> |
| <li>A new book arrives at the book store; a message is sent to <i>BookStore</i> with type="History" in its header</li> |
| <li>The message is then delivered to <i>BookStore</i>'s subscribers.</li> |
| <li>Subscriber A filters the message by checking messages' header to accept those messages whose type is "History".</li> |
| <li>Subscriber B filters out the message, as the type does not match its preferences.</li> |
| </ol> |
| |
| <h3>Client Message Filter.</h3> |
| |
| <p>A <i>ClientMessageFilter</i> runs on the client side. Each subscriber can write its own filter and pass it as a parameter when starting delivery ( <i>startDelivery(topic, subscriberId, messageHandler, messageFilter)</i> ).</p> |
| |
| <h3>Server Message Filter.</h3> |
| |
| <p>A <i>ServerMessageFilter</i> 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 <i>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</i> to filter unnecessary message deliveries between regions.</p> |
| |
| <p>Since hub servers use reflection to instantiate a <i>ServerMessageFilter</i>, an implementation of <i>ServerMessageFilter</i> needs to implement two additional methods:</p> |
| |
| <ul> |
| <li><code>initialize(conf)</code>: Initialize the message filter before filtering messages.</li> |
| <li><code>uninitialize()</code>: Uninitialize the message filter to release resources used by the message filter.</li> |
| </ul> |
| |
| <p>For the hub server to load the message filter, the implementation class must be in the server's classpath at startup.</p> |
| |
| <h3>Which message filter should be used?</h3> |
| |
| <p>It depends on application requirements. Using a <i>ServerMessageFilter</i> 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.</p> |
| |
| </div> |
| <footer class="footer"> |
| <div class="container"> |
| <p class="text-muted">Copyright © 2014 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.<br/> |
| Apache BookKeeper, BookKeeper, Apache, Apache ZooKeeper, ZooKeeper, the Apache feather logo, and the Apache BookKeeper project logo are trademarks of The Apache Software Foundation.</p> |
| </div> |
| </footer> |
| |
| <script src="//code.jquery.com/jquery.js"></script> |
| <script src="/archives/js/bootstrap.min.js"></script> |
| </body> |
| </html> |