<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Angle of Sight</title>
	
	<link>http://www.angleofsight.com</link>
	<description>The solution depends on how you see the problem.</description>
	<pubDate>Sat, 03 Apr 2010 15:55:36 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AngleOfSight" /><feedburner:info uri="angleofsight" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>AngleOfSight</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/AngleOfSight" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.yourminis.com/subscribe.aspx?u=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.yourminis.com/images/addtoyourminisbadge.gif">Subscribe with Yourminis.com</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://hub.netomat.net/account/account.autoSubscribe.jspa?urls=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.netomat.net/blogger/images/icon_netomat_feedbutton.gif">Subscribe with netomat Hub</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FAngleOfSight" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/Ot2Ynaf3vQY/</link>
		<comments>http://www.angleofsight.com/2010/03/mongowave/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 06:15:02 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[Strategy]]></category>

		<category><![CDATA[annotation]]></category>

		<category><![CDATA[aop]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[guice]]></category>

		<category><![CDATA[mongodb]]></category>

		<category><![CDATA[persistence]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=189</guid>
		<description><![CDATA[


Purpose
My company, SESI, has been working on applying advanced collaboration and analytical techniques to complex-situations to aid decision-making.  As part of that effort I have been quite involved with the Google Wave Protocol project.  I wanted to share my preliminary success implementing persistence on FedOne with MongoDB. &#160;In my previous post on the [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p></p>
<div id="a92x" style="text-align:left"><img src="http://www.angleofsight.com/images/wave/mongowave.png"></div>
<p></p>
<div><b><font class="Apple-style-span" size="3">Purpose</font></b><br/><br/></div>
<div><font class="Apple-style-span" size="3">My company, SESI, has been working on applying advanced collaboration and analytical techniques to complex-situations to aid decision-making.  As part of that effort I have been quite involved with the Google Wave Protocol project.  I wanted to share my preliminary success implementing persistence on FedOne with MongoDB. &nbsp;In my <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-5/" id="l5g0" title="previous post">previous post</a> on the topic of persistence I explored where you could add persistence. &nbsp;As I followed the recommendations of that post, it is probably a good primer for this entry. &nbsp;This post will be more focused on the mechanics of my implementation. &nbsp;I will discuss my current progress, why I chose mongoDB, my design goals, how I implemented the design in code, the hurdles I encountered, and my next steps.</font></p>
</div>
<div><b><font class="Apple-style-span" size="3">Current Progress</font></b><br/><br/></div>
<div><font class="Apple-style-span" size="3">I have tested persistence locally and through federation with the console client, QWaveClient, and wavesandbox.com. &nbsp;I can create multiple waves, add and remove participants, and host conversations between multiple wavesandbox, QWave, and console clients. When I restart my server the clients&#8217; waves are loaded automatically. &nbsp;When I open a wave, the conversation is brought to the latest version (even if the client was not online when the last updates were made). &nbsp;I was pretty excited when the QWave client restored correctly, because I tested solely on the console client that is part of FedOne and had no knowledge of how QWave was implemented. &nbsp;Many thanks to Torben Weis for his excellent work on QWave (and not just because it worked with my persistence).</font></p>
</div>
<div><font class="Apple-style-span" size="3">I have NOT constructed or run any JUnit tests. &nbsp;My persistence mechanisms are focused on storing information in the current implementation of FedOne and I have not expended any effort into correctly handling the commit-notice. &nbsp;That is to say I persist information when I receive a wavelet-update as FedOne does not currently have an algorithm in place to store pending deltas in a separate container from applied deltas that have been acknowledged by a commit-notice (see <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-5/" id="ug_2" title="previous pos">this post</a> for details). &nbsp;This isn&#8217;t an attempt to blame FedOne, rather to say that is not where my focus has been. And as a side note, I&#8217;m hoping the Google team decides to do away with the notion of a separate commit-notice.</font><br/><br/></div>
<div><b><font class="Apple-style-span" size="3">Why MongoDB</font></b><br/><br/></div>
<div><font class="Apple-style-span" size="3">As defined on their <a href="http://www.mongodb.org/display/DOCS/Home" id="ckim" target="mongodb" title="website">website</a>, MongoDB (from &#8220;hu<b>mongo</b>us&#8221;) is a scalable, high-performance, open source, schema-free, document-oriented database. &nbsp;I admittedly like the sound and thought of &#8216;MongoWave&#8217; as in huge wave, but that was not part of the decision to go in that direction. &nbsp;My primary reasons for using mongoDB were the flexibility of schema-free storage (no tables), a JSON sytle syntax for storing and retrieving information (converted to and stored in BSON), embedded map-reduce, auto-sharding for scalability, good documentation, easy setup, drivers in many languages (Java, C++, Ruby, Python, Perl), and an active expanding community. &nbsp;I do not want to start a holy war here or engage in the &#8220;why didn&#8217;t you go with or have you tried &lt;insert my favorite storage solution&gt;?&#8221;. &nbsp;Suffice to say this is what I feel mongoDB offers me and that is why I am using it.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">For more in-depth info on mongoDB, I recommend:</font><br/></div>
<ul>
<li><a href="http://mongo.kylebanker.com/" id="n4i4" target="mongodb" title="Interactive Online Shell Tutorial"><font class="Apple-style-span" size="3">Interactive Online Shell Tutorial</font></a><font class="Apple-style-span" size="3"> - 5 minute hands-on demonstration of mongoDB by Kyle Banker. &nbsp;I also recommend his </font><a href="http://kylebanker.com/blog/" id="swmr" target="mongodb" title="other posts"><font class="Apple-style-span" size="3">other posts</font></a><font class="Apple-style-span" size="3"> on mongoDB.</font></li>
<li><a href="http://blog.boxedice.com/2009/07/25/choosing-a-non-relational-database-why-we-migrated-from-mysql-to-mongodb/" id="nf-:" target="mongodb" title="Case Study on Switching to mongoDB"><font class="Apple-style-span" size="3">Case Study on Switching to mongoDB</font></a><font class="Apple-style-span" size="3"> - Very insightful and well-written article on why a company went from MySQL to MongoDB and the issues involved in their migration by David Mytton.</font></li>
<li><a href="http://www.mongodb.org/display/DOCS/Getting+Started" id="ljwz" target="mongodb" title="Getting Started"><font class="Apple-style-span" size="3">Getting Started</font></a><font class="Apple-style-span" size="3"> - mongoDB quick start reference.</font></li>
</ul>
<div><b><font class="Apple-style-span" size="3">Design Goals</font></b><br/><br/></div>
<div><font class="Apple-style-span" size="3">My overarching goals in building persistence into the FedOne solution were</font><br/></div>
<ul>
<li><font class="Apple-style-span" size="3">Minimal disruption to code base. &nbsp;FedOne is an open source project that is rapidly changing. &nbsp;I did not want my code to be littered throughout such that it became tedious to re-implement persistence anytime a new release was made available.</font></li>
<li><font class="Apple-style-span" size="3">Flexibility to modify what information I persist and where I persist/restore that information. &nbsp;As FedOne matures, I expect there to be more information that needs to be persisted (e.g. - user management/access controls). &nbsp;I also expect there to be refactoring due to optimizations, updates to the protocol, and other progress in general. &nbsp;In consideration of this, I wanted to be able to easily modify the information I persist and update the location in code of my persistence mechanisms.</font></li>
<li><font class="Apple-style-span" size="3">Loose coupling and clear separation of responsibilities. &nbsp;Just good design practices here.<br />
</font></li>
<li><font class="Apple-style-span" size="3">Ability to swap out different implementations of storage solution. &nbsp;This applies at any level of the persistence package and is not solely related to the use of mongoDB.<br />
</font></li>
</ul>
<div><b><font class="Apple-style-span" size="3">Implementation</font></b><br/><br/></div>
<div><font class="Apple-style-span" size="3">To achieve my design goals, I decided to incorporate the following tools and techniques:</font><br/></div>
<ul>
<li><font class="Apple-style-span" size="3">Google Guice for dependency injection and Aspect Oriented Programming (AOP)</font></li>
<li><font class="Apple-style-span" size="3">Seperation of code into AOPInterceptor, AOPImplementation, PersistenceManager, and WaveStore</font></li>
<li><font class="Apple-style-span" size="3">MongoDB/Schema-free database</font></li>
</ul>
<p><font class="Apple-style-span" size="3">I have </font><a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-1/" id="j8bd" title="previosly written"><font class="Apple-style-span" size="3">previosly written</font></a><font class="Apple-style-span" size="3"> about Wave&#8217;s use of Guice. &nbsp;Another capability of Guice outside of dependency injection is the ability to provide annotations on methods that will act as interceptors. &nbsp;Whenever an annotated method is invoked, Guice will proxy the call and forward execution to a segment of code I have defined. &nbsp;I don&#8217;t want to go over the benefits of AOP in general, so I&#8217;ll just point to the </font><a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" id="h7ag" title="wiki article" target="_blank"><font class="Apple-style-span" size="3">wiki article</font></a><font class="Apple-style-span" size="3"> and the </font><a href="http://code.google.com/p/google-guice/wiki/AOP" id="kkfp" title="Guice AOP site" target="_blank"><font class="Apple-style-span" size="3">Guice AOP site</font></a><font class="Apple-style-span" size="3">.</font><br/><br />
<font class="Apple-style-span" size="3">The reasons I used AOP was to avoid introducing a lot of cross-cutting concerns directly into the code base. &nbsp;With the FedOne code base changing rapidly I did not want to go through great effort restoring my persistence everytime a significant release was made. &nbsp;By using AOP I can just annotate the method and all the work is done in a separate set of classes defined by me. &nbsp;Lastly, I gain great flexibility using AOP. &nbsp;If I decide at some point that it is more efficient to save or restore information at another location, I simply move my annotation and adjust my code for the new set of parameters (which may not be any different since I am probably still storing the same information). &nbsp;In this way there is no refactoring of the main code base. &nbsp;FedOne will continue to function without regard to my update.</font><br/></p>
<div><font class="Apple-style-span" size="3">I provide an activity diagram below to show how the internals of my persistence solution interact. &nbsp;What&#8217;s important at a high-level is the way the components have been separated to allow for localized changes. &nbsp;I am using Guice for dependency injection, so everything is written to interfaces with the subclasses being applied in a separate Module class. &nbsp;This allows me to easily change out an implementation for another in the case of optimizations, changes in course, testing, etc. &nbsp;For example, my persistence modules will still invoke the WaveStore interface if I later decide to switch to Couchdb for a comparison. &nbsp;I simply change WaveStoreMongo to WaveStoreCouch in my Guice binding without the need to update any of my source code.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">A breakdown of responsibilities of each component is as follows:</font><br/></div>
<ul>
<li><i><font class="Apple-style-span" size="3">AOPIntercepter </font></i><font class="Apple-style-span" size="3">- invoked by Guice when an binded annotation is encountered. Responsible for interpreting annotation and forwarding to correct method of </font><i><font class="Apple-style-span" size="3">AOPImplementation</font></i><font class="Apple-style-span" size="3">. &nbsp;This module only has knowledge of the annotation and methods available on the </font><i><font class="Apple-style-span" size="3">AOPImplementation</font></i><font class="Apple-style-span" size="3">. &nbsp;It has no knowledge and takes no action with regards to Wave structures.</font></li>
<li><i><font class="Apple-style-span" size="3">AOPImplementation </font></i><font class="Apple-style-span" size="3">- acts as a bridge between the method invocation passed from the interceptor and the </font><i><font class="Apple-style-span" size="3">PersistenceManager</font></i><font class="Apple-style-span" size="3">. &nbsp;It will extract parameters, invoke the method, and enact the correct method within the </font><i><font class="Apple-style-span" size="3">PersistenceManager </font></i><font class="Apple-style-span" size="3">(not necessarily in that order). &nbsp;It has no knowledge of how the information extracted is used and therefore no knowledge of the underlying </font><i><font class="Apple-style-span" size="3">WaveStore</font></i><font class="Apple-style-span" size="3">.</font></li>
<li><i><font class="Apple-style-span" size="3">PersistenceManager </font></i><font class="Apple-style-span" size="3">- prepares the data passed in for storing or as a key for retrieving values from the </font><i><font class="Apple-style-span" size="3">WaveStore</font></i><font class="Apple-style-span" size="3">. &nbsp;It has no knowledge of its caller (</font><i><font class="Apple-style-span" size="3">AOPImplementation</font></i><font class="Apple-style-span" size="3">) and has no upward dependency. &nbsp;This means that I &nbsp;can easily choose not to use AOP and instead make direct invocations within code by calling the </font><i><font class="Apple-style-span" size="3">PersistenceManager</font></i><font class="Apple-style-span" size="3">. &nbsp;This class is responsible for understanding the wavelet data and its internal structures so that it can be stored efficiently.</font></li>
<li><i><font class="Apple-style-span" size="3">WaveStore </font></i><font class="Apple-style-span" size="3">- acts as a store for serialized information. &nbsp;It has no knowledge of Wave structures, AOP, or the </font><i><font class="Apple-style-span" size="3">PersistenceManager</font></i><font class="Apple-style-span" size="3">. &nbsp;This keeps the interface simple and immune to changes in Wave structures. &nbsp;Any serialization that needs to be done prior to storing information is the responsibility of the </font><i><font class="Apple-style-span" size="3">PersistenceManager</font></i><font class="Apple-style-span" size="3">.&nbsp;</font></li>
</ul>
<p><font class="Apple-style-span" size="3">The following activity diagram illustrates a general interaction (click image to see in full-size):</font></p>
<div id="ghwz" style="text-align:left"><a href="http://www.angleofsight.com/images/wave/persistence.png" target="_blank"><img src="http://www.angleofsight.com/images/wave/persistence.png" style="height:1066.473581px;width:648px"></a><br/><br/></div>
<div><font class="Apple-style-span" size="3">The following is a dependency graph produced by using GraphViz with Guice. &nbsp;You will see the dependencies exist only on generic interfaces such that the implementations may be substituted at any level.  Click on the image to see in full-size.</font><br/><br/></div>
<div id="hwy0" style="text-align:left"><a href="http://www.angleofsight.com/images/wave/WaveDependenciesPersist.png" target="_blank"><img src="http://www.angleofsight.com/images/wave/WaveDependenciesPersist.png" style="height:364.603581px;width:648px"></a><br/><br/></div>
<div><b><font class="Apple-style-span" size="3">Challenges</font></b></div>
<p><font class="Apple-style-span" size="3">I did experience a couple of challenges while implementing persistence. &nbsp;Recall that one of my goals was minimal disruption of the FedOne code base. &nbsp;The framework I established allows for this by and large, but there were still a couple of changes that needed to be made to the FedOne core.</font><br/></p>
<div><font class="Apple-style-span" size="3">If you read my&nbsp;</font><a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-5/" id="eo_h" style="color:#551a8b" title="previous post"><font class="Apple-style-span" size="3">previous post</font></a><font class="Apple-style-span" size="3">&nbsp;on the topic of persistence you will recall that I suggested much of the work of storing and restoring wavelet data could be accomplished in the WaveletContainerImpl class. &nbsp;Perhaps my largest hurdle in implementing persistence within my framework was intercepting the method annotations I placed in this class with Guice. &nbsp;Guice AOP has a restriction that states instances that support method interception must be created by Guice by an @Inject-annotated or no-argument constructor. &nbsp;Both the </font><i><font class="Apple-style-span" size="3">LocalWaveletConatinerImpl</font></i><font class="Apple-style-span" size="3"> and </font><i><font class="Apple-style-span" size="3">RemoteWaveletContainerImpl </font></i><font class="Apple-style-span" size="3">(which both extend </font><i><font class="Apple-style-span" size="3">WaveletContainerImpl</font></i><font class="Apple-style-span" size="3">) are created by a Factory method in </font><i><font class="Apple-style-span" size="3">fedone.waveserver.WaveServerModule </font></i><font class="Apple-style-span" size="3">as:</font></p>
</div>
<div><font class="Apple-style-span" size="3">[code]</font><br/><br/></div>
<div><font class="Apple-style-span" size="2">bind(LocalWaveletContainer.Factory.class).to(LocalWaveletContainerFactory.class)</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.in(Singleton.class);</font></div>
<p></p>
<div><font class="Apple-style-span" size="2">private static class LocalWaveletContainerFactory implements LocalWaveletContainer.Factory {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;@Override</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;public LocalWaveletContainer create(WaveletName waveletName) {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp; &nbsp;return new LocalWaveletContainerImpl(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;}</font></div>
<p>
 &nbsp;&nbsp; &nbsp;invokes</p>
<div>
<div><font class="Apple-style-span" size="2">public LocalWaveletContainerImpl(WaveletName waveletName) {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;super(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;}</font></div>
<p></p>
<div><font class="Apple-style-span" size="2">bind(RemoteWaveletContainer.Factory.class).to(RemoteWaveletContainerFactory.class)</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.in(Singleton.class);</font></div>
<p></p>
<div><font class="Apple-style-span" size="2">private static class RemoteWaveletContainerFactory implements RemoteWaveletContainer.Factory {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;@Override</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;public RemoteWaveletContainer create(WaveletName waveletName) {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp; &nbsp;return new RemoteWaveletContainerImpl(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;}</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;}</font></div>
<p>
 &nbsp;&nbsp;invokes</div>
<div><font class="Apple-style-span" size="2">public RemoteWaveletContainerImpl(WaveletName waveletName) {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;super(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;state = State.LOADING;</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;}</font></div>
<p></p>
<div><font class="Apple-style-span" size="3">[/code]</font></div>
<p><font class="Apple-style-span" size="3"><br />
 Even though the Factory class is binded by Guice, you see that the actual </font><i><font class="Apple-style-span" size="3">LocalWaveletContainerImpl </font></i><font class="Apple-style-span" size="3">and </font><i><font class="Apple-style-span" size="3">RemoteWaveletContainerImpl </font></i><font class="Apple-style-span" size="3">are not created by Guice, thereby negating the possibility of AOP within these classes. &nbsp;After a little bit of research I realized that Guice does provide support for creating objects through Factory methods via its </font><a href="http://code.google.com/p/google-guice/wiki/AssistedInject" id="ohpf" title="@AssistedInject"><i><font class="Apple-style-span" size="3">@AssistedInject</font></i></a><font class="Apple-style-span" size="3"> construct. &nbsp;Using this method the code above became:</p>
<p></font></p>
<div><font class="Apple-style-span" size="3">[code]</font></div>
<p></p>
<div><font class="Apple-style-span" size="2">bind(LocalWaveletContainer.Factory.class).<b>toProvider</b>(FactoryProvider.newFactory(</font></div>
<div>&nbsp;&nbsp; &nbsp; <font class="Apple-style-span" size="2">LocalWaveletContainer.Factory.class, LocalWaveletContainerImpl.class))</font></div>
<div>&nbsp;&nbsp; &nbsp; <font class="Apple-style-span" size="2">.in(Singleton.class);</font></div>
<p></p>
<div>&nbsp;&nbsp;invokes</div>
<p></p>
<div><font class="Apple-style-span" size="2"><b>@Inject</b></font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;public LocalWaveletContainerImpl(<b>@Assisted</b> WaveletName waveletName)&nbsp;</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;{</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;super(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;}</font></div>
<p></p>
<div><font class="Apple-style-span" size="2">bind(RemoteWaveletContainer.Factory.class).<b>toProvider</b>(FactoryProvider.newFactory(</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <font class="Apple-style-span" size="2">RemoteWaveletContainer.Factory.class, RemoteWaveletContainerImpl.class))</font></div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <font class="Apple-style-span" size="2">.in(Singleton.class);</font></div>
<p>
 &nbsp;&nbsp; invokes</p>
<div><font class="Apple-style-span" size="2"><b>@Inject</b></font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;public RemoteWaveletContainerImpl(<b>@Assisted</b>&nbsp;WaveletName waveletName) {</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;super(waveletName);</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp; &nbsp;state = State.LOADING;</font></div>
<div><font class="Apple-style-span" size="2">&nbsp;&nbsp;}</font></div>
<p></p>
<div><font class="Apple-style-span" size="3">[/code]</p>
<p></font></div>
<div><font class="Apple-style-span" size="3">As you can see we reduced the amount of boilerplate code by removing the private Factory classes that contained the create() method. &nbsp;I did not have to modify the code that called the create method in </font><i><font class="Apple-style-span" size="3">WaveServerImpl </font><span class="Apple-style-span" style="font-style:normal"><font class="Apple-style-span" size="3">[</font></span><font class="Apple-style-span" size="2">wc = localWaveletContainerFactory.create(waveletName);</font></i><font class="Apple-style-span" size="3">].&nbsp;</font></div>
<p></p>
<div><font class="Apple-style-span" size="3">Of course, what is most important to me is that Guice now creates the </font><i><font class="Apple-style-span" size="3">RemoteWaveletContainerImpl </font></i><font class="Apple-style-span" size="3">and </font><i><font class="Apple-style-span" size="3">LocalWaveletContainerImpl </font></i><font class="Apple-style-span" size="3">classes thereby allowing me to intercept methods through AOP. &nbsp;Not only does Guice now allow me to intercept the local and remote classes, but I can also add my annotations to the super class </font><i><font class="Apple-style-span" size="3">WaveletContainerImpl</font></i><font class="Apple-style-span" size="3">&nbsp;where the actual commit and restore of wavelet deltas occurs! Yes, I think this is super cool and one reason I am a huge fan of Guice.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">Another issue was deciding exactly what type of information to persist. &nbsp;I had to decide whether I wanted to store only the deltas or attempt also to store the substantive data (e.g. - </font><i><font class="Apple-style-span" size="3">WaveletData</font></i><font class="Apple-style-span" size="3">). &nbsp;I made the decision to only store processual information such that when I load wavelet deltas, I must then apply the underlying operations to seed my data containers. &nbsp;I am quite interested in knowing if Google also stores their data objects along with the deltas.</font><br/><br/></div>
<p><font class="Apple-style-span" size="3">The last significant roadblock was determining all the sections of code that implicitly functioned without regard to persistence. &nbsp;For example, the </font><i><font class="Apple-style-span" size="3">fedone.waveserver.ClientFrontendImpl.PerWavelet</font></i><font class="Apple-style-span" size="3"> and </font><i><font class="Apple-style-span" size="3">fedone.waveserver.UserManager</font></i><font class="Apple-style-span" size="3">&nbsp;are in-memory objects used by the </font><i><font class="Apple-style-span" size="3">ClientFrontendImpl</font></i><font class="Apple-style-span" size="3"> to keep track of the index wave. When the server is restarted these objects are empty. &nbsp;One issue that arises from this is if a remote participant updates a wave hosted by our newly started wave server the delta will be applied and the callback </font><i><font class="Apple-style-span" size="3">ClientFrontendImpl.waveletUpdate()</font></i><font class="Apple-style-span" size="3"> will be invoked. &nbsp;An </font><i><font class="Apple-style-span" size="3">IllegalStateException&nbsp;</font></i><font class="Apple-style-span" size="3">will now occur because the expected version that is pulled from the </font><i><font class="Apple-style-span" size="3">perWavelet</font></i><font class="Apple-style-span" size="3"> object will have a version of 0 while the start version of the delta sequence will be non-zero. &nbsp;From this point the local participants will have a different version from the latest version and will never be able to update the wave again.<br/></font></p>
<div><font class="Apple-style-span" size="3">I don&#8217;t want to delve too far into this topic, but I have serious reservations about the way the index wave is handled, that there are no recovery mechanisms if versions are ever out of sync, and that in the current implementation of FedOne participants must specify an end version (even though the spec indicates it is optional) negating the possibility of restoring with the latest deltas.</font><br/><br/></div>
<div><b><font class="Apple-style-span" size="3">Next Steps</font></b><br/></div>
<p><font class="Apple-style-span" size="3">My goal was to establish a flexible framework for persistence just as much as it was to actually have the ability to store and retrieve information in my wave server. &nbsp;I have many questions regarding the most efficient storage of wavelets and I do not claim that I have chosen the optimal places to store/retrieve information. &nbsp;My hope is that through the framework any modifications I need to make will be clearly defined and concise. &nbsp;For now, I want to do more testing and get feedback on from Google and the community on my strategy for persistence.</font></p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/Ot2Ynaf3vQY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/03/mongowave/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/03/mongowave/</feedburner:origLink></item>
		<item>
		<title>Google Wave’s Federation Protocol Under the Hood, Part 5</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/4CPTBLnO-kE/</link>
		<comments>http://www.angleofsight.com/2010/02/google-wave-federation-part-5/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 19:42:29 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[persistence]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=142</guid>
		<description><![CDATA[Purpose  [Updated 4/3/2010]
This is the fifth and final post in the series dedicated to introducing some of the internals of the FedOne protocol. &#160;As you probably realize, FedOne does not store wavelets to a persistent state. &#160;The goals of this post are to illustrate where the in-memory store takes place and highlight the information [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<div><font class="Apple-style-span" size="3"><br/><b>Purpose  [Updated 4/3/2010]</b></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">This is the fifth and final post in the <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-1/">series </a>dedicated to introducing some of the internals of the FedOne protocol. &nbsp;As you probably realize, FedOne does not store wavelets to a persistent state. &nbsp;The goals of this post are to illustrate where the in-memory store takes place and highlight the information that should be captured in order to restore the state of a wave upon the restart of a server.&nbsp;&nbsp;</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal">The documentation on the Fed protocol states that local AND remote wavelets are all stored in the wave server&#8217;s persistent wave store. &nbsp;In addition to persisting hosted and remote wavelets, the wave server must also maintain additional information related to its clients (covered later). &nbsp;I have provided the following graph to illustrate the structure of the in-memory wavelet storage containers:</span></font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div id="yvzu" style="text-align:left"><img src="http://www.angleofsight.com/images/wave/WaveletContainers.png" style="height:391px;width:567px"></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal">The process of retrieving a wavelet container is initiated in &nbsp; fedone.waveserver.WaveServerImpl.getOrCreateLocalWavelet()</i> and <i>fedone.waveserver.WaveServerImpl.getOrCreateRemoteWavelet()</i>. &nbsp;These methods call <i>localWaveletContainerFactory.create(waveletName)</i> and <i>remoteWaveletContainerFactory.create(waveletName)</i> respectively, which are defined by the <i>fedone.waveserver.ServerModule()</i> Guice Module. &nbsp;This module simply calls the constructors of the <i>fedone.waveserver.LocalWaveletContainerImpl</i> and <i>fedone.waveserver.RemoteWaveletContainerImpl</i> classes. &nbsp;Each of these constructors in turn calls the super constructor of the <i>fedone.waveserver.WaveletContainerImpl</i> class.</span></font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal">Most of the work of persistence can be narrowed down to the <i>fedone.waveserver.WaveletContainerImpl</i> class. &nbsp;Specifically, I suggest checking the persistent store as part of the constructor process, such that if the passed <i>WaveletName</i> is contained in the store, the applied and transformed deltas will be retrieved to seed the Wavelet Container. &nbsp;Wavelet operations can be commited to the store in the <i>commitAppliedDelta()</i> method. &nbsp;Updates in these sections will apply to the <i>fedone.waveserver.LocalWaveletContainerImpl</i> and <i>fedone.waveserver.RemoteWaveletContainerImpl</i>, which both call the <i>fedone.waveserver.WaveletContainerImpl.commitAppliedDelta()</i>. It will be necessary to update these two classes to only invoke the commit method when a commit-notice is received.  It will then be necessary to maintain a set of pending deltas that correspond to wavelet updates that will be dequeued when the corresponding commit-notices are sent (note that this is one strategy of many possibilities).</span></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">It should be noted that in FedOne the <i>RemoteWaveletContainerImpl </i>maintains a set of pending deltas.  This set is populated when it receives a waveletUpdate from a remote Host server. &nbsp;However, <i>commitAppliedDelta() </i>is invoked prior to receiving the the actual commit-notice and the newly applied delta is removed from the queue of pending deltas. &nbsp;When the commit-notice is received by <i>wave.federation.xmpp.XmppFederationRemote.update()</i> it is passed through to the client via <i>fedone.waveserver.ClientFrontendImpl.waveletCommitted()</i>.  Obviously, commit-notice must be handled differently in production.  This is necessary as the wavesandbox currently supports the sending and queuing of hosted wavelets prior to committing and sending the commit-notice.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">The FedOne Host server currently has no mechanisms in place to first queue deltas then commit them at some later time. &nbsp;When a delta is submitted to the <i>LocalWaveletContainer</i>, it is immediately committed through the call to <i>commitAppliedDelta() </i>(please note that it is not actually committed, but it is treated as such and a commit notice is sent to Remote servers as soon as the deltas are applied). &nbsp;The reason wavesandbox queues updates is to optimize latency, however, this does cause a number of issues that are out of the scope of this post. &nbsp;To read more about commit-notice and its implications on the wave server, I suggest following this <a href="http://groups.google.com/group/wave-protocol/browse_thread/thread/fe2786402e72a3e0/c950be174243c411#c950be174243c411" id="o5o1" title="thread" target="_blank">thread</a>&nbsp;on the google group.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">To properly restore the WaveServer at startup, it is also necessary to add persistence to the implementation of the <i>wave.crypto.CertPathStore</i>. &nbsp;The <i>wave.crypto.DefaultCertPathStore</i>&nbsp;notes that this default implementation is in-memory only and will lose certificate chains when the server is shut down.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">Finally, we must provide some persistence for the client. Specifically, we must store information related to the Index Wave</font><font class="Apple-style-span" size="3">. &nbsp;The Index Wave is a lookup that contains all waves a participant has access to. &nbsp;Conceptually, the Index Wave can be thought of as follows:</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div id="ptn_" style="text-align:left"><img src="http://www.angleofsight.com/images/wave/IndexWave.png" style="height:533px;width:570px"></div>
<p><font class="Apple-style-span" size="3"><br />
</font><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">When a user connects to the client, a call is made to <i>fedone.waveserver.ClientFrontendImpl.openRequest()</i> with the Index Wave ID (specified in <i>fedone.common.CommonConstants.INDEX_WAVE_ID</i>). &nbsp;This will request history on all wavelets associated with the Index Wave for the user. &nbsp;As illustrated in the above graphic, the Wavelet ID of the Index Wave is actually a reference to a Wave ID to which the user is a participant.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">In all, the following information should be persisted: The Wavelet identification, Applied Wavelet Deltas, Transformed Wavelet Deltas, Certificate Store, and Index Wave information. &nbsp;These can either be stored in-place (for instance, as a ProtoBuf wrapped object) or the data can be extracted and saved in its native format. &nbsp;</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b>Objects decomposed into native representations</b>&nbsp;(see wave.protocol.common.proto for ProtoBuf based objects)</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">The following is a breakdown of the ProtocolBuffer objects used in FedOne. &nbsp;The syntax is &lt;name&gt;/&lt;type&gt;: { &lt;internals of structure&gt; }.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b><i>ProtocolAppliedWaveletDelta</i></b>: {</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;signed_original_delta/ProtocolSignedDelta: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;delta/bytes(ProtocolWaveletDelta): {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;hashed_version/ProtocolHashedVersion: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;version/int64<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,history_hash/bytes&nbsp;&nbsp; &nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;&nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} //end ProtocolHashVersion</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,author/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,operation/ProtocolWaveletOperation: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp;add_participant/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,remove_participant/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,mutate_document/MutateDocument (see reference for details)<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,no_op/bool<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} //end ProtocolWaveletOperation<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,address_path:String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} //end of ProtocolWaveletDelta<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,signature/ProtocolSignature: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;signature_bytes/bytes<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,signer_id/bytes(ProtocolSignerInfo): {</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;/*The certificates present in a ProtocolSignerInfo are encoded in PkiPath format, and then hashed into signer_id using the hash algorithm indicated in the ProtocolSignerInfo*/</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;hash_algorithm/enum<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,domain:String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,certificate:bytes<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} //end of ProtocolSignerInfo<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,signature_algorithm/enum<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} //end ProtocolSignature<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end ProtocolSignedDelta<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,hashed_version_applied_at/ProtocolHashVersion: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;version/int64<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,history_hash/bytes<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end ProtocolHashVersion<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,operations_applied/int32<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,application_timestamp/int64<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">} //end ProtocolAppliedWaveletDelta</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3"><b><i>ProtocolWaveletDelta for transformedProtocolDelta</i></b>. (The number of operations applied as referenced in the AppliedDelta above reference the operations contained in this transformedProtocolDelta):</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">{ //same as above. repeated here for ease of reference</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;hashed_version/ProtocolHashedVersion: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;version/int64<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;,history_hash/bytes&nbsp;&nbsp; &nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;&nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end ProtocolHashVersion</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,author/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,operation/ProtocolWaveletOperation: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;add_participant/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;,remove_participant/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;,mutate_document/MutateDocument (see reference for details)<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;,no_op/bool<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end ProtocolWaveletOperation<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,address_path:String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">} //end of ProtocolWaveletDelta</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3"><b><i>WaveletName</i></b>: {</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;waveId/WaveId: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;domain/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,id/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end WaveId<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;,waveletId/WaveletId: {<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;domain/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;,id/String<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;} //end WaveletId<br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">} //end WaveletName</font></div>
<p><font class="Apple-style-span" size="3"><b><br />
</b></font></p>
<div><font class="Apple-style-span" size="3"><b><i>&lt;? implements CertPathStore&gt;</i></b> {</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;public SignerInfo get(byte[]);</font><font class="Apple-style-span" size="3"><br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;public void put(ProtocolSignerInfo);</font><font class="Apple-style-span" size="3"><br />
</font></div>
<p><font class="Apple-style-span" size="3"><br />
</font></p>
<div><font class="Apple-style-span" size="3">}</font></div>
<p><font class="Apple-style-span" size="3"><font class="Apple-style-span" size="3"><br />
</font><b>Wrap Up</b></font><br/></p>
<div><font class="Apple-style-span" size="3">I hope this series has been a useful companion to the FedOne documentation. &nbsp;When you really dig into the code as a potential contributer you realize that there is a very complex (yet elegant) architecture under the hood. &nbsp;There was much not covered in this series like the implementation of the OT algorithms or the current (soon to be replaced) client-server protocol. &nbsp;This will not be my last post about the wave protocol, but I figured the 5 posts was enough for an introduction/overview.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b>Further Investigation</b></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">The best place to go for more in-depth information is the code itself. &nbsp;I would also HIGHLY recommend joining the Google User Groups for the FedOne project. &nbsp;There is a wealth of information being shared there on a daily basis.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">A few links if you&#8217;re just getting started:</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><a href="http://code.google.com/p/wave-protocol/wiki/Installation" id="vqaf" title="Installation Instructions">Installation Instructions</a> [http://code.google.com/p/wave-protocol/wiki/Installation]</font></div>
<div><font class="Apple-style-span" size="3"><a href="http://jamespurser.com.au/blog/How_To_-_Install_WRS_On_Windows" id="tmqo" title="Installation Instructions for Windows users">Installation Instructions for Windows users</a> [http://jamespurser.com.au/blog/How_To_-_Install_WRS_On_Windows]</font></div>
<div><font class="Apple-style-span" size="3"><a href="http://groups.google.com/group/wave-protocol/" id="yjc4" title="Wave Protocol Google Group">Wave Protocol Google Group</a> [http://groups.google.com/group/wave-protocol/]</font></div>
<div><font class="Apple-style-span" size="3"><a href="http://groups.google.com/group/wave-protocol-code-discuss" id="iiso" title="Wave Protocol Code Google Group">Wave Protocol Code Google Group</a> (more focused on code reviews and repository updates) [http://groups.google.com/group/wave-protocol-code-discuss]</font></div>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/4CPTBLnO-kE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/google-wave-federation-part-5/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/google-wave-federation-part-5/</feedburner:origLink></item>
		<item>
		<title>Google Wave’s Federation Protocol Under the Hood, Part 4</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/gRYRWzL18VE/</link>
		<comments>http://www.angleofsight.com/2010/02/google-wave-federation-part-4/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 17:26:17 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[wave]]></category>

		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=128</guid>
		<description><![CDATA[
Purpose [Updated 4/3/2010]
This is the fourth post in the series dedicated to exploring the internals of the FedOne architecture. &#160;This post is more a reference that will quickly guide you to the location in code that corresponds to the receipt and execution of an XMPP packet (e.g. History Request IQ Get Packet or a Wavelet [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><font class="Apple-style-span" size="3"><br />
<b>Purpose [Updated 4/3/2010]</b></font></p>
<div><font class="Apple-style-span" size="3">This is the fourth post in the <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-1/">series</a> dedicated to exploring the internals of the FedOne architecture. &nbsp;This post is more a reference that will quickly guide you to the location in code that corresponds to the receipt and execution of an XMPP packet (e.g. <a href="http://www.waveprotocol.org/draft-protocol-specs/draft-protocol-spec#iq-elements-service-stream" id="e819" title="History Request IQ Get Packet">History Request IQ Get Packet</a> or a <a href="http://www.waveprotocol.org/draft-protocol-specs/draft-protocol-spec#wavelet-ops" id="deq3" title="Wavelet Update Message Event">Wavelet Update Message Event</a>). &nbsp;The messages processed are those supported by the FedOne codebase and is not based off of the documentation (not saying anything against the documentation, which I referenced many times. For instance to see examples of successful Packet transmissions). &nbsp;</font></p>
</div>
<div><font class="Apple-style-span" size="3">FedOne was recently updated to introduce more robust error handling mechanisms. &nbsp;You will now find a set of files in the package <i>org.waveprotocol.wave.federation</i>&nbsp;that are dedicated to federation errors. &nbsp;The error codes supported can be found in <i>org.waveprotocol.wave.federation.federation_error.protodevel</i> (note this is the specification, if you want to see the actual .java file, go to proto_src/<i>org.waveprotocol.wave.federation.FederationErrorProto)</i>. Per the documentation, the error codes map to XMPP error stanzas as specified in RFC 3920 (9.3.3). &nbsp;There is also a wrapper <i>FederationErrors.java</i> to make it easy to create the <i>FederationError</i> objects. &nbsp;You will see these used throughout the communication code as a parameter to <i>org.waveprotcol.wave.federation.xmpp.PacketCallaback</i> responses (also used to communicate success). &nbsp;For an example of its use see <i>wave.federation.xmpp.processHistoryRequest().</i></font><br/><br/></div>
<p><font class="Apple-style-span" size="3"><b>Communication Interfaces</b><br />
</font></p>
<div><font class="Apple-style-span" size="3">XMPP communication within the federation protocol occurs in the <font class="Apple-style-span" size="3"><i>org.waveprotocol.wave.federation.xmpp</i> package. &nbsp;All elements related specifically to XMPP (e.g. IQ packets) are read in here and stripped out into neutral formats (well, let&#8217;s count ProtoBuf as neutral). &nbsp;The resulting data is then passed to the wave server for processing. &nbsp;For each operation, I will list the file/method of the XMPP filter along with the file/method within the wave server that processes the data. &nbsp;Please recall that I am focusing on Server to Server communication, however, I will try to list the mirrored methods of the wave server that would be used by the client (e.g. - instead of just listing the server&#8217;s response to an incoming submitRequest, I will attempt to show where a local client would initiate its own submitRequest).</font></p>
</div>
<div><font class="Apple-style-span" size="3">As a preliminary note, all incoming packets are received by <i>receivePacket()</i> in <i>org.waveprotocol.wave.federation.xmpp.XmppManager</i></font></p>
</div>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="hy0e" width="95%">
<tbody>
<tr>
<td colspan="2"><font class="Apple-style-span" size="3"><b>HistoryRequest </b>- received from Federation remote to request wavelet operations from the hosting wave providers.</font></td>
</tr>
<tr>
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Get Packet</font></td>
</tr>
<tr>
<td><font class="Apple-style-span" size="3">XMPP Filter </font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationHost processHistoryRequest() - </i>collect history request data from XMPP IQ packet and pass to Wavelet provider for processing. </font></td>
</tr>
<tr>
<td><font class="Apple-style-span" size="3">WaveServer Handler </font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.WaveServerImpl.requestHistory()</i> - retrieves info for a signer of an applied delta and returns IQ result to foreign remote via <i>fedone.federation.xmpp.XmppFederationHost. HistoryResponsePacketListener.onSuccess()</i>. Note: onFailure currently just logs an error, but does not actually send error back to foreign remote.</font></td>
</tr>
<tr>
<td><font class="Apple-style-span" size="3">WaveServer Mirror</font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.WaveServerImpl.requestHistory()</i> - gets the transformed history for a wavelet and returns to caller. Note this call is overloaded, so it is not the same method as above.</font></td>
</tr>
</tbody>
</table>
<p><u><font class="Apple-style-span" size="3"><br />
</font></u></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="t1fa" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>SignerRequest </b>- received from Federation remote to request certificates for wavelets where the signer is unknown. &nbsp;Request sent to host wave providers.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Get Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationHost.  processGetSignerRequest()</i> - collect signer request data from XMPP IQ packet and pass to Wavelet provider for processing.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.WaveServerImpl.getDeltaSignerInfo()</i> - retrieves delta history for a given wavelet and returns info to listener via <i>wave.federation.xmpp.XmppFederationHost. DeltaSignerInfoPacketListener.onSuccess()</i> or <i> .onFailure()</i>.</font></td>
</tr>
</tbody>
</table>
<p><u><font class="Apple-style-span" size="3"><br />
</font></u></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="s.n5" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>DiscoveryInfoRequest (Disco)&nbsp;</b>- received from foreign source to get info on what we support. &nbsp;Will send back message saying we are Wave Component.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Get Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppDisco.processDiscoInfoGet() - </i>handles discovery info get. Will send back message identifying server as a Wave Server.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="m3mb" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>DiscoveryItemRequest (Disco)</b>&nbsp;</font><font class="Apple-style-span" size="3">- received from foreign source to get disco items. &nbsp;No defined use within Wave.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Get Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><font class="Apple-style-span" size="3"><i>wave.federation.xmpp.XmppDisco. processDiscoItemsGet()</i> - </font><font class="Apple-style-span" size="3">handles discovery item get. Will send back copy of message in response.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A<br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="iiuj" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>errorCallback</b></font>&nbsp;<font class="Apple-style-span" size="3">- when the WaveServer sends a packet, it has the option of specifying an error callback in the case the host or remote responds with an error.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Error Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><span class="Apple-style-span" style="font-style:normal"><font class="Apple-style-span" size="3">&nbsp;wave.federatoin.xmpp.XmppManager.response() -&nbsp;</font><font class="Apple-style-span" size="3">on an error packet, checks to see if there is a callback defined.</font></span></font></i></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A<br />
</font><font class="Apple-style-span" size="3"><br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="rbhk" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>MessageReceived</b>&nbsp;</font><font class="Apple-style-span" size="3">- received from Federation remote to acknowledge an update.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">Message Received Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><font class="Apple-style-span" size="3"> <i>wave.federatoin.xmpp.XmppManager.response()</i> - handles Wavelet Update Response by sending packet to callback handler.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A<br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="ydu3" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>MessageEvent (update)</b></font>&nbsp;<font class="Apple-style-span" size="3">- received from Federation Host to Federation Remote to update a wavelet.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">Message Event Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal"> wave.federation.xmpp.XmppFederationRemote.</span>update() - <span class="Apple-style-span" style="font-style:normal">Parses update message. Creates a latched callback that is invoked when all deltas of all wavelet updates are applied. Also parses final commit notice if one is given.</span></font></i></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.WaveServerImpl.listenerForDomain(). waveletDeltaUpdate() </i>- get and check state of wavelet. &nbsp;Place deltas in ProtoBuf and get/create remoteWavelet to update.<i>&nbsp;</p>
<p><font class="Apple-style-span" size="3">fedone.waveserver.WaveServerImpl.listenerForDomain(). waveletCommitUpdate()</font><span class="Apple-style-span" style="font-style:normal">&nbsp; - notify client listener that update has been persisted and they can release any resources held for update (of course since there is no persistence we&#8217;re just telling lies)<br />
<font class="Apple-style-span" size="3"><br />
 fedone.waveserver.RemoteWaveletContainerImpl.update()&nbsp;<span class="Apple-style-span" style="font-style:normal">- pre-fetch all the signers and run the internalUpdate.</span></font></span></i></font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="kb4j" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>Message Ping</b></font>&nbsp;<font class="Apple-style-span" size="3">- provide evidence of available service.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">Message Ping Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal"> wave.federation.xmpp.XmppManager.</span>processMessage()<span class="Apple-style-span" style="font-style:normal"> - adds receipt to response and sends back to requestor</span></font></i><font class="Apple-style-span" size="3">.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A</font><font class="Apple-style-span" size="3"><br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="fb7r" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>DiscoveryInfoResult (Disco</b>)&nbsp;</font><font class="Apple-style-span" size="3">- handles disco info result for remote JID and triggers callback.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Result Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><i><font class="Apple-style-span" size="3">wave.federation.xmpp.XmppManager.response()<span class="Apple-style-span" style="font-style:normal">&nbsp;- forwards to callback hander defined in<br />
</span><br />
<i>PacketCallback.run()</i> of <i>wave.federation.xmpp.RemoteDisco. requestDiscoInfo()</i> - receives response from a disco info request to a specific target JID (supports wave) and processes in&nbsp; </font><font class="Apple-style-span" size="3"><br />
<font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.RemoteDisco.finish()</i> - if we find the remote JID, execute the callback functions that were set in <i>wave.federation.xmpp.RemoteDisco.discoverRmoteJID()</i>.</font></font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A<br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="l1i6" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>DiscoveryItemResult (Disco</b></font><font class="Apple-style-span" size="3">)&nbsp;</font><font class="Apple-style-span" size="3">- handles disco item response from remote JID and triggers callback.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Result Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><font class="Apple-style-span" size="3"><font class="Apple-style-span" size="3"><i>wave.federation.xmpp.XmppManager.response()</i> - forwards to callback hander defined in<br />
<i>PacketCallback.run()</i> of wave.federation.xmpp.RemoteDisco.startDisco() that calls<br />
</font><br />
<i>wave.federation.xmpp.RemoteDisco.processDiscoItemsResult()</i> - process disco item results executing <i>requestDiscoInfo()</i> to see if any are wave servers. </font></span></i></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3">N/A<br />
</font><font class="Apple-style-span" size="3"><br />
</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="bvgs" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>HistoryResult&nbsp;</b></font><font class="Apple-style-span" size="3">- foreign Federation Host sending history response.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Result Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter&nbsp;</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationRemote .processHistoryRequest()</i> - receives history request response packet, decodes it and calls wave server. [this is defined as the <i>PacketCallback</i> in <i>wave.federation.xmpp.XmppFederationRemote. requestHistory()</i>]</td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.RemoteWaveletContainerImpl.internalUpdate()</i> [<i>onSuccess()</i> method defined in <i>federationProvider.requestHistory()</i> call] - converts deltas into ProtoBuf format and calls<br />
<i>fedone.waveserver.RemoteWaveletContainerImpl.update()</i> - pre-fetches signer info and calls<br />
fedone.waveserver.RemoteWaveletContainerImpl.internalUpdate() [note, first reference to this function above was not actually direct call. &nbsp;What was called was the <i>onSuccess()</i> method that was defined as a parameter in the <i>requestHistory()</i> method, so there is no recursion here] - applies deltas received from foreign Federation Host.</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="b0yd" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>SubmitResponse&nbsp;</b></font><font class="Apple-style-span" size="3">- handles response from a submit request</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Result Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter&nbsp;</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationRemote. processSubmitResponse()</i> receives submit response response packet, decodes it and calls wave server callback. [defined in <i>PacketCallback.run()</i> of <i>wave.federation.xmpp.XmppFederationRemote.submitRequest()</i>]</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><i><span class="Apple-style-span" style="font-style:normal"><span class="Apple-style-span" style="font-style:normal"><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal">not really implemented in FedOne or by the WaveServer. &nbsp;The responsibility of handling a submit response does not necessarily fall to the Federation Remote since it does not host the wave. &nbsp;We should store the applied deltas, but the client will ultimately handle this response. &nbsp;This is done at a very basic level in the FedOne at </span>fedone.waveclient.common.ClientBackend. sendAndAwaitWaveletDelta()<span class="Apple-style-span" style="font-style:normal">.</span><br />
</font></span></span></i></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="s:vu" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>PostSignerResponse&nbsp;</b></font><font class="Apple-style-span" size="3">- ACK from foreign Host server in response to certificate chain sent to authenticate wave delta. &nbsp;This must be done first time before sending any wave delta.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Get Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationHost. WaveletFederationProvider. DeltaSignerInfoResponseListenter()</i> - receives post signer response packet, decodes it and calls wave server callback.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><font class="Apple-style-span" size="3"><i>fedone.waveserver.WaveServerImpl.submitDelta() [callback defined as parameter in <i>postAllSignerInfo()</i> method] - logs success and then uses Federation Remote to submit request.</font></td>
</tr>
</tbody>
</table>
<p><i><b><font class="Apple-style-span" size="3"><br />
</font></b></i></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="hu43" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>SubmitRequest&nbsp;</b></font><font class="Apple-style-span" size="3">- handles a submit request from a foreign Remote server</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Set Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter&nbsp;</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationHost. processSubmitRequest()</i> - receives submit request packet, decodes it and calls wave server callback. </font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><i><span class="Apple-style-span" style="font-style:normal"><span class="Apple-style-span" style="font-style:normal"><font class="Apple-style-span" size="3">fedone.waveserver.WaveServerImpl.submitRequest() <span class="Apple-style-span" style="font-style:normal">- ensures delta is properly signed and meets preconditions to be applied, then submits delta calling:<br />
<font class="Apple-style-span" size="3">fedone.waveserver.WaveServerImpl.submitDelta()&nbsp;<span class="Apple-style-span" style="font-style:normal">- submits delta to local or remote wavelets (remote first sends signatures then delta) , broadcast updates to Federation Hosts and Client. &nbsp;Returns result via listener.</span></font></span></font></span></span></i></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Mirror</font></td>
<td><i><font class="Apple-style-span" size="3">fedone.waveserver.WaveServerImpl.submitRequest()</font></i><font class="Apple-style-span" size="3"> - signs the delta and calls:<br />
<i>fedone.waveserver.WaveServerImpl.submitDelta()</i> - submits delta to local or remote wavelets and returns result to listener</font></td>
</tr>
</tbody>
</table>
<p><b><font class="Apple-style-span" size="3"><br />
</font></b></p>
<table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="t8yc" width="95%">
<tbody>
<tr style="text-align:left">
<td colspan="2"><font class="Apple-style-span" size="3"><b>PostSignerRequest&nbsp;</b></font><font class="Apple-style-span" size="3">- Signer info from foreign Remote to be stored prior to receiving and applying deltas.</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">Packet Type</font></td>
<td><font class="Apple-style-span" size="3">IQ Set Packet</font></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">XMPP Filter</font></td>
<td><font class="Apple-style-span" size="3"> <i>wave.federation.xmpp.XmppFederationHost. processPostSignerRequest()</i> - receives post signer request packet, decodes it and calls wave server. </font></i></td>
</tr>
<tr style="text-align:left">
<td><font class="Apple-style-span" size="3">WaveServer Handler</font></td>
<td><i><font class="Apple-style-span" size="3">fedone.waveserver.WaveServerImpl.postSignerInfo()<span class="Apple-style-span" style="font-style:normal">&nbsp;</span></font><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-style:normal">- stores signer info with CertificateManager.</span><br />
</font></i></td>
</tr>
</tbody>
</table>
<p><font class="Apple-style-span" size="3"><b><br />
</b></font></p>
<div><font class="Apple-style-span" size="3"><b>Next In Series</b></font></p>
</div>
<p><font class="Apple-style-span" size="3">The <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-5/">next post</a> will be focused on Persistence. &nbsp;I will highlight where the local in-memory store occurs and hopefully point out the correct areas to implement persistence if you so choose.<br />
</font></p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/gRYRWzL18VE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/google-wave-federation-part-4/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/google-wave-federation-part-4/</feedburner:origLink></item>
		<item>
		<title>Google Wave’s Federation Protocol Under the Hood, Part 3</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/q3w2Gimd2J4/</link>
		<comments>http://www.angleofsight.com/2010/02/google-wave-federation-part-3/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 16:18:59 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[guice]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=108</guid>
		<description><![CDATA[
Purpose [Updated 4/3/2010]
This is the third post in the series dedicated to the design of FedOne. &#160;I am taking a quick aside to show the dependency object graph as managed by Guice. &#160;I found it quite interesting to view a picture of how many of the components were associated. &#160;There are dependencies that are not [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-1/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 1'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 1</a> <small> Purpose [Updated 4/3/2010] This post is the first in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-2/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 2'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 2</a> <small>Purpose [Updated 4/3/2010] This post is the second in a...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>
<font class="Apple-style-span" size="3"><b>Purpose [Updated 4/3/2010]</b></font></p>
<div><font class="Apple-style-span" size="3">This is the third post in the <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-1/">series</a> dedicated to the design of FedOne. &nbsp;I am taking a quick aside to show the dependency object graph as managed by Guice. &nbsp;I found it quite interesting to view a picture of how many of the components were associated. &nbsp;There are dependencies that are not captured by Guice and are therefore not present in the graph, however, I would suggest that the areas where dependency injection was used are most likely suitable for alternative implementations (if you decide to develop your own wave server).</font></p>
</div>
<div><font class="Apple-style-span" size="3"><b>Dependency Object Graph</b></font></p>
</div>
<div><font class="Apple-style-span" size="3">It became apparent upon creating the Activity Diagram that it would be helpful to illustrate the dependencies as resolved by Guice. &nbsp;Guice 2.0 has a Grapher module that will produce a <i>.dot</i> file that can be visualized with GraphViz. &nbsp;<a href="http://code.google.com/docreader/#p=google-guice&amp;s=google-guice&amp;t=Grapher" id="d1c2" title="Read Instructions here">Read Instructions here</a>.</font><font class="Apple-style-span" size="3">&nbsp;&nbsp;However, Grapher is an extension that is NOT bundled with Wave or the pre-compiled Guice libraries, so you will have to download Guice src and build Grapher (located in extension/grapher).</font></p>
</div>
<div><font class="Apple-style-span" size="3">Following is the complete image (click image to open new window at full-size) ran on my Wave Server.</font>
</div>
<div style="text-align:left"><a href="http://www.angleofsight.com/images/wave/WaveDependencies2.png" target="_blank"><img src="http://www.angleofsight.com/images/wave/WaveDependencies2.png" style="height:319.808px;width:530px"></a></p>
</div>
<div><font class="Apple-style-span" size="3"><u>Legend</u></font></p>
</div>
<div><font class="Apple-style-span" size="3">Nodes:</font></div>
<ul>
<li><font class="Apple-style-span" size="3">Dashed Nodes are Interfaces or Abstract Classes</font></li>
<li><font class="Apple-style-span" size="3">Black backgrounds denote Implementation types</font></li>
<li><font class="Apple-style-span" size="3">Gray backgrounds denote Implementation Instances</font></li>
</ul>
<div><font class="Apple-style-span" size="3">Edges:</font></div>
<ul>
<li><font class="Apple-style-span" size="3">Solid edges represent dependencies (think the parameters of a constructor)</font></li>
<li><font class="Apple-style-span" size="3">Dashed edges represent bindings from types to their implementations (think subclasses or implementation of an interface)</font></li>
<li><font class="Apple-style-span" size="3">Double arrows represent that the binding or dependency is to a Provider (Provider is a Guice construct)</font></li>
</ul>
<div><font class="Apple-style-span" size="3">I will focus on one aspect of the object graph to demonstrate how Guice is utilized and why viewing the dependencies may not be straightforward at first glance.</font></p>
</div>
<div><font class="Apple-style-span" size="3">The following image illustrates the instantiation of the <i>ProtocolWaveClient</i> interface. &nbsp;I will only traverse to the 3rd dependency at <i>ClientFrontEndImpl</i>.</font></p>
</div>
<div style="text-align:left"><a href="http://www.angleofsight.com/images/wave/WaveDependencies_ProtocolWaveClientRPC.png" target="_blank"><img src="http://www.angleofsight.com/images/wave/WaveDependencies_ProtocolWaveClientRPC.png"></a></div>
<p></p>
<div><font class="Apple-style-span" size="3">In the <i>run()</i> method of <i>fedone.ServerMain</i> you will find:</font></p>
</div>
<div><font class="Apple-style-span" size="3">[code]</font></div>
<div><font class="Apple-style-span" size="3">Injector injector = Guice.createInjector(new ServerModule(), flags);</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&#8230;</font></div>
<div><font class="Apple-style-span" size="3">ProtocolWaveClientRpc.Interface rpcImpl = injector.getInstance(</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ProtocolWaveClientRpc.Interface.class);</font></div>
<div><font class="Apple-style-span" size="3">[/code]</font></p>
</div>
<div><font class="Apple-style-span" size="3">The <i>injector.getInstance(ProtocolWaveClientRpc.Interface.class)</i> requests Guice to find the associated dependency, which we can see from the graph is satisfied by <i>WaveClientRpcImpl</i>. &nbsp;To see how this connection is made, we will examine the first line in the <i>run()</i> method that created the injector [<i>Guice.createInjector(new ServerModule(), flags)</i>].</font></p>
</div>
<div><font class="Apple-style-span" size="3">In the <i>configure()</i> method of <i>fedone.ServerModule()</i>, we find:</font></p>
</div>
<div><font class="Apple-style-span" size="3">[code]</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;// Receive updates from the outside world, and push them into our local Wave Server.</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;bind(WaveletFederationListener.Factory.class).annotatedWith(FederationRemoteBridge.class)</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.to(WaveServer.class);</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&#8230;</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;install(new WaveServerModule());</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;bind(String.class).annotatedWith(Names.named(&#8221;privateKey&#8221;)).toInstance(&#8221;");</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;&#8230;</font></div>
<div><font class="Apple-style-span" size="3">[/code]</font></p>
</div>
<div><font class="Apple-style-span" size="3">Since we do not find a binding associated with <i>ProtocolWaveClientRpc</i> in this <i>configure()</i> method, we will step into the <i>configure()</i> method of <i>fedone.waveserver.WaveServerModule()</i> (note we are in a different package). &nbsp;Here we find:</font></p>
</div>
<div><font class="Apple-style-span" size="3">[code]</font></div>
<div><font class="Apple-style-span" size="3"> &nbsp;bind(CertPathStore.class).to(DefaultCertPathStore.class).in(Singleton.class); </font></div>
<div><font class="Apple-style-span" size="3"> &nbsp;&nbsp; &nbsp;&#8230; </font></div>
<div><font class="Apple-style-span" size="3"> &nbsp;&nbsp; &nbsp;bind(ClientFrontend.class).to(ClientFrontendImpl.class).in(Singleton.class); </font></div>
<div><font class="Apple-style-span" size="3"> &nbsp;&nbsp; &nbsp;bind(ProtocolWaveClientRpc.Interface.class).to(WaveClientRpcImpl.class).in(Singleton.class); </font></div>
<div><font class="Apple-style-span" size="3"> &nbsp;&nbsp; &nbsp;&#8230; </font></div>
<div><font class="Apple-style-span" size="3">[/code]</font></p>
</div>
<div><font class="Apple-style-span" size="3">Now we see the bind statement that creates the actual dependency to the <i>WaveClientRpcImpl</i> class (which btw is a Singleton class). &nbsp;The resolution does not end here since stepping into the constructor of the <i>fedone.waveserver.WaveClientRpcImpl</i> class reveals a dependency on <i>ClientFrontend</i>:</font></p>
</div>
<div><font class="Apple-style-span" size="3">[code]</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;/**</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; * Constructor.</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; *</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; * @param frontend ClientFrontend that consumes the operations.</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; */</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;@Inject</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;public WaveClientRpcImpl(ClientFrontend frontend) {</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp; &nbsp;this.frontend = frontend;</font></div>
<div><font class="Apple-style-span" size="3">&nbsp;&nbsp;}</font></div>
<div><font class="Apple-style-span" size="3">[/code]</font></p>
</div>
<div><font class="Apple-style-span" size="3">Since we see the <i>@Inject</i> annotation, we know that Guice will provide this value as well. &nbsp;Since we are still in the path of the same Injector that was originally created I will look back into either the flag, <i>ServerModule</i>, or <i>WaveServerModule</i> modules. &nbsp;Since <i>ClientFrontend</i> is a class in <i>fedone.waveserver</i>, we expect and do indeed find the binding in the <i>configure()</i> method of <i>fedone.waveserver.WaveServerModule()</i>. &nbsp;This is denoted above in the excerpt of that class [<i>bind(ClientFrontend.class).to(ClientFrontendImpl.class).in(Singleton.class);</i>]. I will stop here, but you will also note from the graph or if you explore <i>ClientFrontendImpl</i> that there is another dependency within the constructor that calls for a <i>WaveletProvider</i>, which Guice must also resolve.</font></p>
</div>
<div><font class="Apple-style-span" size="3">I can hear some of you now saying &#8220;OMG, there are so many levels of indirection. &nbsp;Why would you ever do this?&#8221;. &nbsp;First I would point out that our dependencies exist regardless of using Guice. &nbsp;Usually these dependencies are just littered throughout the code making it more difficult to locate and switch to different implementations. &nbsp;Guice takes these bindings and places them in defined areas that, once you are familiar with Guice and the codebase, can be located fairly easily. &nbsp;This makes testing more efficient as bindings can be switched without much effort. &nbsp;As you have seen, object graphs can be created which will illustrate dependencies within your code managed by Guice giving you a better overall understanding of the structure of your project. &nbsp;Guice is also typesafe such that at compile time you will know if a binding was left out or applied incorrectly.</font></p>
</div>
<div><font class="Apple-style-span" size="3">If you are curious where the command line Flags are used within Wave, just take a look at the object graph. &nbsp;Since they are instances they will be located in gray nodes and will tell you the java File and line number where it was resolved as well as the value passed in. &nbsp;For instance, the <i>ComponentPacketTransport</i> uses several.</font></p>
</div>
<div style="text-align:left"><a href="http://www.angleofsight.com/images/wave/WaveDependencies_WaveXMPP2.png" target="_blank"><img src="http://www.angleofsight.com/images/wave/WaveDependencies_WaveXMPP2.png"></a></p>
</div>
<p><font class="Apple-style-span" size="3"><b>Next in Series</b></font></p>
<div><font class="Apple-style-span" size="3">The <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-4/">next post</a> investigates the XMPP to WaveServer communication methods. &nbsp;All methods related to incoming or outgoing packets through XMPP will be covered as implemented in code (as opposed to what is documented).</font></div>
<p></p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-1/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 1'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 1</a> <small> Purpose [Updated 4/3/2010] This post is the first in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-2/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 2'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 2</a> <small>Purpose [Updated 4/3/2010] This post is the second in a...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/q3w2Gimd2J4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/google-wave-federation-part-3/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/google-wave-federation-part-3/</feedburner:origLink></item>
		<item>
		<title>Google Wave’s Federation Protocol Under the Hood, Part 2</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/zltD1NWfKBA/</link>
		<comments>http://www.angleofsight.com/2010/02/google-wave-federation-part-2/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 15:42:37 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[startup]]></category>

		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=81</guid>
		<description><![CDATA[Purpose [Updated 4/3/2010]
This post is the second in a series aimed at understanding the internals of the FedOne protocol. &#160;I will focus on the startup process in this post. Specifically, the classes and packages involved coupled with how they interact. &#160;If you are not familiar with Guice, I recommend reading the first post in this [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<div><font class="Apple-style-span" size="3"><br/><b>Purpose [Updated 4/3/2010]</b><br/><br/></font></div>
<div><font class="Apple-style-span" size="3">This post is the second in a series aimed at understanding the internals of the FedOne protocol. &nbsp;I will focus on the startup process in this post. Specifically, the classes and packages involved coupled with how they interact. &nbsp;If you are not familiar with Guice, I recommend reading the <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-1/">first post</a> in this series, which covers pre-requisites to understanding the FedOne codebase. </font></div>
<p><font class="Apple-style-span" size="3"><br/><b>Startup Process </b><br /></font></p>
<div><font class="Apple-style-span" size="3">When you startup your Wave server, you may use a command that resembles the following: <br /></font></div>
<div><font class="Apple-style-span" size="2">java -jar dist/fedone-server-0.2.jar &#8211;client_frontend_hostname=127.0.0.1 &#8211;client_frontend_port=5222 &#8211;xmpp_component_name=wave &#8211;xmpp_server_hostname=%XMPP_SERVER_HOSTNAME% &#8211;xmpp_server_ip=%XMPP_SERVER_IP% &#8211;xmpp_server_port=5275 &#8211;xmpp_server_secret=%XMPP_SERVER_SECRET% &#8211;xmpp_server_ping=&#8221;acmewave.com&#8221; &#8211;certificate_private_key=%PRIVATE_KEY_FILENAME% &#8211;certificate_files=%CERTIFICATE_FILENAME_LIST% &#8211;certificate_domain=%CERTIFICATE_DOMAIN_NAME% &#8211;waveserver_disable_verification=true &#8211;waveserver_disable_signer_verification=true &#8211;xmpp_jid<font class="Apple-style-span" size="2">=wave.%WAVE_SERVER_DOMAIN_NAME% &#8211;xmpp_server_description=&#8221;FedOne</font>&#8220;</font></div>
<p><font class="Apple-style-span" size="3">This startup command maps to <i>ServerMain.java</i> within the package <i>org.waveprotocol.wave.examples.fedone</i> (until otherwise specified, all files I list are housed within this package). &nbsp;The flags that are passed via the command are specified in <i>FlagSettings.java</i>. &nbsp;There you will see the annotation <i>@Flag</i> (specified in <i>Flag.java</i>). &nbsp;The <i>main()</i> method of <i>ServerMain.java</i> calls <i>FlagBinder.java</i> to read in the Flags and validate them against the allowable values as specified in <i>FlagSettings.java</i>. &nbsp;<i>FlagBinder</i> then returns an injectable Guice module which is used by the Injector in the <i>run()</i> method. &nbsp;</p>
<p> The above describes how the command line arguments are propagated throughout FedOne. &nbsp;The following Activity Diagram illustrates the complete startup process (click image to see full-size).</font></p>
<div><a href="http://www.angleofsight.com/images/wave/WaveStartup2.png" target="_blank"><img alt="" src="http://www.angleofsight.com/images/wave/WaveStartup2.png" style="height:1069.61px;width:540px"></a> <font class="Apple-style-span" size="3"> <b>Next In Series</b></font> <font class="Apple-style-span" size="3">The <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-3/">next post</a> will cover some of the dependencies in the FedOne code (those managed by Guice). &nbsp;I will show a diagram of the dependencies in the GraphViz tool using a data file produced by the Grapher extension of Guice.</font>
</div>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-5/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 5'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 5</a> <small>Purpose [Updated 4/3/2010] This is the fifth and final post...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-4/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 4'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 4</a> <small> Purpose [Updated 4/3/2010] This is the fourth post in...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/zltD1NWfKBA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/google-wave-federation-part-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/google-wave-federation-part-2/</feedburner:origLink></item>
		<item>
		<title>Google Wave’s Federation Protocol Under the Hood, Part 1</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/lO4AnUu7nek/</link>
		<comments>http://www.angleofsight.com/2010/02/google-wave-federation-part-1/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 23:59:08 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Google Wave]]></category>

		<category><![CDATA[Blogs2]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[guice]]></category>

		<category><![CDATA[protobuf]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=68</guid>
		<description><![CDATA[

Purpose [Updated 4/3/2010]

This post is the first in a series intended to cover the basics of how the FedOne project as released by Google is designed and implemented in code. &#160;I could not find a guide that covered the internal architecture and namespaces, which left me sifting through approximately 200 files in 30 packages to [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-2/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 2'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 2</a> <small>Purpose [Updated 4/3/2010] This post is the second in a...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>
<img id="l7q3" src="http://www.angleofsight.com/images/wave/google_wave_logo.jpg" style="float:left;margin-left:0px;margin-right:1em"></p>
<div><font class="Apple-style-span" size="3"><b>Purpose [Updated 4/3/2010]</b></font></p>
</div>
<div><font class="Apple-style-span" size="3">This post is the first in a series intended to cover the basics of how the FedOne project as released by Google is designed and implemented in code. &nbsp;I could not find a guide that covered the internal architecture and namespaces, which left me sifting through approximately 200 files in 30 packages to gain an understanding that allowed me to modify and contribute code. &nbsp;In addition, I was not familiar with some of the Google technologies employed (e.g. - Guice and ProtoBuf). &nbsp;Since we are exploring the use of Wave at my company, I thought it would be helpful to our engineers to write up an overview. &nbsp;Hopefully, as you read this you will find it useful as well.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">I do not intend to write an exposition on every package or file. &nbsp;There will be many topics left uncovered or as I like to think of it many opportunities for others to expand upon this post :). &nbsp; &nbsp;I plan to highlight the topics that will give those new to the project/code a push in the right direction. &nbsp;My current intention in this series is to cover prerequisites to examining the code, the startup process, dependencies as captured by Guice, the XMPP to WaveServer communication, and Persistence. &nbsp;Other topics such as the Client-Server protocol or the OT algorithm itself will not be addressed (at least at this time).</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b>Audience</b></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">This post is targeted specifically to developers and technical managers. &nbsp;No effort has been made to abstract the technical implementations or figures into high-level concepts. &nbsp;Furthermore, I assume the reader has an understanding of Google Wave in general and more specifically the Google Wave FedOne project. &nbsp;</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">For an introduction to Google Wave, I recommend:</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><a href="http://wave.google.com/help/wave/about.html" id="p0ut" title="About Wave [http://wave.google.com/help/wave/about.html]">About Wave</a>&nbsp;[http://wave.google.com/help/wave/about.html]</font></div>
<div><font class="Apple-style-span" size="3"><a href="http://en.wikipedia.org/wiki/Google_Wave" id="ahmw" title="Google Wave Wikipedia Entry">Google Wave Wikipedia Entry</a>&nbsp;[http://en.wikipedia.org/wiki/Google_Wave]</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">For an introduction to the FedOne Project see:</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><a href="http://www.waveprotocol.org/" id="izrc" title="Wave Federation Home">Wave Federation Home</a> [http://www.waveprotocol.org/]</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b>Prerequisites</b></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">An understanding of a couple of Google technologies used will make it much easier to follow the FedOne code base. &nbsp;These are Guice and Protocol Buffers.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><u>Guice&nbsp;</u></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">You will quickly get lost in the code without an understanding of Guice and how it is used. &nbsp;Guice is a lightweight dependency injection technology used and open sourced by Google. &nbsp;It allows for the decoupling of dependencies in code that are created when direct calls are made to constructors of external Classes. &nbsp;The Guice technology has many benefits and applications, but we&#8217;ll focus on the ease of switching out implementations of an algorithm that are present in different subclasses (think Template pattern as defined by the Gang of Four). &nbsp;What you need to know at a base level (and I posit you need more) is that when you see an <i>@Inject</i> annotation, the parameters that follow will be looked up and supplied by Guice at or prior to runtime. &nbsp;Guice does this by defining bindings in a separate Module from an Abstract class to a subclass. &nbsp;A Guice injector is then created from that Module and the specified dependency (Subclass) is injected when an Instance of the Base Class is requested. &nbsp;Clear as mud? &nbsp;Yes, you really need to read about Guice separately from this discussion.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3">The reason I even broached the topic of Guice is because while dependency injection is an incredibly useful technique it does have the downside that it can often be difficult to track the class/values that are actually being applied at runtime. &nbsp;Using an example from the Guice site, a constructor may have a <i>BillingService</i> class that is implemented by <i>RealCreditCardBillingService</i> and <i>FakeCreditCardBillingService</i>. &nbsp;Since the binding to one of the subclasses is specified in a separate file and is constructed by Guice, you may have difficulty when you&#8217;re testing to realize that <i>RealCreditCardBilling</i> is still being used. &nbsp;If you set up your Guice bindings in your own project, you&#8217;ll probably be familiar with where these settings are located, but if you&#8217;re looking at another Project for the first time that has 200 files over 30 packages it can be difficult. &nbsp;For instance, the <i>ComponentPacketTransport.java</i>&nbsp;within <i>org.waveprotocol.wave.federation.xmpp</i> package contains <i>@Named</i> annnotations for parameters that are supplied by <i>FlagBinder.java</i> in <i>org.waveprotocol.wave.examples.fedone</i>. &nbsp;There is a Graph extension that allows you to view the dependency linkings, however, that is not released within FedOne. I will show an output of this tool on FedOne in a later post to this series. </font><br/><br/></div>
<div><font class="Apple-style-span" size="3">To read more on Guice, I recommend you <a href="http://code.google.com/p/google-guice/" id="r092" title="watch the video">watch the video</a> and <a href="http://code.google.com/docreader/#p=google-guice&amp;s=google-guice&amp;t=UsersGuide" id="th-h" title="read the user guide">read the user guide</a>. &nbsp;There are other uses within FedOne (e.g. - scoping) that I did not cover above.</font><br/><br/></div>
<div><font class="Apple-style-span" size="3"><u>Protocol Buffers (often referred to as protobufs)</u></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">Protobufs are used by Google to serialize structured data for storage and transmission. &nbsp;The data structure you wish to emulate in Java (or C++ and Python) is specified in a <i>.proto</i> file, which the Proto compiler then uses to generate code allowing an object with that structure to be constructed in Java. &nbsp;The Proto compiler also adds a number of other methods such as getter, setter, and exist methods. &nbsp;The benefit of the ProtoBufer is the simplicity, size and speed of the resulting code. &nbsp;To use an example from the Protobuf site, accessing data from XML may require the developer to write&nbsp;<i><font class="Apple-style-span" size="3">person</font><font class="Apple-style-span" size="3">.</font><font class="Apple-style-span" size="3">getElementsByTagName</font><font class="Apple-style-span" size="3">(</font><span class="str Apple-style-span"><font class="Apple-style-span" size="3">&#8220;name&#8221;</font></span><span class="pun Apple-style-span"><font class="Apple-style-span" size="3">)-&gt;</font></span><span class="pln Apple-style-span"><font class="Apple-style-span" size="3">item</font></span><span class="pun Apple-style-span"><font class="Apple-style-span" size="3">(</font></span><span class="lit Apple-style-span"><font class="Apple-style-span" size="3">0</font></span><span class="pun Apple-style-span"><font class="Apple-style-span" size="3">)-&gt;</font></span><span class="pln Apple-style-span"><font class="Apple-style-span" size="3">innerText</font></span></i><span class="pun Apple-style-span"><font class="Apple-style-span" size="3"><i>()</i> while ProtoBuf would access the same data with <i>person.name()</i>. &nbsp;As a result of the amount of code generated by the Proto Complier it is much easier to understand the structure of an object by locating the <i>.proto</i> file. &nbsp;The methods generated by the compiler can be found by researching the ProtoBuf documentation. &nbsp;ProtoBufs are used early and often in FedOne, so an understanding of them will be of great assistance.</font></span></font><br/><br/></div>
<div><span class="pun Apple-style-span"><font class="Apple-style-span" size="3"><a href="http://code.google.com/apis/protocolbuffers/docs/overview.html" id="sabd" title="Read more on Protocol Buffers">Read more on Protocol Buffers</a>.</font></span><br/><br/></div>
<div><font class="Apple-style-span" size="3"><b>Next in Series</b></font><br/><br/></div>
<div><font class="Apple-style-span" size="3">The <a href="http://www.angleofsight.com/2010/02/google-wave-federation-part-2/">next post</a> will cover the startup process within the FedOne code. &nbsp;It will list the primary packages/classes invoked and layout the process by which they interact (will illustrate this in an Activity Diagram).</font></div>
<p><font class="Apple-style-span" size="3"><b><br />
</b></font></p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-3/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 3'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 3</a> <small> Purpose [Updated 4/3/2010] This is the third post in...</small></li><li><a href='http://www.angleofsight.com/2010/03/mongowave/' rel='bookmark' title='Permanent Link: MongoWave: Persistence on Google FedOne Wave Server with mongoDB'>MongoWave: Persistence on Google FedOne Wave Server with mongoDB</a> <small> Purpose My company, SESI, has been working on applying...</small></li><li><a href='http://www.angleofsight.com/2010/02/google-wave-federation-part-2/' rel='bookmark' title='Permanent Link: Google Wave&#8217;s Federation Protocol Under the Hood, Part 2'>Google Wave&#8217;s Federation Protocol Under the Hood, Part 2</a> <small>Purpose [Updated 4/3/2010] This post is the second in a...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/lO4AnUu7nek" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/google-wave-federation-part-1/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/google-wave-federation-part-1/</feedburner:origLink></item>
		<item>
		<title>The Authority of Perspectives</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/TIw1TXtrz5o/</link>
		<comments>http://www.angleofsight.com/2010/02/the-authority-of-perspectives/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 16:17:26 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Social Media]]></category>

		<category><![CDATA[Strategy]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[perspectives]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=49</guid>
		<description><![CDATA[This post is based on a response I made to a Knowledge Management listserv several months ago.  Since that time the notion of authoritative data sources and validity of information has continued to surface in the course of my work.  My view on the subject has been refined by discussions with Dr. Andres Sousa-Poza [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2009/11/do-you-see-what-i-see/' rel='bookmark' title='Permanent Link: Do You See What I See?'>Do You See What I See?</a> <small>When I conceived of this blog, I thought I would...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.ryanashton.org/2008/04/29/the-abuse-of-authority/" target="_blank"><img id="s:xv" style=" float: right; margin-left: 1em ; margin-right: 0em;" src="http://www.angleofsight.com/images/perspective/authority_web.jpg" alt="Image courtesy of Ryan Ashton (blog.ryanashton.org)" /></a>This post is based on a response I made to a Knowledge Management listserv several months ago.  Since that time the notion of authoritative data sources and validity of information has continued to surface in the course of my work.  My view on the subject has been refined by discussions with Dr. Andres Sousa-Poza and Sam Kovacic at the National Center for System of Systems Engineering at Old Dominion University.  The content of my original post was as follows:</p>
<div style="clear:both">
<table id="tfhq" class="zeroBorder" border="0" cellspacing="0" cellpadding="3" width="85%" bordercolor="#000000">
<tbody>
<tr>
<td width="100%">
<p class="MsoPlainText" style="margin-right: 0.5in; margin-left: 0.5in">I believe that too often, particularly in the Federal government, there is too much emphasis placed on SMEs and authoritative sources of information.  I believe a culture shift is in order that will go from “authoritative” to “value-added”.  You won’t find many people who consider themselves experts in a given category, but that does not mean they do not have valuable viewpoints on a topic.  Out of the 700 or so people on this listserv, there are probably a large number that could add value to this subject, but will not because they do not feel they can offer expert advice.</p>
<p class="MsoPlainText" style="margin-right: 0.5in; margin-left: 0.5in">This is akin to offering Consumer Reports to the community as the authoritative source of information on products and providing access to the people that actually performed the reviews.  Certainly, their insight is valuable and they can tell you that the battery life on the portable DVD player is actually only an hour as opposed to the 2 hours listed in the technical specifications.  However, I find the most value by going to Amazon.com and reading regular user reviews on a product.  There I might find that another parent bought the product for their child on long car drives, but the buttons were left exposed so the child constantly turned the DVD player off (based on this I bought a Sony that had a Hold button :) ).  You will also discover issues like how customer support responds to problems and be able to surmise the true value of a product based on finding trends in the comment threads.  The great majority of these people would not consider themselves experts, but do feel they have a perspective that may add value.  Sites like Amazon.com and Barnes and Noble encourage this type of user participation.  I have not seen the same encouragement from the Federal government.</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>I have modified my view on the subject, although the sentiment of my original post remains the same.  The key remains capturing the perspectives that contribute valuable information.  However, it was inaccurate for me to make a one to one correlation between authoritative sources and SMEs.  Expertise can be localized such that the authoritative source on an issue is not a SME.</p>
<p style="margin-right: 0in; margin-left: 0in"><span>For instance, a solider that has been on the ground in Afghanistan for a year may have more knowledge of the prevailing conditions than a PhD who has studied the society.  I consider both perspectives to fall within the &#8220;expert&#8221; category.  Both individuals have relevant perspectives and should be considered as capable of providing valuable information. However, it must be recognized that these two views will be more appropriate in different situations.</span></p>
<p style="margin-right: 0in; margin-left: 0in"><span>A SME point of view will be most effective in situations that require strategy based on broad generalities that are valid over some defined segment.  The local perspective is much more effective in providing context specific advice.  For instance, a SME could best advise on how the US Military should approach civilians in Afghanistan given their culture, while a local figure would be more knowledgeable on the most likely hideouts for terrorists in a region.  To facilitate informed decision-making it is vital to understand when to shift between these perspectives as most problems have an element of both.</span></p>
<p style="margin-right: 0in; margin-left: 0in"><span>An additional issue arises when trying to identify a local perspective.  SMEs can usually be identified by a number of factors to include experience, education, speaking engagements, and published works.  Locating an individual that has “lived-in” a related situation or within a target environment and has a viewpoint that is in line with an overarching strategy is much more difficult.  A local perspective may also extend beyond the views of a single individual, but rather be composed of a group of individuals that exhibit certain patterns.  As local perspectives are either solicited or derived from a crowd, there is a massive amount of information that must be filtered.</span></p>
<p style="margin-right: 0in; margin-left: 0in"><span>Social Media is largely responsible for bringing many of these issues to the forefront.  The crowd now has a voice that extends as far or beyond traditional communication outlets, which are more accessible to SMEs.  Also, the volume of user-generated content enabled by this technology far exceeds that which was previously available.  As a result, organizations within the public and private sector along with private citizens are engaged in processes to aggregate, search and analyze the flow of information to reveal interesting patterns and drive decision-making in near real-time.</span></p>
<p style="margin-right: 0in; margin-left: 0in"><span>While Social Media has enormous potential to drive business, the success of any organization at making informed decisions in the future will be limited by the credibility they assign to the local perspective.   The technology to filter relevant content and identify reliable patterns has and will continue to evolve at a rapid pace.  The greater challenge for most organizations will be the cultural shift required to embrace and rely on this new type of “authoritative” information.</span></p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2009/11/do-you-see-what-i-see/' rel='bookmark' title='Permanent Link: Do You See What I See?'>Do You See What I See?</a> <small>When I conceived of this blog, I thought I would...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/TIw1TXtrz5o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2010/02/the-authority-of-perspectives/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2010/02/the-authority-of-perspectives/</feedburner:origLink></item>
		<item>
		<title>Do You See What I See?</title>
		<link>http://feedproxy.google.com/~r/AngleOfSight/~3/lK8frRrhjp0/</link>
		<comments>http://www.angleofsight.com/2009/11/do-you-see-what-i-see/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 05:11:15 +0000</pubDate>
		<dc:creator>Anthony</dc:creator>
		
		<category><![CDATA[Blogs]]></category>

		<category><![CDATA[Strategy]]></category>

		<category><![CDATA[about]]></category>

		<category><![CDATA[blog]]></category>

		<category><![CDATA[perspectives]]></category>

		<guid isPermaLink="false">http://www.angleofsight.com/?p=28</guid>
		<description><![CDATA[When I conceived of this blog, I thought I would explore “solutions”.  That is, how technology could be applied to solve challenges faced in the government and commercial sectors.  I have recently started a new job that focuses on assisting clients with decision-making within complex environments.  While I still intend to focus [...]


Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/the-authority-of-perspectives/' rel='bookmark' title='Permanent Link: The Authority of Perspectives'>The Authority of Perspectives</a> <small>This post is based on a response I made to...</small></li><li><a href='http://www.angleofsight.com/about/' rel='bookmark' title='Permanent Link: About Me'>About Me</a> <small>BarCamp Style Who are you? - Husband | Father |...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img style="float:right;padding:15px" src="http://www.angleofsight.com/images/perspective.jpg" alt="perspective" width="200" height="200" />When I conceived of this blog, I thought I would explore “solutions”.  That is, how technology could be applied to solve challenges faced in the government and commercial sectors.  I have recently started a new job that focuses on assisting clients with decision-making within complex environments.  While I still intend to focus on applied technology, my new position has introduced me to the philosophical underpinnings that play a heavy role in decision-making.  Paramount to what I am researching now is how to account for perspectives.  An individual’s perspective will affect how the problem is framed, the approach taken, and will ultimately define how success is measured.</p>
<p>Given the importance of perspective, it’s probably a good idea to tell you a little bit about mine.  As a former business owner, I tend to look at the value of technology as measured by its utility to the end user in conjunction with its costs to the organization.  Keep in mind that cost is not always monetary.  Cost could be defined as resources required, time to deploy, maintenance schedules, impact on culture, or any number of other factors.  The key point being that technology does not exist in a vacuum and should serve a defined need.  While this is a belief that I hold dear, I must be candid.  I am a Software Architect by trade so I do still appreciate, and sometimes even marvel at, a well-designed innovate piece of software.  To put it plainly, there’s definitely some geek in me and I do enjoy the occasional shiny object.</p>
<p>With this in mind, my blog will share my thoughts and experiences in regards to business strategy, software architecture, and technologies that revolve around collaboration-based solutions.  I will also catalog what I learn in regards to Philosophy and how we are able to apply it to software to enhance decision-making capabilities.  I hope that through this channel I will engage you enough that you will share your experiences and ideas with me.  I look forward to speaking with you. </p>


<p>Related posts:<ol><li><a href='http://www.angleofsight.com/2010/02/the-authority-of-perspectives/' rel='bookmark' title='Permanent Link: The Authority of Perspectives'>The Authority of Perspectives</a> <small>This post is based on a response I made to...</small></li><li><a href='http://www.angleofsight.com/about/' rel='bookmark' title='Permanent Link: About Me'>About Me</a> <small>BarCamp Style Who are you? - Husband | Father |...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p><img src="http://feeds.feedburner.com/~r/AngleOfSight/~4/lK8frRrhjp0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.angleofsight.com/2009/11/do-you-see-what-i-see/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.angleofsight.com/2009/11/do-you-see-what-i-see/</feedburner:origLink></item>
	</channel>
</rss>
