<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Shane K Johnson</title>
	<atom:link href="http://blogs.citytechinc.com/sjohnson/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blogs.citytechinc.com/sjohnson</link>
	<description>Architecture &#38; The Devil&#039;s Advocate</description>
	<pubDate>Wed, 20 Jan 2010 14:12:57 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
			<item>
		<title>JBoss DNA, Revisited</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=144</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=144#comments</comments>
		<pubDate>Wed, 14 Oct 2009 15:01:40 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Enterprise Content Management]]></category>
		<category><![CDATA[JBoss]]></category>
		<category><![CDATA[Java Content Repository]]></category>
		<category><![CDATA[DNA]]></category>
		<category><![CDATA[JCR]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=144</guid>
		<description><![CDATA[I decided to take another look at JBoss DNA the other day, and it turned out to be quite a surprise.
It seems that the focus has been refined, and the vision clarified.
The first time I looked at it, DNA was not a repository. Rather it was something that could federate multiple content stores (e.g. &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to take another look at JBoss <a href="http://jboss.org/dna/"title="JBoss DNA"  onclick="javascript:pageTracker._trackPageview('/outbound/article/jboss.org');">DNA</a> the other day, and it turned out to be quite a surprise.</p>
<p>It seems that the focus has been refined, and the vision clarified.</p>
<p>The first time I looked at it, DNA was not a repository. Rather it was <em>something</em> that could federate multiple content stores (e.g. &#8211; repository/database/file system). I just wasn&#8217;t sure what that <em>something</em> was. I believe that is what led me to question how practical it was.</p>
<p>Now, DNA is a repository. However, with this particular repository you can access multiple content stores via the JCR API.</p>
<p><span id="more-144"></span></p>
<p>In my first <a href="http://blogs.citytechinc.com/sjohnson/?p=34"title="JBoss DNA, Hello"  >post</a> on DNA I mentioned two JIRA issues: DNA-55 (RESTful API) and DNA-46 (JCR Implementation). They were supporting features. Now, they are defining features.</p>
<p>The one thing that hasn&#8217;t changed is that I still see the value in DNA. I still like the idea of federated repositories. That, and I really like the JCR API.</p>
<p>So, what is the big deal?</p>
<p>First, the ability to access content outside the repository via the JCR API.</p>
<p>Second, the ability to apply JCR functionality (search, versioning, etc.) to content outside the repository.</p>
<p>Third, the ability to federate multiple content stores. Here are a few scenarios where I think this might be practical.</p>
<ul>
<li>SVN &amp; File System &#8211; The source code may be in a SVN repository, but the build artifacts are on a file system.</li>
<li>JCR &amp; File System &#8211; I&#8217;ve worked with a number of clients who maintain their binaries on a file system, but maintain the metadata in a repository (JCR).</li>
<li>Database (Metadata) &amp; Database (Metadata) &#8211; How about comparing the schemas of multiple databases?</li>
</ul>
<p>There are a few issues though&#8230;</p>
<p>According to the reference documentation, DNA is lacking a JCR connector. To me, this is a sore spot. I just described a possible JCR/file system pairing above, but at the moment the repository would have to be a DNA repository.</p>
<p>The database connector is only for metadata, as I just described. That may be a bit limiting. I would like to have added this pairing: Database (Content) &amp; JBoss Cache/Infinispan. Wouldn&#8217;t it be nice to compare what is cached with what has been persisted?</p>
<p><span style="text-decoration: line-through;">The file system/SVN connectors are read-only. A little disappointing. The scenarios I described are now useful only for reporting.</span> The file system connector is read/write. While the SVN connector is currently read-only, work is currently in progress to add write capabilities. It <span style="text-decoration: line-through;">would</span> should be nice to be able to use DNA to persist content to the file system and metadata to a repository.</p>
<p>It appears that the JBoss Cache/<a href="http://www.jboss.org/infinispan"title="INFINISPAN"  onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jboss.org');">Infinispan</a> connectors are really just persistence options for DNA repositories. I&#8217;m not sure that they can be used to access content that has been cached outside the context of DNA. Though I could be wrong.</p>
<p>Now I&#8217;m left wondering, does DNA have any disk based persistence options? Perhaps it is not via a connector. I didn&#8217;t see anything in the reference documentation regarding this point.</p>
<p>Also, a number or rather important JCR features are still missing: queries, observation, and locking. That significantly diminishes my second point above (applying JCR functionality to content outside the repository).</p>
<p>Note: If observation is available as part of the Graph API, why is it not yet available as part of the JCR implementation?</p>
<p>That being said, DNA is still in the early stages of development. I suspect some of these issues may be addressed before the 1.0 release. I still think it is pretty neat even with the limited connectors currently available.</p>
<p>There is one aspect that is particularly interesting. The JBoss Cache/Infinispan connectors. I&#8217;ve always thought it would be cool to be able to persist a repository to a distributed data grid/cache. As far as I know, there are no such persistence managers for Jackrabbit. I wonder how much emphasis JBoss is going to place on these connectors. Personally, I think they could be defining features.</p>
<p>That brings me to one last concern. How is JBoss going to market DNA?</p>
<p>Part of me wonders if the JCR implementation shouldn&#8217;t be separated and treated as its own project. Then place a great deal of emphasis on the fact that the content can be persisted to a distributed data grid/cache. It could now be treated as a direct competitor to Jackrabbit and offer a distinguishing feature. Finally, allow DNA to focus purely on the federation aspect and the ability to use the JCR API to access content outside of repositories.</p>
<p>We&#8217;ll just have to see what the 1.0 release bring us. I&#8217;m looking forward to it.</p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=144</wfw:commentRss>
		</item>
		<item>
		<title>How I learned to say &#8216;No&#8217; to SQL</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=89</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=89#comments</comments>
		<pubDate>Wed, 30 Sep 2009 14:23:04 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Cassandra]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[distributed]]></category>
		<category><![CDATA[key/value store]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>
		<category><![CDATA[Tokyo Tyrant]]></category>
		<category><![CDATA[Voldemort]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=89</guid>
		<description><![CDATA[This is the story of how I learned to say &#8216;No&#8217; to SQL and to cope with my wife&#8217;s addiction to Coach bags.
The answer is support groups. I kid. No, I don&#8217;t.
There are a number of alternatives to relational databases. However, for the purposes of this post, I am focusing on persistent, distributed key/value stores.
It [...]]]></description>
			<content:encoded><![CDATA[<p>This is the story of how I learned to say &#8216;No&#8217; to SQL and to cope with my wife&#8217;s addiction to Coach bags.</p>
<p>The answer is support groups. I kid. No, I don&#8217;t.</p>
<p>There are a number of alternatives to relational databases. However, for the purposes of this post, I am focusing on persistent, distributed key/value stores.</p>
<p>It all seems to have started with Amazon&#8217;s <a href="http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html"title="Amazon's Dynamo"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.allthingsdistributed.com');">Dynamo</a>.</p>
<p>Clarification: I&#8217;m not saying that Dynamo was the first distributed key/store. I imagine most developers are familiar with memcached and products such as Oracle Coherence when it comes to caching and data grids. There is also Berkely DB, a persistent key/value store. However, Dynamo is both distributed and persistent. That, and it seems to have lead (indirectly and directly) to the development of numerous open source implementations as I&#8217;ll explain below. It appears that Dynamo and Google BigTable had a one night stand and their illegitimate children formed the NoSQL movement.</p>
<p>In order to understand how today&#8217;s key value stores are borrowing heavily from Dynamo, it is worth briefly going over some of its characteristics.</p>
<ul>
<li>Fault Tolerance &#8211; The data is replicated and/or partitioned.</li>
<li>Distributed Hash Table (DHT)</li>
<li>Consistent Hashing &#8211; The mechanism behind distributed hash tables.</li>
<li>Eventually Consistent</li>
<li>Distributed Consistency</li>
</ul>
<p><span id="more-89"></span></p>
<h2>Consistent Hashing</h2>
<p>Consistent hashing is a means of looking up a node based on a key. The idea is that a key is generated for each node. When you do a get/put/delete, you use the key to look up the key of the closest node.</p>
<p>For proper descriptions of consistent hashing check out these blog posts:</p>
<ul>
<li><a href="http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html"title="Consistent Hashing"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.java.net');">Consistent Hashing</a></li>
<li><a href="http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/"title="Programmer’s Toolbox Part 3: Consistent Hashing"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.spiteful.com');">Programmer’s Toolbox Part 3: Consistent Hashing</a></li>
<li><a href="http://www.mikeperham.com/2009/01/14/consistent-hashing-in-memcache-client/"title="Consistent Hashing in memcache-client"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.mikeperham.com');">Consistent Hashing in memcache-client</a></li>
</ul>
<h2>Eventually Consistent</h2>
<p>CAP Theorem</p>
<ul>
<li>Consistent &#8211; The notion that all clients have the same view of the data at any given time.</li>
<li>Available &#8211; The notion that the data can always be viewed by all clients at any given time.</li>
<li>Partition Tolerance &#8211; The notion that the system can tolerate physical network partitions at any given time.</li>
</ul>
<p>The theorem states that you can only have two of these properties at a time. This is interesting because I&#8217;ve found that a number of distributed key value stores are sacrificing consistency for availability and partition tolerance.</p>
<p>This is where the notion of eventually consistent comes into play. The idea is that if there are no further updates, the data will eventually become consistent.</p>
<p>For proper descriptions of the CAP theorem check out these blog posts:</p>
<ul>
<li><a href="http://camelcase.blogspot.com/2007/08/cap-theorem.html"title="The CAP Theorem"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/camelcase.blogspot.com');">The CAP Theorem</a></li>
<li><a href="http://www.julianbrowne.com/article/viewer/brewers-cap-theorem"title="Brewer's CAP Theorem"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.julianbrowne.com');">Brewer&#8217;s CAP Theorem</a></li>
</ul>
<p>For a proper description of eventually consistent check out this blog <a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html"title="Eventually Consistent - Revisited"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.allthingsdistributed.com');">post</a> by Werner Vogels (CTO &#8211; Amazon).</p>
<h2>Distributed Consistency</h2>
<ul>
<li>Locking</li>
<li>Multi-Version Concurrency Control (<a href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"title="Multi-Version Concurrency Control"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">MVCC</a>) -  The idea is that each user views a <em>snapshot</em> of the data based on a point in time.</li>
<li><a href="http://en.wikipedia.org/wiki/Vector_clock"title="Vector Clocks"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Vector Clock</a> &#8211; The idea is that each node maintains a local copy of the system state (node event counters), as it knows it, and relies on messaging for synchronization.</li>
<li>Read Repair &#8211; The idea is that rather than having the system prevent conflicts, it will rely on the client to resolve them.</li>
</ul>
<h2>Serialization &amp; Protocols</h2>
<ul>
<li>Byte Array</li>
<li>JSON (Binary)</li>
<li>Java Serialization</li>
<li><a href="http://code.google.com/p/protobuf/"title="protobuf"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">protobuf</a> (Google Protocol Buffers)</li>
<li><a href="http://incubator.apache.org/thrift/"title="Thrift"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/incubator.apache.org');">Thrift</a></li>
<li>HTTP/REST (JSON)</li>
<li><a href="http://www.danga.com/memcached/"title="memcached"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.danga.com');">memcached</a></li>
</ul>
<h2>Key Value Stores</h2>
<p>There seem to be two types of variations.</p>
<ul>
<li>Key/Value Store &#8211; The value is arbitrary.</li>
<li>Document Store &#8211; The value is semi structured data (e.g. JSON).</li>
</ul>
<p><a href="http://project-voldemort.com/"title="Project Voldemort"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/project-voldemort.com');">Project Voldemort</a> &#8211; LinkedIn</p>
<p>Voldemort is a key value store. It has, by far, the best documentation.</p>
<ul>
<li>Replicated &amp; Partitioned</li>
<li>Consistent Hashing</li>
<li>Eventually Consistent</li>
<li>Versioned</li>
<li>Vector Clock with Read-Repair</li>
<li>JSON (Binary/Typed), String, Java, protobuf (Google Protocol Buffers), byte[]</li>
<li>Other
<ul>
<li>Java</li>
</ul>
</li>
</ul>
<p><a href="http://1978th.net/"title="Tokyo Cabinet/Tyrant"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/1978th.net');">Tokyo Cabinet/Tyrant</a> &#8211; Mixi</p>
<p>Tokyo Cabinet is a key value store. Tyrant is the server that provides network access to Cabinet.</p>
<p>While I wouldn&#8217;t consider Cabinet to be distributed, I had to add it because it is ridiculously fast.</p>
<p>About 1 million inserts in 0.4 seconds fast.</p>
<ul>
<li>Replicated (Tyrant &#8211; Asynchronous)</li>
<li>Locking &#8211; Read/Write (Transactions are available via Cabinet, but not Tyrant.)</li>
<li>Write Ahead Logging/Shadow Paging</li>
<li>byte[], memcached, HTTP/REST</li>
<li>Other
<ul>
<li>Sorted Keys (B Tree Index)</li>
<li>C &#8211; pwrite, pread, mmap</li>
<li>Thread Safe (pthreads)</li>
<li>Cache Flushing &#8211; Writes are persisted to an in memory buffer. Once the buffer is full, they are written to disk.</li>
</ul>
</li>
</ul>
<p>The general consensus is that if your data can fit onto a single server, use Tokyo Cabinet/Tyrant. If not, use something like Voldemort.</p>
<p><span style="text-decoration: underline;">Notes</span></p>
<p>This blog <a href="http://www.igvita.com/2009/02/13/tokyo-cabinet-beyond-key-value-store/"title="Tokyo Cabinet: Beyond Key-Value Store"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.igvita.com');">post</a> provides additional information with respect to Tokyo Cabinet/Tyrant. And <a href="http://www.scribd.com/doc/12016121/Tokyo-Cabinet-and-Tokyo-Tyrant-Presentation"title="Tokyo Cabinet and Tokyo Tyrant"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.scribd.com');">here</a> is the presentation.</p>
<p><a href="http://couchdb.apache.org/"title="CouchDB"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/couchdb.apache.org');">Apache CouchDB</a></p>
<p>CouchDB is a document store, and because of that it supports search functionality.</p>
<ul>
<li>Replicated (Incremental, Shared Nothing, Asynchronous)</li>
<li>Eventually Consistent</li>
<li>HTTP/REST (JSON)</li>
<li>MVCC<a href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"title="MVCC"  onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');"></a></li>
<li>Other
<ul>
<li>Sorted keys (B Tree Index)</li>
<li>Erlang &#8211; Concurrency</li>
<li>Index/Query (Map/Reduce via JavaScript)</li>
</ul>
</li>
</ul>
<p><span style="text-decoration: underline;">Notes </span></p>
<p>This blog <a href="http://www.mikeperham.com/2009/09/01/comparing-document-oriented-databases/"title="Comparing Dcoument-oriented Databases"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.mikeperham.com');">post</a> provides a nice comparison of the differences between CouchDB and Tokyo Cabinent/Tyrant.</p>
<p><a href="http://incubator.apache.org/cassandra/"title="Cassandra"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/incubator.apache.org');">Apache Cassandra</a> &#8211; Facebook</p>
<p>Cassandra is really a BigTable clone. Think of it as a completely denormalized database. However, it too borrows heavily Dynamo and uses a DHT.</p>
<ul>
<li>Replicated &amp; Partitioned</li>
<li>Eventually Consistent</li>
<li>Consistent Hashing</li>
<li>Read-Repair</li>
<li>Thrift</li>
</ul>
<p><span style="text-decoration: underline;">Notes </span></p>
<p>You can find two (useful) presentations on Cassandra <a href="http://assets.en.oreilly.com/1/event/27/Cassandra_%20Open%20Source%20Bigtable%20+%20Dynamo%20Presentation.pdf"title="Cassandra"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/assets.en.oreilly.com');">here</a> and <a href="http://ewh.ieee.org/r6/scv/computer//nfic/2009/IBM-Jun-Rao.pdf"title="BlueRunner"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/ewh.ieee.org');">here</a>.</p>
<h2>Conclusion</h2>
<p>Why are distributed key/value stores gaining momentum? It is simple: performance and scalability.</p>
<p>I like to think of it as an exercise in simplicity. A typical key/value store only supports 3 operations:</p>
<ul>
<li>put(key, value)</li>
<li>get(key)</li>
<li>delete(key)</li>
</ul>
<p>That is it!</p>
<p>The problem with databases is that they are difficult to scale horizontally. One solution is sharding. One problem with sharding is that you will likely lose the &#8216;relational&#8217; aspect due to the performance cost of running a query across several nodes. The other problem is the cost of rebalancing the nodes if additional sharding is needed. Ultimately you will likely end up denormalizing the data. The is the first step on the path to key/value stores.</p>
<p>That being said, there are still use cases where you want to use a database. One case might be search. Typical key/value stores are not going to provide search functionality. However, document stores (CouchDB) and BigTable clones (Cassandra) will. The other resolves around consistency. As mentioned before, these distributed key/value stores are relaxing on consistency in favour of availability and partition tolerance. A common example is banking transactions. I don&#8217;t think anyone wants relax on consistency when working with banking transactions.</p>
<p>On the other hand, here is a use case from my own experience where I think a key/value store would be more appropriate.</p>
<p>I used to work on an application for generating and processing insurance applications. There were two steps to this process. The first step was determining if insurance was even available to the applicant. The next step was building a dynamic application for the applicant. For the first step, we maintained a complex set of business rules in our database. Essentially we used the applicant&#8217;s zip code and business type to determine if insurance was even available. For the second step, we maintained a list of questions based on the applicant&#8217;s insurance type and the carriers available.</p>
<p>The SQL for these operations was quite complex and included stored procedures as a result. A better alternative might have been to denormalize the database and push both the business rules and the applications to a key/value store. That is not to say that we wouldn&#8217;t continue to use a database. We would. It is just that the database would be used to enter the business rules/applications. The key/value store would be used to retrieve the business rules/applications. Ultimately, the business rules could be collapsed to a key that is the hash of the applicant&#8217;s business type and zip code. The value could be a serialized application. Now we just call get(key) and if the value is null, then there is no insurance available. If it is not, then insurance is available and this is the serialized application. On top of that, the applicant&#8217;s can save their application and update it at a later date. So, we might as well persist the application instance to a key/value store as well.</p>
<p>Of course, I have simplified things quite a bit here. However, my point is that this process is not transactional in the sense that banking transactions are. The only writes are for updating the answers, and for all intensive purposes this will be done a single client (the applicant). Concurrency is not really a problem here.</p>
<p>Notes:</p>
<p>This blog <a href="http://www.25hoursaday.com/weblog/2009/01/16/BuildingScalableDatabasesProsAndConsOfVariousDatabaseShardingSchemes.aspx"title="Building Scalable Databases: Pros and Cons of Various Database Sharding Schemes"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.25hoursaday.com');">post</a> provides a nice summary of the issues surrounding sharding.</p>
<h2>Additional Reading &#8211; General<strong> </strong></h2>
<p><a href="http://www.metabrew.com/article/anti-rdbms-a-list-of-distributed-key-value-stores/"title="Anti-RDBMS: A list of distributed key-value stores"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.metabrew.com');">Anti-RDBMS: A list of distributed key-value stores</a></p>
<p><a href="http://anyall.org/blog/2009/04/performance-comparison-keyvalue-stores-for-language-model-counts/"title="Performance comparison: key/value stores for language model counts"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/anyall.org');">Performance comparison: key/value stores for language model counts</a></p>
<p><a href="http://randomfoo.net/2009/04/20/some-notes-on-distributed-key-stores"title="Some Notes on Distributed Key Stores"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/randomfoo.net');">Some Notes on Distributed Key Stores</a></p>
<p><a href="http://bcbio.wordpress.com/2009/05/10/evaluating-key-value-and-document-stores-for-short-read-data/"title="Evaluating key-value and document stores for short read data"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/bcbio.wordpress.com');">Evaluating key-value and document stores for short read data</a></p>
<p><a href="http://www.eflorenzano.com/blog/post/my-thoughts-nosql/"title="My Thoughts on NoSQL"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.eflorenzano.com');">My Thoughts on NoSQL</a></p>
<p><a href="http://bjclark.me/2009/08/04/nosql-if-only-it-was-that-easy/"title="NoSQL: If Only It Was That Easy"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/bjclark.me');">NoSQL: If Only It Was That Easy</a></p>
<p><a href="http://www.25hoursaday.com/weblog/2009/09/10/BuildingScalableDatabasesDenormalizationTheNoSQLMovementAndDigg.aspx"title="Building Scalable Databases: Denormalization, the NoSQL Movement and Digg"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.25hoursaday.com');">Building Scalable Databases: Denormalization, the NoSQL Movement and Digg</a></p>
<p><a href="http://highscalability.com/drop-acid-and-think-about-data"title="Drop ACID and Think About Data"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/highscalability.com');">Drop ACID and Think About Data</a></p>
<p><a href=" http://bytepawn.com/readings-in-distributed-systems/"title="Readings in Distributed Systems"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/bytepawn.com');">Readings in Distributed Systems</a> &#8211; Great List of Papers</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 125px; width: 1px; height: 1px;">http://www.julianbrowne.com/article/viewer/brewers-cap-theorem</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=89</wfw:commentRss>
		</item>
		<item>
		<title>Upcoming Day/Alfresco Events with CITYTECH</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=86</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=86#comments</comments>
		<pubDate>Fri, 17 Apr 2009 04:08:25 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Enterprise Content Management]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Web Content Management]]></category>
		<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CQ]]></category>
		<category><![CDATA[DM]]></category>
		<category><![CDATA[WCM]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=86</guid>
		<description><![CDATA[It is turning out to be quite a busy month. I am going to be speaking at 3 events over the next couple weeks.

Day CQ5 Product Tour
CITYTECH will be supporting the midwest leg.
4/21 &#8211; Minneapolis
4/22 &#8211; Chicago
4/23 &#8211; Columbus
I&#8217;ll be speaking in Columbus while Jeff &#038; Satish will be speaking in Chicago.
It should come as [...]]]></description>
			<content:encoded><![CDATA[<p>It is turning out to be quite a busy month. I am going to be speaking at 3 events over the next couple weeks.<br />
<br/><br/></p>
<h3>Day CQ5 Product Tour</h3>
<p>CITYTECH will be supporting the midwest leg.</p>
<p>4/21 &#8211; Minneapolis<br />
4/22 &#8211; Chicago<br />
4/23 &#8211; Columbus</p>
<p>I&#8217;ll be speaking in Columbus while Jeff &#038; Satish will be speaking in Chicago.</p>
<p>It should come as no surprise to anyone that I&#8217;m a huge fan of CQ5. At CITYTECH, we call it the Cadillac of web content management systems. In addition to covering CQ5, I&#8217;m going to be dicussing aspects of web content management in general. If web content management is important to your business, I think you&#8217;ll find a great deal of value in attending.</p>
<p><a href="http://day.com/cq5tour" target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/day.com');">info/registration</a><br />
<br/></p>
<h3>Alfresco Chicago Meetup</h3>
<p>I&#8217;ll be presenting on CMIS during the &#8220;barcamp&#8221;.</p>
<p>4/29 &#8211; Chicago</p>
<p>Nancy has done a great a job with the Alfresco community events. I always enjoy them. They are casual, informative, social, and a great time in general. I&#8217;d strongly encourage anyone to attend regardless of their level of experience with Alfresco.</p>
<p><a href="http://www.cmsexpo.net/" target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.cmsexpo.net');">info/registration</a><br />
<br/></p>
<h3>CMS Expo Learning &amp; Business Conference</h3>
<p>CITYTECH is going to be presenting on Alfresco (DM/WCM) and CMIS.</p>
<p>4/30 &amp; 5/1 &#8211; Evanston (Chicago)</p>
<p>Thursday morning Jeff and Tom will be discussing document management/collaboration. In the afternoon I&#8217;ll be dicussing CMIS. Finally, on Friday, John will be discussing web content management.</p>
<p>In addition to Alfresco, CMS Expo will be featuring professional training on Joomla! and Drupal.</p>
<p><a href="http://www.alfresco.com/about/events/2009/04/chicagomeetup/" target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.alfresco.com');">info/registration</a></p>
<p><br/><br/><br />
You can always find my dropping some tweets on Alfresco, Day CQ, CMIS, architecture, and Battlestar Galactica on Twitter.<br />
<a href="http://twitter.com/shane_dev" target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/twitter.com');">http://twitter.com/shane_dev</a></p>
<p>So until next time, good fight, good night.</p>
<p><br/><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=86</wfw:commentRss>
		</item>
		<item>
		<title>What makes a great developer?</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=85</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=85#comments</comments>
		<pubDate>Thu, 16 Apr 2009 15:00:24 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=85</guid>
		<description><![CDATA[Simplicity
This is what it all comes down to. A lot of developers tend to write complex code. I think it is a result of the ad-hoc nature of programming. The truth is that it is much more difficult to write simple code. I think there are two facets to writing simple code. One is experience, [...]]]></description>
			<content:encoded><![CDATA[<h3>Simplicity</h3>
<p>This is what it all comes down to. A lot of developers tend to write complex code. I think it is a result of the ad-hoc nature of programming. The truth is that it is much more difficult to write simple code. I think there are two facets to writing simple code. One is experience, and the other is patience. Experienced developers are better prepared to write simple code from the start. However, simplicity is ultimately achieved by continuously refactoring the code.</p>
<h3>Elegance</h3>
<p>The code may be simple, but is it elegant? Elegant code is a sure sign of a great developer. It is no longer about efficiency or effectiveness. It is about pride.</p>
<h3>Balance</h3>
<p>In order to achieve simplicity and elegance, a developer needs to find the right balance between framework/libraries and code. A lot of developers assume that when a framework/library can be used, it should be. Others insist on writing code without the use of any frameworks/libraries. It is all about finding the right balance between the two.</p>
<h3>Cleanliness</h3>
<p>If the code is simple, elegant, and balanced then there is no reason why it shouldn&#8217;t be clean. It should be formatted and follow the proper naming conventions.</p>
<h3>Learning Curve</h3>
<p>The breadth and depth of knowledge is not nearly as important as a developers ability and desire to learn. As a matter of fact, I&#8217;d say that a significant amount of breadth or depth may be detrimental. It may indicate a lack or awareness or flexibility. It is not about knowing X and Y for years. It is about being able to learn Z in days.</p>
<h3>Domination</h3>
<p>A great developer dominates the entire code base. While some developers may be comfortable in their area of responsibility, great developers have a need to know and understand the entire code base.</p>
<h3>Vision</h3>
<p>It is important to consider aspects such as maintainability when developing code. The focus should not just be on whether it is functional or not. A great developer considers the long term consequences in addition to the short term goals.</p>
<p>Well, this is my option anyways. I&#8217;d welcome any thoughts and/or suggestions.</p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=85</wfw:commentRss>
		</item>
		<item>
		<title>I purchased a cloud. Did you? Wait. What is a cloud?</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=84</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=84#comments</comments>
		<pubDate>Tue, 14 Apr 2009 14:39:35 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=84</guid>
		<description><![CDATA[Reality Television Shows
Buzzwords are a lot like reality television shows. Every time one is canceled, two more take its place. You know what else they have in common? They lack originality. They are just putting on a new face.
Zombie Viruses
Actually, buzzwords are a lot like zombie viruses too. Somewhere in a secret lab, a vendor [...]]]></description>
			<content:encoded><![CDATA[<h3><strong>Reality Television Shows</strong></h3>
<p>Buzzwords are a lot like reality television shows. Every time one is canceled, two more take its place. You know what else they have in common? They lack originality. They are just putting on a new face.</p>
<h3><strong>Zombie Viruses</strong></h3>
<p>Actually, buzzwords are a lot like zombie viruses too. Somewhere in a secret lab, a vendor and a research analyst are splicing buzzwords looking to create a more perfect buzzword. Then they go to a conference and discretely drop the buzzword. Next thing you know, you&#8217;re holed up in bar with a Winchester picking off evangelists one at a time.</p>
<p>For me, it is being holed up in an IRC channel along with my friends/colleagues and other prominent members of the Java community. I thought I was safe. Then, I see that some of them have actually been infected. The Winchester will suffice for now, but I may need to go sawed off, double barrel style soon.</p>
<p>I guess that means a buzzword is a lot like a reality television show featuring zombies.</p>
<p><span id="more-84"></span></p>
<h3><strong>Undefined</strong></h3>
<p>The thing that really bothers me is when a buzzword is coined, but not defined. Apparently it is an abstract concept that is simply too broad in scope to define. Are you kidding me? Whenever I suggest that a buzzword represents an existing concept or an aggregate of existing concepts, an evangelist tells me that I&#8217;m wrong and then proceeds to start talking in gibberish. Seeing as I can&#8217;t interpret gibberish, I&#8217;m told that I simply do not &#8216;get it&#8217;.</p>
<h3><strong>Cloud Computing</strong></h3>
<p>Let&#8217;s take a look at the latest outbreak. Cloud Computing. Come on, say it together&#8230;</p>
<p>&#8220;In the Cloud.&#8221;</p>
<p>I know, I know. I&#8217;d rather shoot myself in the head with a nail gun than have to listen to someone repeat that phrase again.</p>
<p>So what is cloud computing?</p>
<h2>Wikipedia</h2>
<p><em style="font-size: 10px;">&#8220;Cloud computing is a style of computing in which dynamically scalable and often virtualised resources are provided as a service over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure &#8216;in the cloud&#8217; that supports them.&#8221;</em></p>
<p>This is an adequate definition of utility computing, but we are looking for a definition of cloud computing. One approach to defining cloud computing is to describe utility computing but then say that it is not actually utility computing.</p>
<p>Shortly after, this entry mentions IaaS, PaaS, and SaaS. And for good measure, it tosses in Web 2.0 and other unnamed (buzzwords are still incubating) technologies. I guess you just toss the ingredients into a crock pot and wait. Come back 8 hours later and your enterprise IT solution is ready.</p>
<p>Finally, they say that the term <em>cloud</em> is actually a metaphor for the Internet and that this whole cloud computing thing is about relying on the Internet for the computing needs of users. Wow! What a breakthrough! I never thought about using this so called Internet for computing, and I definitely never thought about using it to perform computing for its users. So, if I understand this correctly, the Internet has computers and it has users? When used together, you can use the computers to do computer &#8217;stuff&#8217; for the users? Sweet.</p>
<h2>Distinguishing Cloud Computing from Utility Computing</h2>
<p><em style="font-size: 10px;">&#8220;For those of us who aren&#8217;t totally up to speed on the difference, can you summarize the difference between utility computing and cloud computing (in 75 words or less)?</em></p>
<p><em style="font-size: 10px;">Lynn: That would be analogous to trying to talk about the differences between electricity and a generator. So, I prefer talking about how one relates to the other, rather than the differences.&#8221;</em></p>
<p>Classic. You know you have a problem when you have to side step the issue of defining the buzzword.</p>
<p><em style="font-size: 10px;">&#8220;Cloud computing enables users and developers to utilize services without knowledge of, expertise with, nor control over the technology infrastructure that supports them. It is, almost literally, operating the service in a cloud. That&#8217;s a good thing, because many companies lack the ability or desire to work with infrastructure. Utility computing, conversely, provides on-demand infrastructure with the ability to control, scale, and configure that infrastructure. At 3tera, we believe that a utility is necessary in order to build a reliable cloud.&#8221;</em></p>
<p>Someone hand me the nail gun. Seriously. I&#8217;m not even sure where to start here. What does &#8216;utilize&#8217; mean? Are we talking about developing services, or are we talking about consuming them? As consumers of services, we have never been interested in their technical infrastructure/implementation. That is the whole point of services. As a developer, I don&#8217;t necessarily need to have a technical understanding of the infrastructure. It certainly helps, but it is not required. If the code is well written, it is portable. It makes no difference whether it is deployed to Tomcat or JBoss. It makes no difference whether the application is clustered or not. What is this &#8216;operating the service in a cloud&#8217; business? Just because the code has been abstracted from the infrastructure, the services are &#8216;operating in a cloud&#8217;? In that case, every service ever written is &#8216;operating in a cloud&#8217;.</p>
<h2>How Cloud &amp; Utility Computing Are Different</h2>
<p><em style="font-size: 10px;">&#8220;The big news is for application developers and IT operations. Done right, cloud computing allows them to develop, deploy and run applications that can easily grow capacity (scalability), work fast (performance), and never — or at least rarely — fail (reliability), all without any concern as to the nature and location of the underlying infrastructure.&#8221;<br />
</em><br />
Once again, we see an adequate definition of utility computing. Once again, that is it.</p>
<h2>Ah, Yes. How To Define Cloud Computing&#8230;</h2>
<p><em style="font-size: 10px;">&#8220;Cloud computing describes a systems architecture. Period. This particular architecture assumes nothing about the physical location, internal composition or ownership of its component parts. It represents the entire computing stack from software to hardware, though system boundaries (e.g. where does one system stop and another begin) may be difficult to define. Components are simply integrated or consumed as need requires and economics allow.&#8221;</em></p>
<p>First, take away the infrastructure. Then, take away the software architecture. Finally, lose the system boundaries because they are difficult to define anyways. Done. What are you left with? Anyone? So is the cloud architect merely responsible for selecting a utility computing service? Is that what this is all about?</p>
<p>The author then goes on to say (more or less) that cloud computing is deploying service oriented applications to a utility service. Well, at least this is not gibberish. However, according to that definition, cloud computing <em>itself</em> does not provide any added value. It is simply bundling two buzzwords together in the same package. In my opinion, that repackaging does not count as innovation.</p>
<h3><strong>Conclusion</strong></h3>
<p>Okay, the title was misleading. Amazon EC2? Go for it. I would.</p>
<p>I&#8217;m a fan of utility computing. I think it is a truly novel idea, and that it will have a significant impact on the future of enterprise IT.</p>
<p>My issue is with the buzzwords, and the people who evangelize them.</p>
<p>A buzzword is not an architecture. It is not a solution. You can&#8217;t just purchase a product thats been stamped with a buzzword and expect to call it a day.</p>
<p>You need an architect. You need a problem solver. You need developers.</p>
<p>IT is something you do, not something you buy.</p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=84</wfw:commentRss>
		</item>
		<item>
		<title>AIR / Flex &#8211; Drap &amp; Drop (to Desktop)</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=83</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=83#comments</comments>
		<pubDate>Wed, 25 Feb 2009 06:25:34 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Rich Internet Applications]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Drag & Drop]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=83</guid>
		<description><![CDATA[In order to drag one or more files from an AIR application to the desktop you have to handle just one event: DragEvent.
public function downloadFiles(event:DragEvent):void
{
   this.docs = List(event.target).selectedItems;

   var clip:Clipboard = new Clipboard();

   clip.setDataHandler(ClipboardFormats.FILE_LIST_FORMAT,
      getDownloadFiles);

   var dragOptions:NativeDragOptions = new NativeDragOptions();

   [...]]]></description>
			<content:encoded><![CDATA[<p>In order to drag one or more files from an AIR application to the desktop you have to handle just one event: DragEvent.</p>
<pre>public function downloadFiles(event:DragEvent):void
{
   this.docs = List(event.target).selectedItems;

   var clip:Clipboard = new Clipboard();

   clip.setDataHandler(ClipboardFormats.FILE_LIST_FORMAT,
      getDownloadFiles);

   var dragOptions:NativeDragOptions = new NativeDragOptions();

   dragOptions.allowCopy = true;

   NativeDragManager.doDrag(event.currentTarget as InteractiveObject,
      clip, null, null, dragOptions);
}</pre>
<p><span id="more-83"></span></p>
<p>I have created a custom class named Document. This class specifies properties for the filename and the URL to the file itself. I then created an ArrayCollection and added some Documents to it.</p>
<p>So, the first thing I need to do is get the items being dragged (Documents).</p>
<p>Then I have to create a Clipboard and add an Array of Files to it. In addition, you have the option of creating a NativeDragOptions. Finally, you have to tell the NativeDragManager to begin the drag by specifying the drag initiator (&lt;mx:List/&gt;), the Clipboard, the proxy image (null), the offset between the mouse and the top left corner of the drag image (null), and the NativeDragOptions.</p>
<p>However, no Files are available when the drag event is thrown. So, I have to add a data handler to the Clipboard to call a separate method that creates and returns an Array of Files. This is why I set the dragged items (Documents) to a class level variable. So that this method can access them.</p>
<pre>private function getDownloadFiles():Array
{
   var files:Array = new Array();

   for (var i:int = 0; i &lt; this.docs.length; i++)
   {
      var doc:Document = Document(this.docs[i]);

      var request:URLRequest = new URLRequest(doc.url);

      var header:URLRequestHeader;

      header = new URLRequestHeader("Authorization",
         "Basic " + this.auth);

      request.requestHeaders.push(header);

      var file:File =
         File.createTempDirectory().resolvePath(doc.fileName);

      var buffer:FileBuffer = new FileBuffer(file);

      var loader:URLLoader = new URLLoader();

      loader.dataFormat = URLLoaderDataFormat.BINARY;
      loader.addEventListener(Event.COMPLETE, buffer.write);
      loader.load(request);

      files.push(file);
   }

   return files;
}</pre>
<p>There is not much to this method. I simply have to iterate over the selected items (Documents) and create a new File using the filename. Then I have to create a URLRequest using the URL. Finally, I create a URLLoader and load the URLRequest. What I&#8217;ve done is wrap the File in a FileBuffer. Then I added a listener to the URLLoader to write its data to the FileBuffer once it has been retrieved.</p>
<p>Here is the code for the file buffer.</p>
<pre>public class FileBuffer
{

   private var file:File;

   public function FileBuffer(file:File)
   {
      this.file = file;
   }

   public function write(event:Event):void
   {
      var loader:URLLoader = URLLoader(event.target);

      var fileStream:FileStream = new FileStream();

      fileStream.open(file, FileMode.WRITE);
      fileStream.writeBytes(loader.data);
      fileStream.close();
   }

}</pre>
<p>That is all there is to it. I&#8217;d say drag and drop is pretty easy with AIR.</p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=83</wfw:commentRss>
		</item>
		<item>
		<title>Web Applications, Services, &amp; Loose Coupling</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=78</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=78#comments</comments>
		<pubDate>Tue, 24 Feb 2009 06:30:33 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[RESTful Services]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[loose coupling]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=78</guid>
		<description><![CDATA[I think it&#8217;s pretty safe to say that most web applications fall into one of two categories.

Content Driven
Data Driven

I also think it is pretty safe to say that they are easy to build. However, things can get a little dicey when it comes time to integrate services. The fact is that we are implementing reusable [...]]]></description>
			<content:encoded><![CDATA[<p>I think it&#8217;s pretty safe to say that most web applications fall into one of two categories.</p>
<ul>
<li>Content Driven</li>
<li>Data Driven</li>
</ul>
<p>I also think it is pretty safe to say that they are easy to build. However, things can get a little dicey when it comes time to integrate services. The fact is that we are implementing reusable functionality as services and that means that our web applications must now include service clients.</p>
<p>That means we are now responsible for maintaining the client and the UI.</p>
<p>Here is a thought. How about we allow the services to generate their own forms and allow the users to interact with them directly? I do not want to continue playing the middle man.</p>
<p><span id="more-78"></span></p>
<p>This approach may not be appropriate for every service, but I suspect it is for quite a few. Here are a few services that are often associated with e-commerce web applications.</p>
<ul>
<li>Account Management</li>
<li>Product Registration</li>
<li>Payment Processing</li>
</ul>
<p>Each of these is certainly reusable. In addition to the web application, these services may be consumed by customer support, technical support, and/or kiosks. The point is that it certainly makes sense to implement this functionality as services.</p>
<p>However, this functionality is ultimately user driven. That, and our web application is not going to provide any additional business logic with respect to these services. All it is really doing is generating the HTML form, performing validation upon submission, calling the service, and converting its response to HTML.</p>
<p>Perhaps the only issue is how to we provide a consistent UI if we are allowing the user to interact with the service directly. I think the answer is pretty simple. We&#8217;ll use Apache server side includes.</p>
<p>Ultimately, there are only three types of responses.</p>
<ol>
<li>Form</li>
<li>Form + Validation Error(s)</li>
<li>Result</li>
</ol>
<p>We can further break that down into two types of tasks.</p>
<ol>
<li>Integrate Form with Page</li>
<li>Integrate Validation Error(s)/Result with Page</li>
</ol>
<h2>Integrate Form with Page</h2>
<p>The first one is pretty easy.</p>
<ol>
<li>User Sends Request to Apache</li>
<li>Apache Sends Request to Web Application</li>
<li>Web Application Returns Response w/SSI for Form</li>
<li>Apache Sends Include Request to Transformation Service</li>
<li>Transformation Service Sends Include Request to Service</li>
<li>Service Returns Response (Form XML)</li>
<li>Transformation Service Applies Transformation to XML</li>
<li>Transformation Service Returns Response (HTML)</li>
<li>Apache Returns Response (HTML)</li>
</ol>
<p style="TEXT-ALIGN: center"><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_request.gif" ><img class="size-full wp-image-80 aligncenter" title="form_request" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_request.gif" alt="" width="435" height="459" /></a></p>
<p>I front the service(s) with a transformation service so that they are not responsible for generating the HTML. After all, the service may be used by other applications and those applications may or may not be web applications.</p>
<h2>Integrate Validation Error(s)/Result with Page</h2>
<p>The second one requires a little more work and is really a two step process (post get redirect).</p>
<h3>POST</h3>
<ol>
<li>User Sends Post to Apache</li>
<li>Apache Sends Post to Transformation Service</li>
<li>Transformation Service Sends Post to Service</li>
<li>Service Returns Validation Error(s) or Result (XML)</li>
<li>Transformation Service Caches Transformed Service Response (HTML)</li>
<li>Transformation Service Returns Redirect
<ol>
<li>Validation Error(s) &#8211; Redirect to Form</li>
<li>Result &#8211; Redirect to Result</li>
</ol>
</li>
<li>Apache Returns Redirect</li>
</ol>
<p style="TEXT-ALIGN: center"><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_submit_redirect.gif" ><img class="size-full wp-image-81 aligncenter" title="form_submit_redirect" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_submit_redirect.gif" alt="" width="435" height="459" /></a></p>
<h3>GET</h3>
<ol>
<li>User Sends Request to Apache</li>
<li>Apache Sends Request to Web Application</li>
<li>Web Application Returns Response w/SSI</li>
<li>Apache Sends Include Request to Transformation Service</li>
<li>Transformation Service Sends Cached Response (HTML)
<ol>
<li>Transformation Service Removes Cached Response</li>
</ol>
</li>
<li>Apache Returns Response (HTML)</li>
</ol>
<p style="text-align: center;"><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_response.gif" ><img class="size-full wp-image-82 aligncenter" title="form_response" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/form_response.gif" alt="" width="435" height="459" /></a></p>
<p style="float: right;">
<script type="text/javascript"><script type="text/javascript">var dzone_url = 'http://blogs.citytechinc.com/sjohnson/?p=78';</script><script type="text/javascript">var dzone_title = 'Web Applications, Services, &#038; Loose Coupling';</script><script type="text/javascript">var dzone_blurb = ''Thoughts on how to achieve loose coupling between web applications and services.';</script><script type="text/javascript">var dzone_style = '1';</script><script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script>
</p>
<div style="clear: both;"></div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=78</wfw:commentRss>
		</item>
		<item>
		<title>Alfresco Tech Talk &#8211; CMIS</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=79</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=79#comments</comments>
		<pubDate>Mon, 23 Feb 2009 16:05:39 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Enterprise Content Management]]></category>
		<category><![CDATA[RESTful Services]]></category>
		<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[ATOM]]></category>
		<category><![CDATA[CMIS]]></category>
		<category><![CDATA[speaking]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=79</guid>
		<description><![CDATA[What went right?

I was able to demo the CMIS explorer live.
I was able to demo Sten&#8217;s CMIS visualizer live.
I was able to walk through my prepared OO presentation.

What went wrong?

Adobe Connect
Apparently Adobe Connect is not fully compatible with Linux. I was able to join the meeting without incident. I was able to see the shared [...]]]></description>
			<content:encoded><![CDATA[<p>What went right?</p>
<ul>
<li>I was able to demo the CMIS explorer live.</li>
<li>I was able to demo Sten&#8217;s CMIS visualizer live.</li>
<li>I was able to walk through my prepared OO presentation.</li>
</ul>
<p>What went wrong?</p>
<p><span id="more-79"></span></p>
<h3>Adobe Connect</h3>
<p>Apparently Adobe Connect is not fully compatible with Linux. I was able to join the meeting without incident. I was able to see the shared screen. Adobe was even able to detect my microphone and once I was assigned speaking privileges I was able to talk to everyone. Seemed like everything was working perfectly. Then it came time to share my desktop. Interesting. How do I do that? Eventually I was made aware that there should be an option under the &#8217;share&#8217; button for &#8216;my computer&#8217;. Of course, that option wasn&#8217;t there. Other options were, just not that one.</p>
<p>I had to reboot into Vista. Here&#8217;s the thing. I only boot to Vista for syncing my Zune. That is it. I have nothing else installed beside Adobe Flash for testing my CMIS explorer.</p>
<h3>Bandwidth</h3>
<p>So, I had to start downloading OpenOffice (for my presentation) and Alfresco (to demo the CMIS explorer) when I began the talk. Thankfully I was able to fall back to one of my blog posts on CMIS to help guide me while I awaited the OO download. Eventually it completed, it was installed, and I was able to open my presentation.</p>
<p>Next you know I am finished with my presentation, but I&#8217;m still waiting for Alfresco to finish downloading. Again, I was able to fall back to one of my blogs posts on the CMIS explorer to help guide me. Eventually the download completed, I installed Alfresco, and I was able to demo the CMIS explorer live.</p>
<p>Now, I want to demo Sten&#8217;s CMIS visualizer. I also started that download back at the beginning of the talk. However, the download kept stalling and it took an eternity to download. So, I fell back to Sten&#8217;s post to show some images of it in action. Once again, the download finished and I was able to demo it live.</p>
<h2>Questions</h2>
<p>There were a few questions.</p>
<p>Am I going to contribute this back to the community? Yes. I just haven&#8217;t determined if I&#8217;m going to check in the code as Flex Builder project or as a Maven project.</p>
<p>Did I use a Flex framework? No. I haven&#8217;t had the need yet, but I am strongly considering Mate.</p>
<p>Does CMIS support other interfaces besides REST/ATOM? Yes. Alfresco supports web services as well. In addition, the specification mentions WebDAV.</p>
<p>I guess I&#8217;m getting good at improvising. Anyways, here is my brief (and I mean brief) presentation on Alfresco/CMIS.</p>
<p>So until next time, good fight, good night.</p>
<div id="__ss_1053064" style="width: 425px; text-align: left;"><a href="http://www.slideshare.net/shane_k_j/alfresco-tech-talk-cmis?type=powerpoint"style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Alfresco Tech Talk - CMIS"  onclick="javascript:pageTracker._trackPageview('/outbound/article/www.slideshare.net');">Alfresco Tech Talk &#8211; CMIS</a><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=alf_tech_talk_cmis-090220174452-phpapp01&amp;stripped_title=alfresco-tech-talk-cmis" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=alf_tech_talk_cmis-090220174452-phpapp01&amp;stripped_title=alfresco-tech-talk-cmis" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a href="http://www.slideshare.net/"style="text-decoration:underline;"  onclick="javascript:pageTracker._trackPageview('/outbound/article/www.slideshare.net');">presentations</a> from <a href="http://www.slideshare.net/shane_k_j"style="text-decoration:underline;"  onclick="javascript:pageTracker._trackPageview('/outbound/article/www.slideshare.net');">Shane Johnson</a>. (tags: <a href="http://slideshare.net/tag/alfresco"style="text-decoration:underline;"  onclick="javascript:pageTracker._trackPageview('/outbound/article/slideshare.net');">alfresco</a> <a href="http://slideshare.net/tag/cmis"style="text-decoration:underline;"  onclick="javascript:pageTracker._trackPageview('/outbound/article/slideshare.net');">cmis</a>)</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=79</wfw:commentRss>
		</item>
		<item>
		<title>SOA &#8211; Composition vs Integration</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=67</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=67#comments</comments>
		<pubDate>Mon, 16 Feb 2009 23:34:24 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Composition]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[WS]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=67</guid>
		<description><![CDATA[I think I&#8217;ve finally figured out what bothers me about SOA.
It is responsible for the notion of composition via remoting.
The problem I have with web services is that they are just another method of remoting, and remoting requires messaging. The fact that you are using web services does NOT mean that you have built a [...]]]></description>
			<content:encoded><![CDATA[<p>I think I&#8217;ve finally figured out what bothers me about SOA.</p>
<p>It is responsible for the notion of composition via remoting.</p>
<p>The problem I have with web services is that they are just another method of remoting, and remoting requires messaging. The fact that you are using web services does NOT mean that you have built a distributed system. As a matter of fact, you haven&#8217;t. Especially since web services rely on synchronous point-to-point communication. It means that you have mistakenly used remoting as a means of composition.</p>
<p>I don&#8217;t have a problem with messaging. I&#8217;m down with message queues.<br />
I don&#8217;t have a problem with remoting. It is useful for integration.</p>
<p>I have a problem with using remoting as a means of composition.</p>
<p>Can we all agree that remoting (web services) should only be used as a method of integration with non-Java and/or remote clients?</p>
<p>I&#8217;ve actually seen organizations where every new feature is implemented as a web service written in Java to be consumed by one or more Java applications. There were no non-Java clients and there were no remote clients. How can any architect justify this?</p>
<p>I&#8217;m down with composition &amp; reuse, loose coupling, and other principals often associated with SOA. However, they are best achieved by deploying services as OSGi bundles alongside their clients.</p>
<p>If you need to integrate with non-Java and/or remote clients then simply expose those bundles as web services, but allow the Java applications to run their bundles locally.</p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=67</wfw:commentRss>
		</item>
		<item>
		<title>CMIS Explorer &#8211; Download</title>
		<link>http://blogs.citytechinc.com/sjohnson/?p=60</link>
		<comments>http://blogs.citytechinc.com/sjohnson/?p=60#comments</comments>
		<pubDate>Thu, 12 Feb 2009 21:32:41 +0000</pubDate>
				<media:content url="http://www.gravatar.com/avatar.php?gravatar_id=4ff537658ea625bc11945deba07f2212&amp;d=http%3A%2F%2Fdesign.citytechinc.com%2Fcitytechwebsite%2Fwebsite_redesign%2Fassets%2Fimg%2Fblog_photo2.gif" medium="image">
		</media:content>
		<dc:creator>Shane Johnson</dc:creator>
				<category><![CDATA[Enterprise Content Management]]></category>
		<category><![CDATA[RESTful Services]]></category>
		<category><![CDATA[Rich Internet Applications]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[CMIS]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://blogs.citytechinc.com/sjohnson/?p=60</guid>
		<description><![CDATA[I&#8217;ve been working on the CMIS explorer on and off for the past few weeks. I think it is about time I made it available for download. I&#8217;d be interesting in hearing feedback on it.
Update: The project is now available on Google Code here.
Or, you can go straight for the download. The current download is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on the CMIS explorer on and off for the past few weeks. I think it is about time I made it available for download. I&#8217;d be interesting in hearing feedback on it.</p>
<p>Update: The project is now available on Google Code <a href="http://code.google.com/p/cmis-explorer/"title="cmis-explorer"  target="_blank" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">here</a>.</p>
<p>Or, you can go straight for the <a href="http://cmis-explorer.googlecode.com/files/cmis-explorer-1.0.air"title="Download CMIS Explorer"  onclick="javascript:pageTracker._trackPageview('/outbound/article/cmis-explorer.googlecode.com');">download</a>. The current download is for the CMIS 1.0 specification.</p>
<p>Update: I have fixed the code so that there are no more hard coded URLs. It has been tested in both Windows and Ubuntu against both local and remote repositories. Have fun.</p>
<p>Update: <span style="text-decoration: line-through;">I just realized that there is still a hard coded URL in the source. That means it will only work against Alfresco running locally on port 8080. I&#8217;ll get that fixed up right away. I&#8217;ll be curious to see if it will work against another repository afterwards.</span></p>
<p><span id="more-60"></span></p>
<h2>CMIS Services/Features &#8211; Done</h2>
<ul>
<li>Get Repository Info
<ul>
<li>Display the Repository Properties</li>
<li>Display the Repository Capabilities</li>
</ul>
</li>
<li>Get Types
<ul>
<li>Display the &#8216;Content&#8217; Types</li>
</ul>
</li>
<li>Get Children
<ul>
<li>Used by the Repository Browser</li>
</ul>
</li>
<li>Create Document
<ul>
<li>Used by Drag &#8216;n Drop (from Desktop to Explorer)</li>
</ul>
</li>
<li>Get Content Stream
<ul>
<li>Used by Drag &#8216;n Drop (from Explorer to Desktop)</li>
</ul>
</li>
<li>Query
<ul>
<li>Used by the Search Form</li>
</ul>
</li>
</ul>
<h2>CMIS Services/Features &#8211; In Progress</h2>
<ul>
<li>Create Folder
<ul>
<li>To be used to create folders from within the repository browser.</li>
</ul>
</li>
<li>Delete Object
<ul>
<li>To be used to delete folders/documents from within the repository browser.</li>
</ul>
</li>
<li>Set Content Stream
<ul>
<li>To be used to update documents from within the repository browser. Perhaps to be used in combination with check-in and check-out.</li>
</ul>
</li>
<li>Check-In
<ul>
<li>Perhaps to be used in combination with Set Content Stream to update documents.</li>
</ul>
</li>
<li>Check-Out
<ul>
<li>Perhaps to be used in combination with Set Content Stream to update documents.</li>
</ul>
</li>
<li>Cancel Check-Out</li>
<li>Get All Versions
<ul>
<li>Display document version history from within the repository browser.</li>
</ul>
</li>
<li>Get Type Definition
<ul>
<li>To be used with Get Types to display the details on &#8216;content&#8217; types.</li>
</ul>
</li>
<li>Get Checked Out Documents
<ul>
<li>Display a list of documents that are currently checked out.</li>
</ul>
</li>
</ul>
<h2>CMIS Service/Features &#8211; Way Out</h2>
<p>Eventually I&#8217;d like to get to the remaining services such as those around relationships, allowable actions, and multi-filing.</p>
<h1>CMIS Explorer &#8211; Images</h1>
<p>Before you can browse the repository you have to specify the URL and your credentials.</p>
<p>For Alfresco, running locally, it would look like this.</p>
<p>http://localhost:8080/alfresco/service/api/repository</p>
<h2>Repository Properties</h2>
<p><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_props.png" ><img title="CMIS Explorer - Repository Properties" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_props.png" alt="" width="500" align="center" /></a></p>
<h2>Repository Capabilities</h2>
<p><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_caps.png" ><img title="CMIS Explorer - Repository Capabilities" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_caps.png" alt="" width="500" align="center" /></a></p>
<h2>Repository Content Types</h2>
<p><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_types.png" ><img title="CMIS Explorer - Content Types" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_types.png" alt="" width="500" align="center" /></a></p>
<h2>Repository Browser</h2>
<p>This fully supports multiple drag and drop to/from the desktop and application. Simple select files from the desktop and drag them to the list in the middle where the filenames are displayed for existed files. The new files will then be uploaded the repository and the list will be updated. For the other direction, use control click to select multiple files from the browsed (again from the middle list) and then drag them to the desktop. The files will then be downloaded directly to the desktop.</p>
<p><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_browser.png" ><img title="CMIS Explorer - Repository Browser" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_browser.png" alt="" width="500" align="center" /></a></p>
<h2>Repository Search</h2>
<p>At the moment you have to specify the full query. I&#8217;ll likely change that so that you simply specify the keyword(s).</p>
<p>Here are a couple of example queries.</p>
<p>select * from document<br />
select * from document where contains(&#8217;a')<br />
select * from document where contains(&#8217;a b&#8217;)<br />
select * from document where contains(&#8217;a') or contains (&#8217;b')</p>
<p><a href="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_search.png" ><img title="CMIS Explorer - Repository Search" src="http://blogs.citytechinc.com/sjohnson/wp-content/uploads/2009/02/cmis_explorer_search.png" alt="" width="500" align="center" /></a></p>
<p>So until next time, good fight, good night.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.citytechinc.com/sjohnson/?feed=rss2&amp;p=60</wfw:commentRss>
		</item>
	</channel>
</rss>
